Camera3Device.cpp revision 0ea8fa4ccbf9b2b179370b983f3887d3daf2381f
17fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala/*
27fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * Copyright (C) 2013 The Android Open Source Project
37fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala *
47fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
57fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * you may not use this file except in compliance with the License.
67fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * You may obtain a copy of the License at
77fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala *
87fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
97fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala *
107fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
117fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
127fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * See the License for the specific language governing permissions and
147fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * limitations under the License.
157fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala */
167fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
177fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#define LOG_TAG "Camera3-Device"
187fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
197fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala//#define LOG_NDEBUG 0
207fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala//#define LOG_NNDEBUG 0  // Per-frame verbose logging
217fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
227fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#ifdef LOG_NNDEBUG
237fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#define ALOGVV(...) ALOGV(__VA_ARGS__)
247fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#else
257fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#define ALOGVV(...) ((void)0)
267fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#endif
277fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
28b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala// Convenience macro for transient errors
29b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala#define CLOGE(fmt, ...) ALOGE("Camera %d: %s: " fmt, mId, __FUNCTION__, \
30b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            ##__VA_ARGS__)
31b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
32b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala// Convenience macros for transitioning to the error state
33b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala#define SET_ERR(fmt, ...) setErrorState(   \
34b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    "%s: " fmt, __FUNCTION__,              \
35b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    ##__VA_ARGS__)
36b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala#define SET_ERR_L(fmt, ...) setErrorStateLocked( \
37b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    "%s: " fmt, __FUNCTION__,                    \
38b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    ##__VA_ARGS__)
39b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
40e5729fac81c8a984e984fefc90afc64135817d4fColin Cross#include <inttypes.h>
41e5729fac81c8a984e984fefc90afc64135817d4fColin Cross
427fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#include <utils/Log.h>
437fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#include <utils/Trace.h>
447fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala#include <utils/Timers.h>
457b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala
46ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin#include "utils/CameraTraces.h"
477b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "device3/Camera3Device.h"
487b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "device3/Camera3OutputStream.h"
497b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "device3/Camera3InputStream.h"
507b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala#include "device3/Camera3ZslStream.h"
517fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
52f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalausing namespace android::camera3;
537fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
54f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalanamespace android {
557fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
567fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville TalvalaCamera3Device::Camera3Device(int id):
577fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        mId(id),
58f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mHal3Device(NULL),
597d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        mStatus(STATUS_UNINITIALIZED),
60fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        mUsePartialResultQuirk(false),
6142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        mNextResultFrameNumber(0),
6242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        mNextShutterFrameNumber(0),
637d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        mListener(NULL)
647fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala{
657fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
667fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    camera3_callback_ops::notify = &sNotify;
677fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
687fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
697fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
707fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
717fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville TalvalaCamera3Device::~Camera3Device()
727fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala{
737fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
747fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
757fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    disconnect();
767fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
777fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
7871381051e2d048b2705c447b3d59db6e972493eeIgor Murashkinint Camera3Device::getId() const {
7971381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin    return mId;
8071381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin}
8171381051e2d048b2705c447b3d59db6e972493eeIgor Murashkin
82f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala/**
83f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala * CameraDeviceBase interface
84f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala */
85f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
867fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::initialize(camera_module_t *module)
877fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala{
887fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
89f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
90f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
91f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
927fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
93f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (mStatus != STATUS_UNINITIALIZED) {
94b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        CLOGE("Already initialized!");
957fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        return INVALID_OPERATION;
967fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    }
977fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
987fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    /** Open HAL device */
997fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1007fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    status_t res;
1017fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    String8 deviceName = String8::format("%d", mId);
1027fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1037fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    camera3_device_t *device;
1047fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
105213ce79e943a3b51d7859a184d8211c859c960a0Zhijun He    ATRACE_BEGIN("camera3->open");
1067fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    res = module->common.methods->open(&module->common, deviceName.string(),
1077fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala            reinterpret_cast<hw_device_t**>(&device));
108213ce79e943a3b51d7859a184d8211c859c960a0Zhijun He    ATRACE_END();
1097fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1107fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    if (res != OK) {
111b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
1127fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        return res;
1137fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    }
1147fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1157fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    /** Cross-check device version */
11695dd5ba5bf83716f2eed5fe72366c4212464d710Zhijun He    if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) {
117b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Could not open camera: "
11895dd5ba5bf83716f2eed5fe72366c4212464d710Zhijun He                "Camera device should be at least %x, reports %x instead",
119b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                CAMERA_DEVICE_API_VERSION_3_0,
1207fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala                device->common.version);
1217fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        device->common.close(&device->common);
1227fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        return BAD_VALUE;
1237fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    }
1247fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1257fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    camera_info info;
1267fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    res = module->get_camera_info(mId, &info);
1277fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    if (res != OK) return res;
1287fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1297fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    if (info.device_version != device->common.version) {
130b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
131b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                " and device version (%x).",
13295dd5ba5bf83716f2eed5fe72366c4212464d710Zhijun He                info.device_version, device->common.version);
1337fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        device->common.close(&device->common);
1347fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        return BAD_VALUE;
1357fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    }
1367fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1377fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    /** Initialize device with callback functions */
1387fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
13917a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_BEGIN("camera3->initialize");
1407fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    res = device->ops->initialize(device, this);
14117a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_END();
14217a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala
1437fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    if (res != OK) {
144b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Unable to initialize HAL device: %s (%d)",
145b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                strerror(-res), res);
1467fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        device->common.close(&device->common);
1477fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        return BAD_VALUE;
1487fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    }
1497fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
150f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    /** Start up status tracker thread */
151f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mStatusTracker = new StatusTracker(this);
152f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    res = mStatusTracker->run(String8::format("C3Dev-%d-Status", mId).string());
153f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (res != OK) {
154f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        SET_ERR_L("Unable to start status tracking thread: %s (%d)",
155f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                strerror(-res), res);
156f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        device->common.close(&device->common);
157f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatusTracker.clear();
158f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        return res;
159f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
160f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1617fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    /** Start up request queue thread */
1627fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
163f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mRequestThread = new RequestThread(this, mStatusTracker, device);
164f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
1657fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    if (res != OK) {
166b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Unable to start request queue thread: %s (%d)",
167b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                strerror(-res), res);
1687fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        device->common.close(&device->common);
169f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mRequestThread.clear();
1707fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        return res;
1717fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    }
1727fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1737fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    /** Everything is good to go */
1747fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
175cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    mDeviceVersion = device->common.version;
1767fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    mDeviceInfo = info.static_camera_characteristics;
1777fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    mHal3Device = device;
178f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mStatus = STATUS_UNCONFIGURED;
179f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mNextStreamId = 0;
180ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala    mNeedConfig = true;
181f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mPauseStateNotify = false;
1827fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
183fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    /** Check for quirks */
184fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
185fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // Will the HAL be sending in early partial result metadata?
186fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    camera_metadata_entry partialResultsQuirk =
187fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
188fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) {
189fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        mUsePartialResultQuirk = true;
190fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
191fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1927fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return OK;
1937fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
1947fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1957fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::disconnect() {
1967fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
197f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
1987fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
199f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    ALOGV("%s: E", __FUNCTION__);
200f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
201214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala    status_t res = OK;
202f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
203f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
204f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mLock);
205f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStatus == STATUS_UNINITIALIZED) return res;
206f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
207f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStatus == STATUS_ACTIVE ||
208f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
209f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            res = mRequestThread->clearRepeatingRequests();
210214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala            if (res != OK) {
211f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                SET_ERR_L("Can't stop streaming");
212214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala                // Continue to close device even in case of error
213f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            } else {
214f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
215f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                if (res != OK) {
216f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    SET_ERR_L("Timeout waiting for HAL to drain");
217f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    // Continue to close device even in case of error
218f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                }
219214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala            }
220f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
221f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
222f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStatus == STATUS_ERROR) {
223f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            CLOGE("Shutting down in an error state");
224f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
225f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
226f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStatusTracker != NULL) {
227f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mStatusTracker->requestExit();
228f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
229f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
230f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mRequestThread != NULL) {
231f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mRequestThread->requestExit();
232f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
233f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
234f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mOutputStreams.clear();
235f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mInputStream.clear();
236f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
237f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
238f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Joining done without holding mLock, otherwise deadlocks may ensue
239f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // as the threads try to access parent state
240f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
241f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // HAL may be in a bad state, so waiting for request thread
242f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // (which may be stuck in the HAL processCaptureRequest call)
243f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // could be dangerous.
244f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mRequestThread->join();
245214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala    }
246214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala
247f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mStatusTracker != NULL) {
248f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatusTracker->join();
249f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
250f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
251f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
252f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mLock);
253f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
254f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mRequestThread.clear();
255f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatusTracker.clear();
256f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
257f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mHal3Device != NULL) {
258213ce79e943a3b51d7859a184d8211c859c960a0Zhijun He            ATRACE_BEGIN("camera3->close");
259f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mHal3Device->common.close(&mHal3Device->common);
260213ce79e943a3b51d7859a184d8211c859c960a0Zhijun He            ATRACE_END();
261f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mHal3Device = NULL;
262f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
263f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
264f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatus = STATUS_UNINITIALIZED;
265f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
266f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
267f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    ALOGV("%s: X", __FUNCTION__);
268214a17fd37ef85fc841d3157b1e9096e1aa1b42fEino-Ville Talvala    return res;
2697fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
2707fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
271f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala// For dumping/debugging only -
272f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala// try to acquire a lock a few times, eventually give up to proceed with
273f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala// debug/dump operations
274f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalabool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
275f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    bool gotLock = false;
276f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    for (size_t i = 0; i < kDumpLockAttempts; ++i) {
277f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (lock.tryLock() == NO_ERROR) {
278f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            gotLock = true;
279f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            break;
280f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        } else {
281f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            usleep(kDumpSleepDuration);
282f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
283f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
284f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return gotLock;
285f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
286f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
287cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia YehCamera3Device::Size Camera3Device::getMaxJpegResolution() const {
288f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    int32_t maxJpegWidth = 0, maxJpegHeight = 0;
289cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
290cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        const int STREAM_CONFIGURATION_SIZE = 4;
291cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        const int STREAM_FORMAT_OFFSET = 0;
292cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        const int STREAM_WIDTH_OFFSET = 1;
293cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        const int STREAM_HEIGHT_OFFSET = 2;
294cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        const int STREAM_IS_INPUT_OFFSET = 3;
295cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        camera_metadata_ro_entry_t availableStreamConfigs =
296cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
297cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        if (availableStreamConfigs.count == 0 ||
298cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
299cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            return Size(0, 0);
300cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        }
301cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh
302cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        // Get max jpeg size (area-wise).
303cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
304cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
305cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
306cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
307cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
308cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
309cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                    && format == HAL_PIXEL_FORMAT_BLOB &&
310cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                    (width * height > maxJpegWidth * maxJpegHeight)) {
311cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                maxJpegWidth = width;
312cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                maxJpegHeight = height;
313cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            }
314cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        }
315cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    } else {
316cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        camera_metadata_ro_entry availableJpegSizes =
317cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
318cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        if (availableJpegSizes.count == 0 || availableJpegSizes.count % 2 != 0) {
319cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            return Size(0, 0);
320cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        }
321cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh
322cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        // Get max jpeg size (area-wise).
323cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        for (size_t i = 0; i < availableJpegSizes.count; i += 2) {
324cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            if ((availableJpegSizes.data.i32[i] * availableJpegSizes.data.i32[i + 1])
325cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                    > (maxJpegWidth * maxJpegHeight)) {
326cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                maxJpegWidth = availableJpegSizes.data.i32[i];
327cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                maxJpegHeight = availableJpegSizes.data.i32[i + 1];
328cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            }
329f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        }
330f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    }
331cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    return Size(maxJpegWidth, maxJpegHeight);
332cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh}
333cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh
334cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yehssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
335cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    // Get max jpeg size (area-wise).
336cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    Size maxJpegResolution = getMaxJpegResolution();
337cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    if (maxJpegResolution.width == 0) {
338cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh        ALOGE("%s: Camera %d: Can't find find valid available jpeg sizes in static metadata!",
339cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh                __FUNCTION__, mId);
340f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        return BAD_VALUE;
341f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    }
342f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He
343f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    // Get max jpeg buffer size
344f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    ssize_t maxJpegBufferSize = 0;
345cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
346cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    if (jpegBufMaxSize.count == 0) {
347f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
348f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        return BAD_VALUE;
349f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    }
350cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
351f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He
352f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    // Calculate final jpeg buffer size for the given resolution.
353cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh    float scaleFactor = ((float) (width * height)) /
354cd8fce8fbe0f515e53a0ea0f50b739cf42ee57a4Yin-Chia Yeh            (maxJpegResolution.width * maxJpegResolution.height);
355f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    ssize_t jpegBufferSize = scaleFactor * maxJpegBufferSize;
356f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    // Bound the buffer size to [MIN_JPEG_BUFFER_SIZE, maxJpegBufferSize].
357f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    if (jpegBufferSize > maxJpegBufferSize) {
358f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        jpegBufferSize = maxJpegBufferSize;
359f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    } else if (jpegBufferSize < kMinJpegBufferSize) {
360f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        jpegBufferSize = kMinJpegBufferSize;
361f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    }
362f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He
363f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He    return jpegBufferSize;
364f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He}
365f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He
3667fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::dump(int fd, const Vector<String16> &args) {
3677fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
3687fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    (void)args;
369f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
370f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Try to lock, but continue in case of failure (to avoid blocking in
371f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // deadlocks)
372f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
373f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    bool gotLock = tryLockSpinRightRound(mLock);
374f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
375f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGW_IF(!gotInterfaceLock,
376f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            "Camera %d: %s: Unable to lock interface lock, proceeding anyway",
377f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mId, __FUNCTION__);
378f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGW_IF(!gotLock,
379f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            "Camera %d: %s: Unable to lock main lock, proceeding anyway",
380f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mId, __FUNCTION__);
381f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
382f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    String8 lines;
383f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
384f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    const char *status =
385f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            mStatus == STATUS_ERROR         ? "ERROR" :
386f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
387f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mStatus == STATUS_UNCONFIGURED  ? "UNCONFIGURED" :
388f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mStatus == STATUS_CONFIGURED    ? "CONFIGURED" :
389f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            mStatus == STATUS_ACTIVE        ? "ACTIVE" :
390f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            "Unknown";
391f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
392f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    lines.appendFormat("    Device status: %s\n", status);
393b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    if (mStatus == STATUS_ERROR) {
394b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        lines.appendFormat("    Error cause: %s\n", mErrorCause.string());
395b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    }
396f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    lines.appendFormat("    Stream configuration:\n");
397f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
398f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (mInputStream != NULL) {
399f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        write(fd, lines.string(), lines.size());
400f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mInputStream->dump(fd, args);
401f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    } else {
402f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        lines.appendFormat("      No input stream.\n");
403f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        write(fd, lines.string(), lines.size());
404f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
405f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    for (size_t i = 0; i < mOutputStreams.size(); i++) {
406f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mOutputStreams[i]->dump(fd,args);
407f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
4087fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
40942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    lines = String8("    In-flight requests:\n");
41042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    if (mInFlightMap.size() == 0) {
41142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        lines.append("      None\n");
41242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    } else {
41342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        for (size_t i = 0; i < mInFlightMap.size(); i++) {
41442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            InFlightRequest r = mInFlightMap.valueAt(i);
415e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            lines.appendFormat("      Frame %d |  Timestamp: %" PRId64 ", metadata"
41642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
41742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    r.captureTimestamp, r.haveResultMetadata ? "true" : "false",
41842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    r.numBuffersLeft);
41942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
42042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    }
42142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    write(fd, lines.string(), lines.size());
42242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
4231e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    {
4241e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        lines = String8("    Last request sent:\n");
4251e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        write(fd, lines.string(), lines.size());
4261e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
427f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        CameraMetadata lastRequest = getLatestRequestLocked();
4281e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
4291e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    }
4301e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
431f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (mHal3Device != NULL) {
43242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        lines = String8("    HAL device dump:\n");
433f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        write(fd, lines.string(), lines.size());
434f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mHal3Device->ops->dump(mHal3Device, fd);
435f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
4367fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
437f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (gotLock) mLock.unlock();
438f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (gotInterfaceLock) mInterfaceLock.unlock();
439f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
4407fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return OK;
4417fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
4427fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
4437fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalaconst CameraMetadata& Camera3Device::info() const {
4447fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ALOGVV("%s: E", __FUNCTION__);
445f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
446f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                    mStatus == STATUS_ERROR)) {
447b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        ALOGW("%s: Access to static info %s!", __FUNCTION__,
448f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                mStatus == STATUS_ERROR ?
449f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                "when in error state" : "before init");
450f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
4517fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return mDeviceInfo;
4527fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
4537fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
45490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Weistatus_t Camera3Device::checkStatusOkToCaptureLocked() {
45590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    switch (mStatus) {
45690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        case STATUS_ERROR:
45790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            CLOGE("Device has encountered a serious error");
45890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return INVALID_OPERATION;
45990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        case STATUS_UNINITIALIZED:
46090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            CLOGE("Device not initialized");
46190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return INVALID_OPERATION;
46290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        case STATUS_UNCONFIGURED:
46390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        case STATUS_CONFIGURED:
46490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        case STATUS_ACTIVE:
46590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            // OK
46690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            break;
46790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        default:
46890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            SET_ERR_L("Unexpected status: %d", mStatus);
46990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return INVALID_OPERATION;
47090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
47190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    return OK;
47290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
47390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
47490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Weistatus_t Camera3Device::convertMetadataListToRequestListLocked(
47590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        const List<const CameraMetadata> &metadataList, RequestList *requestList) {
47690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (requestList == NULL) {
47790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        CLOGE("requestList cannot be NULL.");
47890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        return BAD_VALUE;
47990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
48090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
481cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    int32_t burstId = 0;
48290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
48390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            it != metadataList.end(); ++it) {
48490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
48590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (newRequest == 0) {
48690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            CLOGE("Can't create capture request");
48790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            return BAD_VALUE;
48890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
489cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
490cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        // Setup burst Id and request Id
491cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        newRequest->mResultExtras.burstId = burstId++;
492cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        if (it->exists(ANDROID_REQUEST_ID)) {
493cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            if (it->find(ANDROID_REQUEST_ID).count == 0) {
494cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                CLOGE("RequestID entry exists; but must not be empty in metadata");
495cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                return BAD_VALUE;
496cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            }
497cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0];
498cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        } else {
499cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            CLOGE("RequestID does not exist in metadata");
500cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            return BAD_VALUE;
501cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        }
502cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
50390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        requestList->push_back(newRequest);
5042d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei
5052d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
50690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
50790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    return OK;
50890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
50990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
510cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
5117fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
5124d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
5132d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    List<const CameraMetadata> requests;
5142d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    requests.push_back(request);
5152d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    return captureList(requests, /*lastFrameNumber*/NULL);
5167fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
5177fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
51890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Weistatus_t Camera3Device::submitRequestsHelper(
5192d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        const List<const CameraMetadata> &requests, bool repeating,
5202d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        /*out*/
5212d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        int64_t *lastFrameNumber) {
52290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ATRACE_CALL();
52390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    Mutex::Autolock il(mInterfaceLock);
52490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    Mutex::Autolock l(mLock);
52590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
52690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    status_t res = checkStatusOkToCaptureLocked();
52790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (res != OK) {
52890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        // error logged by previous call
52990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        return res;
53090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
53190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
53290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    RequestList requestList;
53390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
53490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);
53590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (res != OK) {
53690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        // error logged by previous call
53790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        return res;
53890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
53990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
54090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (repeating) {
5412d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
54290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    } else {
5432d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
54490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
54590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
54690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    if (res == OK) {
54790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
54890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        if (res != OK) {
54990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            SET_ERR_L("Can't transition to active in %f seconds!",
55090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei                    kActiveTimeout/1e9);
55190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        }
5522d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        ALOGV("Camera %d: Capture request %" PRId32 " enqueued", mId,
5532d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei              (*(requestList.begin()))->mResultExtras.requestId);
55490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    } else {
55590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        CLOGE("Cannot queue request. Impossible.");
55690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        return BAD_VALUE;
55790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
55890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
55990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    return res;
56090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
56190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
562cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::captureList(const List<const CameraMetadata> &requests,
563cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                    int64_t *lastFrameNumber) {
56490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ATRACE_CALL();
56590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
566cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber);
56790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
5687fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
569cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
570cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                            int64_t* /*lastFrameNumber*/) {
5717fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
572f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
5732d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    List<const CameraMetadata> requests;
5742d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    requests.push_back(request);
5752d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    return setStreamingRequestList(requests, /*lastFrameNumber*/NULL);
576f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
577f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
578cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
579cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                                int64_t *lastFrameNumber) {
58090e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    ATRACE_CALL();
58190e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
582cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber);
58390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
584f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
585f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalasp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
586f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        const CameraMetadata &request) {
587f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
588f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
589f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
590f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        res = configureStreamsLocked();
591f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (res != OK) {
592b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
593f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return NULL;
594f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
595f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStatus == STATUS_UNCONFIGURED) {
596f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            CLOGE("No streams configured");
597f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            return NULL;
598f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
599f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
600f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
601f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    sp<CaptureRequest> newRequest = createCaptureRequest(request);
602f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return newRequest;
6037fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
6047fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
605cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
6067fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
607f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
608f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
609f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
610f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    switch (mStatus) {
611f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ERROR:
612b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device has encountered a serious error");
613f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
614f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_UNINITIALIZED:
615b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device not initialized");
616f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
617f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
618f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
619f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ACTIVE:
620f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // OK
621f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
622f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        default:
623b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Unexpected status: %d", mStatus);
624f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
625f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
626f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("Camera %d: Clearing repeating request", mId);
627cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
6282d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    return mRequestThread->clearRepeatingRequests(lastFrameNumber);
6297fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
6307fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
6317fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
6327fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
633f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
6347fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
6354d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
6367fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
6377fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
6385a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkinstatus_t Camera3Device::createInputStream(
6395a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        uint32_t width, uint32_t height, int format, int *id) {
6405a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    ATRACE_CALL();
641f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
6425a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    Mutex::Autolock l(mLock);
643f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("Camera %d: Creating new input stream %d: %d x %d, format %d",
644f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mId, mNextStreamId, width, height, format);
6455a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6465a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    status_t res;
6475a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    bool wasActive = false;
6485a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6495a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    switch (mStatus) {
6505a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        case STATUS_ERROR:
6515a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
6525a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            return INVALID_OPERATION;
6535a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        case STATUS_UNINITIALIZED:
6545a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            ALOGE("%s: Device not initialized", __FUNCTION__);
6555a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            return INVALID_OPERATION;
656f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
657f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
6585a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            // OK
6595a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            break;
6605a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        case STATUS_ACTIVE:
6615a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
662f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            res = internalPauseAndWaitLocked();
6635a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            if (res != OK) {
664f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                SET_ERR_L("Can't pause captures to reconfigure streams!");
6655a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin                return res;
6665a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            }
6675a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            wasActive = true;
6685a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            break;
6695a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        default:
670f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            SET_ERR_L("%s: Unexpected status: %d", mStatus);
6715a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            return INVALID_OPERATION;
6725a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    }
673f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    assert(mStatus != STATUS_ACTIVE);
6745a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6755a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    if (mInputStream != 0) {
6765a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
6775a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        return INVALID_OPERATION;
6785a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    }
6795a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6805a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
6815a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin                width, height, format);
682f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    newStream->setStatusTracker(mStatusTracker);
6835a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6845a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    mInputStream = newStream;
6855a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6865a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    *id = mNextStreamId++;
6875a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
6885a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    // Continue captures if active at start
6895a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    if (wasActive) {
6905a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
6915a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        res = configureStreamsLocked();
6925a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        if (res != OK) {
6935a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
6945a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin                    __FUNCTION__, mNextStreamId, strerror(-res), res);
6955a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin            return res;
6965a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        }
697f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        internalResumeLocked();
6985a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    }
6995a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
700f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("Camera %d: Created input stream", mId);
7015a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin    return OK;
7025a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin}
7035a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin
7042fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7052fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkinstatus_t Camera3Device::createZslStream(
7062fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            uint32_t width, uint32_t height,
7072fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            int depth,
7082fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            /*out*/
7092fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            int *id,
7102fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            sp<Camera3ZslStream>* zslStream) {
7112fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    ATRACE_CALL();
712f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
7132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    Mutex::Autolock l(mLock);
714f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("Camera %d: Creating ZSL stream %d: %d x %d, depth %d",
715f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mId, mNextStreamId, width, height, depth);
7162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    status_t res;
7182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    bool wasActive = false;
7192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    switch (mStatus) {
7212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        case STATUS_ERROR:
7222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
7232fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
7242fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        case STATUS_UNINITIALIZED:
7252fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Device not initialized", __FUNCTION__);
7262fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
727f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
728f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
7292fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            // OK
7302fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            break;
7312fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        case STATUS_ACTIVE:
7322fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
733f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            res = internalPauseAndWaitLocked();
7342fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            if (res != OK) {
735f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                SET_ERR_L("Can't pause captures to reconfigure streams!");
7362fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                return res;
7372fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            }
7382fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            wasActive = true;
7392fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            break;
7402fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        default:
741f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            SET_ERR_L("Unexpected status: %d", mStatus);
7422fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return INVALID_OPERATION;
7432fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
744f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    assert(mStatus != STATUS_ACTIVE);
7452fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7462fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (mInputStream != 0) {
7472fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
7482fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return INVALID_OPERATION;
7492fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
7502fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7512fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera3ZslStream> newStream = new Camera3ZslStream(mNextStreamId,
7522fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                width, height, depth);
753f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    newStream->setStatusTracker(mStatusTracker);
7542fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7552fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    res = mOutputStreams.add(mNextStreamId, newStream);
7562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (res < 0) {
7572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGE("%s: Can't add new stream to set: %s (%d)",
7582fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                __FUNCTION__, strerror(-res), res);
7592fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        return res;
7602fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
7612fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    mInputStream = newStream;
7622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
763e5e3d0823165dea9211a47232dbbbe361153fb49Yuvraj Pasi    mNeedConfig = true;
764e5e3d0823165dea9211a47232dbbbe361153fb49Yuvraj Pasi
7652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    *id = mNextStreamId++;
7662fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    *zslStream = newStream;
7672fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7682fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    // Continue captures if active at start
7692fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    if (wasActive) {
7702fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
7712fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        res = configureStreamsLocked();
7722fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (res != OK) {
7732fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
7742fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                    __FUNCTION__, mNextStreamId, strerror(-res), res);
7752fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            return res;
7762fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
777f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        internalResumeLocked();
7782fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    }
7792fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
780f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("Camera %d: Created ZSL stream", mId);
7812fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    return OK;
7822fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin}
7832fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
7847fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::createStream(sp<ANativeWindow> consumer,
7857fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        uint32_t width, uint32_t height, int format, size_t size, int *id) {
7867fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
787f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
788f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
789e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu",
790f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mId, mNextStreamId, width, height, format, size);
7917fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
792f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
793f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    bool wasActive = false;
794f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
795f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    switch (mStatus) {
796f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ERROR:
797b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device has encountered a serious error");
798f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
799f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_UNINITIALIZED:
800b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device not initialized");
801f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
802f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
803f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
804f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // OK
805f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
806f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ACTIVE:
807f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
808f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            res = internalPauseAndWaitLocked();
809f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            if (res != OK) {
810f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                SET_ERR_L("Can't pause captures to reconfigure streams!");
811f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                return res;
812f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            }
813f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            wasActive = true;
814f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
815f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        default:
816b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Unexpected status: %d", mStatus);
817f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
818f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
819f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    assert(mStatus != STATUS_ACTIVE);
820f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
821f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    sp<Camera3OutputStream> newStream;
822f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (format == HAL_PIXEL_FORMAT_BLOB) {
823f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        ssize_t jpegBufferSize = getJpegBufferSize(width, height);
824f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        if (jpegBufferSize > 0) {
825f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He            ALOGV("%s: Overwrite Jpeg output buffer size from %zu to %zu",
826f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He                    __FUNCTION__, size, jpegBufferSize);
827f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        } else {
828f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He            SET_ERR_L("Invalid jpeg buffer size %zd", jpegBufferSize);
829f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He            return BAD_VALUE;
830f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He        }
831f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He
832f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        newStream = new Camera3OutputStream(mNextStreamId, consumer,
833f7da096db8655531c2f2b7bddccd1064b1021155Zhijun He                width, height, jpegBufferSize, format);
834f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    } else {
835f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        newStream = new Camera3OutputStream(mNextStreamId, consumer,
836f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                width, height, format);
837f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
838f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    newStream->setStatusTracker(mStatusTracker);
839f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
840f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    res = mOutputStreams.add(mNextStreamId, newStream);
841f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (res < 0) {
842b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
843f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return res;
844f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
845f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
846f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    *id = mNextStreamId++;
847ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala    mNeedConfig = true;
848f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
849f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Continue captures if active at start
850f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (wasActive) {
851f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
852f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        res = configureStreamsLocked();
853f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (res != OK) {
854b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
855b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                    mNextStreamId, strerror(-res), res);
856f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return res;
857f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
858f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        internalResumeLocked();
859f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
860f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("Camera %d: Created new stream", mId);
861f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return OK;
8627fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
8637fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
8647fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
8657fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
8667fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    (void)outputId; (void)id;
8677fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
868b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    CLOGE("Unimplemented");
8697fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return INVALID_OPERATION;
8707fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
8717fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
8727fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
8737fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::getStreamInfo(int id,
8747fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        uint32_t *width, uint32_t *height, uint32_t *format) {
8757fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
876f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
877f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
878f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
879f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    switch (mStatus) {
880f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ERROR:
881b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device has encountered a serious error");
882f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
883f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_UNINITIALIZED:
884b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device not initialized!");
885f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
886f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
887f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
888f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ACTIVE:
889f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // OK
890f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
891f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        default:
892b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Unexpected status: %d", mStatus);
893f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
894f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
8957fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
896f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    ssize_t idx = mOutputStreams.indexOfKey(id);
897f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (idx == NAME_NOT_FOUND) {
898b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        CLOGE("Stream %d is unknown", id);
899f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return idx;
900f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
901f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
902f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (width) *width  = mOutputStreams[idx]->getWidth();
903f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (height) *height = mOutputStreams[idx]->getHeight();
904f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (format) *format = mOutputStreams[idx]->getFormat();
905f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
906f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return OK;
9077fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
9087fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
9097fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::setStreamTransform(int id,
9107fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        int transform) {
9117fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
912f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
913f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
914f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
915f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    switch (mStatus) {
916f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ERROR:
917b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device has encountered a serious error");
918f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
919f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_UNINITIALIZED:
920b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device not initialized");
921f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
922f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
923f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
924f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ACTIVE:
925f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // OK
926f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
927f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        default:
928b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Unexpected status: %d", mStatus);
929f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
930f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
9317fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
932f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    ssize_t idx = mOutputStreams.indexOfKey(id);
933f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (idx == NAME_NOT_FOUND) {
934b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        CLOGE("Stream %d does not exist",
935b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                id);
936f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return BAD_VALUE;
937f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
938f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
939f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return mOutputStreams.editValueAt(idx)->setTransform(transform);
9407fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
9417fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
9427fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::deleteStream(int id) {
9437fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
944f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
945f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
946f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
9477fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
948e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin    ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
949e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin
950f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // CameraDevice semantics require device to already be idle before
951f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // deleteStream is called, unlike for createStream.
952f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mStatus == STATUS_ACTIVE) {
9535282713a976184e41451315f1286d8075b257d58Igor Murashkin        ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
9545282713a976184e41451315f1286d8075b257d58Igor Murashkin        return -EBUSY;
955f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
956f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
9572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin    sp<Camera3StreamInterface> deletedStream;
9585f44635dc35814b98b4dc2b255355a93122fec59Zhijun He    ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
959f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (mInputStream != NULL && id == mInputStream->getId()) {
960f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        deletedStream = mInputStream;
961f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mInputStream.clear();
962f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    } else {
9635f44635dc35814b98b4dc2b255355a93122fec59Zhijun He        if (outputStreamIdx == NAME_NOT_FOUND) {
964b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Stream %d does not exist", id);
965f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return BAD_VALUE;
966f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
9675f44635dc35814b98b4dc2b255355a93122fec59Zhijun He    }
9685f44635dc35814b98b4dc2b255355a93122fec59Zhijun He
9695f44635dc35814b98b4dc2b255355a93122fec59Zhijun He    // Delete output stream or the output part of a bi-directional stream.
9705f44635dc35814b98b4dc2b255355a93122fec59Zhijun He    if (outputStreamIdx != NAME_NOT_FOUND) {
9715f44635dc35814b98b4dc2b255355a93122fec59Zhijun He        deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
972f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mOutputStreams.removeItem(id);
973f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
974f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
975f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Free up the stream endpoint so that it can be used by some other stream
976f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    res = deletedStream->disconnect();
977f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (res != OK) {
978b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Can't disconnect deleted stream %d", id);
979f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // fall through since we want to still list the stream as deleted.
980f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
981f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mDeletedStreams.add(deletedStream);
982ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala    mNeedConfig = true;
983f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
984f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return res;
9857fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
9867fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
9877fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::deleteReprocessStream(int id) {
9887fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
9897fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    (void)id;
9907fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
991b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    CLOGE("Unimplemented");
9927fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return INVALID_OPERATION;
9937fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
9947fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
9957fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
9967fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::createDefaultRequest(int templateId,
9977fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        CameraMetadata *request) {
9987fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
999fe7e0c6154309f2491463ee6ca4920d225289638Alex Ray    ALOGV("%s: for template %d", __FUNCTION__, templateId);
1000f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
1001f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
1002f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1003f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    switch (mStatus) {
1004f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ERROR:
1005b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device has encountered a serious error");
1006f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
1007f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_UNINITIALIZED:
1008b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Device is not initialized!");
1009f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
1010f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
1011f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
1012f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ACTIVE:
1013f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // OK
1014f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
1015f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        default:
1016b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Unexpected status: %d", mStatus);
1017f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
1018f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
10197fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
10207fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    const camera_metadata_t *rawRequest;
102117a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_BEGIN("camera3->construct_default_request_settings");
10227fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    rawRequest = mHal3Device->ops->construct_default_request_settings(
10237fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        mHal3Device, templateId);
102417a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_END();
1025b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    if (rawRequest == NULL) {
1026b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("HAL is unable to construct default settings for template %d",
1027b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                templateId);
1028b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        return DEAD_OBJECT;
1029b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    }
10307fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    *request = rawRequest;
10317fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
10327fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return OK;
10337fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
10347fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
10357fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::waitUntilDrained() {
10367fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
1037f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
1038f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mLock);
10397fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
104069a374897392c8bd70f441b7284f6f578c651ec9Zhijun He    return waitUntilDrainedLocked();
104169a374897392c8bd70f441b7284f6f578c651ec9Zhijun He}
104269a374897392c8bd70f441b7284f6f578c651ec9Zhijun He
104369a374897392c8bd70f441b7284f6f578c651ec9Zhijun Hestatus_t Camera3Device::waitUntilDrainedLocked() {
1044f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    switch (mStatus) {
1045f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_UNINITIALIZED:
1046f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_UNCONFIGURED:
1047f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            ALOGV("%s: Already idle", __FUNCTION__);
1048f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return OK;
1049f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        case STATUS_CONFIGURED:
1050f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            // To avoid race conditions, check with tracker to be sure
1051f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ERROR:
1052f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        case STATUS_ACTIVE:
1053f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            // Need to verify shut down
1054f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
1055f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        default:
1056b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Unexpected status: %d",mStatus);
1057f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
1058f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1059f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1060f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
1061f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
1062f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return res;
1063f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1064f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1065f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala// Pause to reconfigure
1066f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalastatus_t Camera3Device::internalPauseAndWaitLocked() {
1067f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mRequestThread->setPaused(true);
1068f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mPauseStateNotify = true;
1069f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1070f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
1071f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
1072f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (res != OK) {
1073f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        SET_ERR_L("Can't idle device in %f seconds!",
1074f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                kShutdownTimeout/1e9);
1075f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1076f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1077f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return res;
1078f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1079f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1080f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala// Resume after internalPauseAndWaitLocked
1081f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalastatus_t Camera3Device::internalResumeLocked() {
1082f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    status_t res;
1083f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1084f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mRequestThread->setPaused(false);
1085f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1086f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1087f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (res != OK) {
1088f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        SET_ERR_L("Can't transition to active in %f seconds!",
1089f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                kActiveTimeout/1e9);
1090f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1091f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mPauseStateNotify = false;
1092f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return OK;
1093f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1094f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1095f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalastatus_t Camera3Device::waitUntilStateThenRelock(bool active,
1096f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        nsecs_t timeout) {
1097f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    status_t res = OK;
1098f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (active == (mStatus == STATUS_ACTIVE)) {
1099f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // Desired state already reached
1100f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        return res;
1101f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1102f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1103f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    bool stateSeen = false;
1104f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    do {
1105f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mRecentStatusUpdates.clear();
1106f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1107f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        res = mStatusChanged.waitRelative(mLock, timeout);
1108f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (res != OK) break;
1109f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1110f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // Check state change history during wait
1111f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        for (size_t i = 0; i < mRecentStatusUpdates.size(); i++) {
1112f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1113f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                stateSeen = true;
1114f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                break;
1115f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            }
1116f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
1117f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    } while (!stateSeen);
1118f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1119f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return res;
11207fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
11217fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1122f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
11237fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
11247fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
11257d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    Mutex::Autolock l(mOutputLock);
11267fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
11277d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    if (listener != NULL && mListener != NULL) {
11287d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        ALOGW("%s: Replacing old callback listener", __FUNCTION__);
11297d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
11307d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    mListener = listener;
11317d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
11327d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    return OK;
11337fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
11347fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
113546910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvalabool Camera3Device::willNotify3A() {
113646910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    return false;
113746910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala}
113846910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala
11397fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
11407d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    status_t res;
11417d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    Mutex::Autolock l(mOutputLock);
11427fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
11437d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    while (mResultQueue.empty()) {
11447d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        res = mResultSignal.waitRelative(mOutputLock, timeout);
11457d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        if (res == TIMED_OUT) {
11467d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            return res;
11477d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        } else if (res != OK) {
1148e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
1149b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                    __FUNCTION__, mId, timeout, strerror(-res), res);
11507d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            return res;
11517d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        }
11527d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
11537d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    return OK;
11547fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
11557fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1156cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::getNextResult(CaptureResult *frame) {
11577fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
11587d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    Mutex::Autolock l(mOutputLock);
11597fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
11607d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    if (mResultQueue.empty()) {
11617d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        return NOT_ENOUGH_DATA;
11627d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
11637d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
1164cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (frame == NULL) {
1165cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1166cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        return BAD_VALUE;
1167cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    }
1168cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
1169cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    CaptureResult &result = *(mResultQueue.begin());
1170cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    frame->mResultExtras = result.mResultExtras;
1171cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    frame->mMetadata.acquire(result.mMetadata);
11727d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    mResultQueue.erase(mResultQueue.begin());
11737d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
11747d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    return OK;
11757fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
11767fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
11777fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::triggerAutofocus(uint32_t id) {
11787fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
1179f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
11807fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
11814d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
11824d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    // Mix-in this trigger into the next request and only the next request.
11834d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    RequestTrigger trigger[] = {
11844d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        {
11854d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AF_TRIGGER,
11864d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AF_TRIGGER_START
11874d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        },
11884d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        {
11894d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AF_TRIGGER_ID,
11904d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            static_cast<int32_t>(id)
1191741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        }
11924d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    };
11934d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
11944d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return mRequestThread->queueTrigger(trigger,
11954d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                        sizeof(trigger)/sizeof(trigger[0]));
11967fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
11977fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
11987fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
11997fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
1200f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
12017fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
12024d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
12034d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    // Mix-in this trigger into the next request and only the next request.
12044d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    RequestTrigger trigger[] = {
12054d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        {
12064d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AF_TRIGGER,
12074d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AF_TRIGGER_CANCEL
12084d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        },
12094d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        {
12104d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AF_TRIGGER_ID,
12114d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            static_cast<int32_t>(id)
1212741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        }
12134d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    };
12144d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
12154d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return mRequestThread->queueTrigger(trigger,
12164d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                        sizeof(trigger)/sizeof(trigger[0]));
12177fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
12187fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
12197fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
12207fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
1221f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
12227fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
12234d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
12244d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    // Mix-in this trigger into the next request and only the next request.
12254d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    RequestTrigger trigger[] = {
12264d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        {
12274d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
12284d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
12294d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        },
12304d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        {
12314d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ANDROID_CONTROL_AE_PRECAPTURE_ID,
12324d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            static_cast<int32_t>(id)
1233741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        }
12344d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    };
12354d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
12364d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return mRequestThread->queueTrigger(trigger,
12374d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                        sizeof(trigger)/sizeof(trigger[0]));
12387fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
12397fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
12407fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalastatus_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
12417fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
12427fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    ATRACE_CALL();
12437fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    (void)reprocessStreamId; (void)buffer; (void)listener;
12447fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1245b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    CLOGE("Unimplemented");
12467fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    return INVALID_OPERATION;
12477fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
12487fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1249cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::flush(int64_t *frameNumber) {
1250abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ATRACE_CALL();
1251abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
1252f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Mutex::Autolock il(mInterfaceLock);
1253abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
12547ef20390ba4375c4b08edd14923846086987a8c8Zhijun He    {
12557ef20390ba4375c4b08edd14923846086987a8c8Zhijun He        Mutex::Autolock l(mLock);
12567ef20390ba4375c4b08edd14923846086987a8c8Zhijun He        mRequestThread->clear(/*out*/frameNumber);
12577ef20390ba4375c4b08edd14923846086987a8c8Zhijun He    }
12587ef20390ba4375c4b08edd14923846086987a8c8Zhijun He
1259491e341211b4772c75f719158f6b397e1c40497dZhijun He    status_t res;
1260491e341211b4772c75f719158f6b397e1c40497dZhijun He    if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
1261491e341211b4772c75f719158f6b397e1c40497dZhijun He        res = mHal3Device->ops->flush(mHal3Device);
1262491e341211b4772c75f719158f6b397e1c40497dZhijun He    } else {
12637ef20390ba4375c4b08edd14923846086987a8c8Zhijun He        Mutex::Autolock l(mLock);
126469a374897392c8bd70f441b7284f6f578c651ec9Zhijun He        res = waitUntilDrainedLocked();
1265491e341211b4772c75f719158f6b397e1c40497dZhijun He    }
1266491e341211b4772c75f719158f6b397e1c40497dZhijun He
1267491e341211b4772c75f719158f6b397e1c40497dZhijun He    return res;
1268abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala}
1269abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
1270f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala/**
1271f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Methods called by subclasses
1272f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala */
1273f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1274f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid Camera3Device::notifyStatus(bool idle) {
1275f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
1276f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // Need mLock to safely update state and synchronize to current
1277f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // state of methods in flight.
1278f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mLock);
1279f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // We can get various system-idle notices from the status tracker
1280f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // while starting up. Only care about them if we've actually sent
1281f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // in some requests recently.
1282f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1283f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            return;
1284f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
1285f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1286f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                idle ? "idle" : "active");
1287f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE;
1288f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mRecentStatusUpdates.add(mStatus);
1289f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatusChanged.signal();
1290f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1291f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // Skip notifying listener if we're doing some user-transparent
1292f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        // state changes
1293f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mPauseStateNotify) return;
1294f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1295f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    NotificationListener *listener;
1296f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    {
1297f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        Mutex::Autolock l(mOutputLock);
1298f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        listener = mListener;
1299f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1300f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (idle && listener != NULL) {
1301f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        listener->notifyIdle();
1302f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1303f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
1304f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1305f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala/**
1306f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala * Camera3Device private methods
1307f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala */
1308f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1309f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalasp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1310f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        const CameraMetadata &request) {
1311f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    ATRACE_CALL();
1312f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
1313f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1314f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    sp<CaptureRequest> newRequest = new CaptureRequest;
1315f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    newRequest->mSettings = request;
1316f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1317f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    camera_metadata_entry_t inputStreams =
1318f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1319f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (inputStreams.count > 0) {
1320f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (mInputStream == NULL ||
1321d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He                mInputStream->getId() != inputStreams.data.i32[0]) {
1322b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Request references unknown input stream %d",
1323b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                    inputStreams.data.u8[0]);
1324f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return NULL;
1325f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
1326f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // Lazy completion of stream configuration (allocation/registration)
1327f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // on first use
1328f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (mInputStream->isConfiguring()) {
1329f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            res = mInputStream->finishConfiguration(mHal3Device);
1330f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            if (res != OK) {
1331b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                SET_ERR_L("Unable to finish configuring input stream %d:"
1332f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                        " %s (%d)",
1333b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                        mInputStream->getId(), strerror(-res), res);
1334f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                return NULL;
1335f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            }
1336f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
1337f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1338f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        newRequest->mInputStream = mInputStream;
1339f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1340f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1341f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1342f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    camera_metadata_entry_t streams =
1343f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1344f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (streams.count == 0) {
1345b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        CLOGE("Zero output streams specified!");
1346f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return NULL;
1347f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1348f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1349f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    for (size_t i = 0; i < streams.count; i++) {
1350d1d6467d3bcbc1305eeba0176a2edf04925c368eZhijun He        int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
1351f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (idx == NAME_NOT_FOUND) {
1352b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            CLOGE("Request references unknown stream %d",
1353b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                    streams.data.u8[i]);
1354f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return NULL;
1355f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
13562fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        sp<Camera3OutputStreamInterface> stream =
13572fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin                mOutputStreams.editValueAt(idx);
1358f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1359f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // Lazy completion of stream configuration (allocation/registration)
1360f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // on first use
1361f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (stream->isConfiguring()) {
1362f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            res = stream->finishConfiguration(mHal3Device);
1363f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            if (res != OK) {
1364b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1365b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                        stream->getId(), strerror(-res), res);
1366f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                return NULL;
1367f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            }
1368f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
1369f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1370f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        newRequest->mOutputStreams.push(stream);
1371f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1372f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1373f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1374f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return newRequest;
13757fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
13767fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1377f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalastatus_t Camera3Device::configureStreamsLocked() {
1378f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    ATRACE_CALL();
1379f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
13807fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1381f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
1382b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        CLOGE("Not idle");
1383f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return INVALID_OPERATION;
1384f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1385f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1386ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala    if (!mNeedConfig) {
1387ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala        ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1388ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala        return OK;
1389ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala    }
1390ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala
1391f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Start configuring the streams
1392f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
1393f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1394f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    camera3_stream_configuration config;
1395f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1396f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1397f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1398f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Vector<camera3_stream_t*> streams;
1399f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    streams.setCapacity(config.num_streams);
1400f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1401f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (mInputStream != NULL) {
1402f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        camera3_stream_t *inputStream;
1403f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        inputStream = mInputStream->startConfiguration();
1404f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (inputStream == NULL) {
1405b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Can't start input stream configuration");
1406f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
1407f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
1408f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        streams.add(inputStream);
1409f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1410f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1411f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    for (size_t i = 0; i < mOutputStreams.size(); i++) {
14122fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
14132fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        // Don't configure bidi streams twice, nor add them twice to the list
14142fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        if (mOutputStreams[i].get() ==
14152fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            static_cast<Camera3StreamInterface*>(mInputStream.get())) {
14162fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
14172fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            config.num_streams--;
14182fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin            continue;
14192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin        }
14202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin
1421f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        camera3_stream_t *outputStream;
1422f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1423f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (outputStream == NULL) {
1424b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR_L("Can't start output stream configuration");
1425f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return INVALID_OPERATION;
1426f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
1427f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        streams.add(outputStream);
1428f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1429f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1430f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    config.streams = streams.editArray();
1431f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1432f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Do the HAL configuration; will potentially touch stream
1433f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // max_buffers, usage, priv fields.
143417a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_BEGIN("camera3->configure_streams");
1435f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    res = mHal3Device->ops->configure_streams(mHal3Device, &config);
143617a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_END();
1437f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1438f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (res != OK) {
1439b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1440b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                strerror(-res), res);
1441f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return res;
1442f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
1443f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
14444c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala    // Finish all stream configuration immediately.
14454c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala    // TODO: Try to relax this later back to lazy completion, which should be
14464c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala    // faster
14474c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala
1448073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin    if (mInputStream != NULL && mInputStream->isConfiguring()) {
14494c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala        res = mInputStream->finishConfiguration(mHal3Device);
14504c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala        if (res != OK) {
14514c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala            SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
14524c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala                    mInputStream->getId(), strerror(-res), res);
14534c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala            return res;
14544c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala        }
14554c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala    }
14564c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala
14574c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala    for (size_t i = 0; i < mOutputStreams.size(); i++) {
1458073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin        sp<Camera3OutputStreamInterface> outputStream =
1459073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin            mOutputStreams.editValueAt(i);
1460073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin        if (outputStream->isConfiguring()) {
1461073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin            res = outputStream->finishConfiguration(mHal3Device);
1462073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin            if (res != OK) {
1463073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin                SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1464073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin                        outputStream->getId(), strerror(-res), res);
1465073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin                return res;
1466073f8570d8404b6d1ea3a1bd34954c6332ba991aIgor Murashkin            }
14674c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala        }
14684c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala    }
14694c95676d259f4449a7da5161dfd46c1d1f9498feEino-Ville Talvala
1470f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Request thread needs to know to avoid using repeat-last-settings protocol
1471f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // across configure_streams() calls
1472f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mRequestThread->configurationComplete();
1473f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1474f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Update device state
1475f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1476ea26c7772f4721657db409068d4bed194ae49c94Eino-Ville Talvala    mNeedConfig = false;
1477f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1478f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (config.num_streams > 0) {
1479f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatus = STATUS_CONFIGURED;
1480f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    } else {
1481f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatus = STATUS_UNCONFIGURED;
1482f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1483f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1484f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1485f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
1486f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return OK;
14877fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
14887fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
1489b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvalavoid Camera3Device::setErrorState(const char *fmt, ...) {
1490b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    Mutex::Autolock l(mLock);
1491b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    va_list args;
1492b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    va_start(args, fmt);
1493b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1494b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    setErrorStateLockedV(fmt, args);
1495b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1496b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    va_end(args);
1497b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala}
1498b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1499b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvalavoid Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1500b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    Mutex::Autolock l(mLock);
1501b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    setErrorStateLockedV(fmt, args);
1502b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala}
1503b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1504b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvalavoid Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1505b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    va_list args;
1506b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    va_start(args, fmt);
1507b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1508b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    setErrorStateLockedV(fmt, args);
1509b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1510b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    va_end(args);
1511b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala}
1512b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1513b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvalavoid Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
151442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    // Print out all error messages to log
151542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    String8 errorCause = String8::formatV(fmt, args);
151642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    ALOGE("Camera %d: %s", mId, errorCause.string());
151742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
151842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    // But only do error state transition steps for the first error
1519b05eeaedacaff92b6e5ac89f99b0fccdf7643f09Zhijun He    if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
1520b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
1521ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    // Save stack trace. View by dumping it later.
1522ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    CameraTraces::saveTrace();
1523ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    // TODO: consider adding errorCause and client pid/procname
1524ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin
152542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    mErrorCause = errorCause;
152642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
152742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    mRequestThread->setPaused(true);
1528b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    mStatus = STATUS_ERROR;
1529b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala}
1530f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
1531f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala/**
153242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala * In-flight request management
153342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala */
153442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
1535cb0652e5a850b2fcd919e977247e87239efaf70eJianing Weistatus_t Camera3Device::registerInFlight(uint32_t frameNumber,
1536c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput) {
153742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    ATRACE_CALL();
153842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    Mutex::Autolock l(mInFlightLock);
153942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
154042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    ssize_t res;
1541c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput));
154242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    if (res < 0) return res;
154342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
154442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    return OK;
154542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala}
154642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
154742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala/**
1548fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala * QUIRK(partial results)
1549fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala * Check if all 3A fields are ready, and send off a partial 3A-only result
1550fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala * to the output frame queue
1551fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala */
1552184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvalabool Camera3Device::processPartial3AQuirk(
1553cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        uint32_t frameNumber,
1554cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
1555fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1556fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // Check if all 3A states are present
1557fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // The full list of fields is
1558fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.afMode
1559fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.awbMode
1560fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.aeState
1561fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.awbState
1562fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.afState
1563fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.afTriggerID
1564fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.control.aePrecaptureID
1565fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // TODO: Add android.control.aeMode
1566fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1567fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    bool gotAllStates = true;
1568fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1569fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    uint8_t afMode;
1570fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    uint8_t awbMode;
1571fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    uint8_t aeState;
1572fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    uint8_t afState;
1573fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    uint8_t awbState;
1574fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1575fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1576fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        &afMode, frameNumber);
1577fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1578fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1579fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        &awbMode, frameNumber);
1580fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1581fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1582fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        &aeState, frameNumber);
1583fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1584fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1585fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        &afState, frameNumber);
1586fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1587fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1588fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        &awbState, frameNumber);
1589fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1590fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (!gotAllStates) return false;
1591fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1592184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala    ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
1593fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        "AF state %d, AE state %d, AWB state %d, "
1594fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        "AF trigger %d, AE precapture trigger %d",
15952d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        __FUNCTION__, mId, frameNumber, resultExtras.requestId,
1596fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        afMode, awbMode,
1597fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        afState, aeState, awbState,
1598741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        resultExtras.afTriggerId, resultExtras.precaptureTriggerId);
1599fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1600fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // Got all states, so construct a minimal result to send
1601fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    // In addition to the above fields, this means adding in
1602fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.request.frameCount
1603184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala    //   android.request.requestId
1604fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    //   android.quirks.partialResult
1605fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1606184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala    const size_t kMinimal3AResultEntries = 10;
1607fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1608fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    Mutex::Autolock l(mOutputLock);
1609fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1610cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    CaptureResult captureResult;
1611cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    captureResult.mResultExtras = resultExtras;
1612cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
1613cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    // TODO: change this to sp<CaptureResult>. This will need other changes, including,
1614cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    // but not limited to CameraDeviceBase::getNextResult
1615cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    CaptureResult& min3AResult =
1616cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            *mResultQueue.insert(mResultQueue.end(), captureResult);
1617cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
1618cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
1619cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            // TODO: This is problematic casting. Need to fix CameraMetadata.
1620cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
1621fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1622fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1623fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1624cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    int32_t requestId = resultExtras.requestId;
1625cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
1626184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala            &requestId, frameNumber)) {
1627184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala        return false;
1628184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala    }
1629184dfe4ea5e2ba33951bed2b1366007aee0ce3daEino-Ville Talvala
1630fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1631cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
1632fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            &partialResult, frameNumber)) {
1633fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1634fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1635fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1636cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
1637fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            &afMode, frameNumber)) {
1638fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1639fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1640fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1641cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
1642fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            &awbMode, frameNumber)) {
1643fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1644fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1645fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1646cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
1647fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            &aeState, frameNumber)) {
1648fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1649fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1650fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1651cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
1652fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            &afState, frameNumber)) {
1653fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1654fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1655fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1656cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
1657fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            &awbState, frameNumber)) {
1658fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1659fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1660fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1661cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
1662741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            &resultExtras.afTriggerId, frameNumber)) {
1663fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1664fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1665fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1666cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1667741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            &resultExtras.precaptureTriggerId, frameNumber)) {
1668fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1669fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1670fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1671fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    mResultSignal.signal();
1672fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1673fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return true;
1674fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala}
1675fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1676fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvalatemplate<typename T>
1677fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvalabool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
1678cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        T* value, uint32_t frameNumber) {
1679fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    (void) frameNumber;
1680fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1681fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    camera_metadata_ro_entry_t entry;
1682fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1683fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    entry = result.find(tag);
1684fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (entry.count == 0) {
1685fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
1686fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            mId, frameNumber, get_camera_metadata_tag_name(tag));
1687fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1688fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1689fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1690fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (sizeof(T) == sizeof(uint8_t)) {
1691fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        *value = entry.data.u8[0];
1692fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    } else if (sizeof(T) == sizeof(int32_t)) {
1693fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        *value = entry.data.i32[0];
1694fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    } else {
1695fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        ALOGE("%s: Unexpected type", __FUNCTION__);
1696fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1697fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1698fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return true;
1699fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala}
1700fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1701fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvalatemplate<typename T>
1702fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvalabool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
1703cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        const T* value, uint32_t frameNumber) {
1704fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (result.update(tag, value, 1) != NO_ERROR) {
1705fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
1706fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        SET_ERR("Frame %d: Failed to set %s in partial metadata",
1707fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                frameNumber, get_camera_metadata_tag_name(tag));
1708fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        return false;
1709fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    }
1710fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    return true;
1711fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala}
1712fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1713fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala/**
1714f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala * Camera HAL device callback methods
1715f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala */
1716f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
17177fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalavoid Camera3Device::processCaptureResult(const camera3_capture_result *result) {
17187d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    ATRACE_CALL();
17197d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
17207d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    status_t res;
17217d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
172242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    uint32_t frameNumber = result->frame_number;
1723f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (result->result == NULL && result->num_output_buffers == 0 &&
1724f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He            result->input_buffer == NULL) {
172542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        SET_ERR("No result data provided by HAL for frame %d",
172642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                frameNumber);
17277d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        return;
17287d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
1729fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    bool partialResultQuirk = false;
1730fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    CameraMetadata collectedQuirkResult;
1731cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    CaptureResultExtras resultExtras;
1732c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He    bool hasInputBufferInRequest = false;
17337d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
1734cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    // Get capture timestamp and resultExtras from list of in-flight requests,
1735cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    // where it was added by the shutter notification for this frame.
1736cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    // Then update the in-flight status and remove the in-flight entry if
1737cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    // all result data has been received.
17387d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    nsecs_t timestamp = 0;
173942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    {
174042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        Mutex::Autolock l(mInFlightLock);
174142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
174242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        if (idx == NAME_NOT_FOUND) {
174342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            SET_ERR("Unknown frame number for capture result: %d",
174442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber);
174542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            return;
174642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
174742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        InFlightRequest &request = mInFlightMap.editValueAt(idx);
1748cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64
1749cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                ", burstId = %" PRId32,
1750cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber,
1751cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                request.resultExtras.burstId);
1752fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1753fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        // Check if this result carries only partial metadata
1754fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        if (mUsePartialResultQuirk && result->result != NULL) {
1755fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            camera_metadata_ro_entry_t partialResultEntry;
1756fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            res = find_camera_metadata_ro_entry(result->result,
1757fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1758fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            if (res != NAME_NOT_FOUND &&
1759fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    partialResultEntry.count > 0 &&
1760fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    partialResultEntry.data.u8[0] ==
1761fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1762fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                // A partial result. Flag this as such, and collect this
1763fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                // set of metadata into the in-flight entry.
1764fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                partialResultQuirk = true;
1765fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                request.partialResultQuirk.collectedResult.append(
1766fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    result->result);
1767fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                request.partialResultQuirk.collectedResult.erase(
1768fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    ANDROID_QUIRKS_PARTIAL_RESULT);
1769fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                // Fire off a 3A-only result if possible
1770fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                if (!request.partialResultQuirk.haveSent3A) {
1771fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    request.partialResultQuirk.haveSent3A =
1772fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                            processPartial3AQuirk(frameNumber,
1773cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                    request.partialResultQuirk.collectedResult,
1774cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                    request.resultExtras);
1775fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                }
1776fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            }
1777fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        }
1778fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
177942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        timestamp = request.captureTimestamp;
1780cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        resultExtras = request.resultExtras;
1781c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        hasInputBufferInRequest = request.hasInputBuffer;
1782cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
17831d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He        /**
1784fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala         * One of the following must happen before it's legal to call process_capture_result,
1785fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala         * unless partial metadata is being provided:
17861d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He         * - CAMERA3_MSG_SHUTTER (expected during normal operation)
17871d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He         * - CAMERA3_MSG_ERROR (expected during flush)
17881d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He         */
1789fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) {
179042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            SET_ERR("Called before shutter notify for frame %d",
179142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber);
179242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            return;
179342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
179442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
1795fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        // Did we get the (final) result metadata for this capture?
1796fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        if (result->result != NULL && !partialResultQuirk) {
179742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            if (request.haveResultMetadata) {
179842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                SET_ERR("Called multiple times with metadata for frame %d",
179942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                        frameNumber);
180042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                return;
180142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            }
1802fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            if (mUsePartialResultQuirk &&
1803fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    !request.partialResultQuirk.collectedResult.isEmpty()) {
1804fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                collectedQuirkResult.acquire(
1805fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala                    request.partialResultQuirk.collectedResult);
1806fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            }
180742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            request.haveResultMetadata = true;
180842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
180942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
1810c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        uint32_t numBuffersReturned = result->num_output_buffers;
1811c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        if (result->input_buffer != NULL) {
1812c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            if (hasInputBufferInRequest) {
1813c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                numBuffersReturned += 1;
1814c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            } else {
1815c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                ALOGW("%s: Input buffer should be NULL if there is no input"
1816c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                        " buffer sent in the request",
1817c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                        __FUNCTION__);
1818c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            }
1819c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        }
1820c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        request.numBuffersLeft -= numBuffersReturned;
182142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        if (request.numBuffersLeft < 0) {
182242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            SET_ERR("Too many buffers returned for frame %d",
182342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber);
182442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            return;
182542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
182642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
18271b05dfc8df5e741086747d076fc39c79fb4acb33Zhijun He        // Check if everything has arrived for this result (buffers and metadata), remove it from
18281b05dfc8df5e741086747d076fc39c79fb4acb33Zhijun He        // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush).
18291b05dfc8df5e741086747d076fc39c79fb4acb33Zhijun He        if ((request.requestStatus != OK) ||
18301b05dfc8df5e741086747d076fc39c79fb4acb33Zhijun He                (request.haveResultMetadata && request.numBuffersLeft == 0)) {
183117a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala            ATRACE_ASYNC_END("frame capture", frameNumber);
183242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            mInFlightMap.removeItemsAt(idx, 1);
183342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
183442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
183542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        // Sanity check - if we have too many in-flight frames, something has
183642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        // likely gone wrong
183742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        if (mInFlightMap.size() > kInFlightWarnLimit) {
1838e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            CLOGE("In-flight list too large: %zu", mInFlightMap.size());
183942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
184042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
184142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    }
184242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
184342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    // Process the result metadata, if provided
1844fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    bool gotResult = false;
1845fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (result->result != NULL && !partialResultQuirk) {
18467d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        Mutex::Autolock l(mOutputLock);
18477d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
1848fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        gotResult = true;
1849fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
18503c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei        // TODO: need to track errors for tighter bounds on expected frame number
18513c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei        if (frameNumber < mNextResultFrameNumber) {
185242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            SET_ERR("Out-of-order capture result metadata submitted! "
185342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    "(got frame number %d, expecting %d)",
185442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber, mNextResultFrameNumber);
185542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            return;
185642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        }
18573c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei        mNextResultFrameNumber = frameNumber + 1;
185842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
1859cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        CaptureResult captureResult;
1860cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        captureResult.mResultExtras = resultExtras;
1861cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        captureResult.mMetadata = result->result;
1862fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1863cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
1864cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                (int32_t*)&frameNumber, 1) != OK) {
1865b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR("Failed to set frame# in metadata (%d)",
186642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber);
1867fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            gotResult = false;
1868d2c90696403bb3c9e28d7b51d65c9468bdf8e78bIgor Murashkin        } else {
1869d2c90696403bb3c9e28d7b51d65c9468bdf8e78bIgor Murashkin            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
187042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    __FUNCTION__, mId, frameNumber);
1871d2c90696403bb3c9e28d7b51d65c9468bdf8e78bIgor Murashkin        }
18727d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
1873fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        // Append any previous partials to form a complete result
1874fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
1875cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            captureResult.mMetadata.append(collectedQuirkResult);
1876fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        }
1877fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1878cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        captureResult.mMetadata.sort();
1879fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
188042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        // Check that there's a timestamp in the result metadata
18817d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
18827d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        camera_metadata_entry entry =
1883cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
18847d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        if (entry.count == 0) {
1885b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala            SET_ERR("No timestamp provided by HAL for frame %d!",
188642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber);
1887fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            gotResult = false;
1888fe7e0c6154309f2491463ee6ca4920d225289638Alex Ray        } else if (timestamp != entry.data.i64[0]) {
188942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            SET_ERR("Timestamp mismatch between shutter notify and result"
1890e5729fac81c8a984e984fefc90afc64135817d4fColin Cross                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
189142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    frameNumber, timestamp, entry.data.i64[0]);
1892fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            gotResult = false;
1893fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        }
1894fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala
1895fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala        if (gotResult) {
1896fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala            // Valid result, insert into queue
1897cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            List<CaptureResult>::iterator queuedResult =
1898cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
1899cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
1900cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                   ", burstId = %" PRId32, __FUNCTION__,
1901cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                   queuedResult->mResultExtras.requestId,
1902cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                   queuedResult->mResultExtras.frameNumber,
1903cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                   queuedResult->mResultExtras.burstId);
19047d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        }
19057d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    } // scope for mOutputLock
19067d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
190742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    // Return completed buffers to their streams with the timestamp
190842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
19097d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    for (size_t i = 0; i < result->num_output_buffers; i++) {
19107d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        Camera3Stream *stream =
19117d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala                Camera3Stream::cast(result->output_buffers[i].stream);
19127d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        res = stream->returnBuffer(result->output_buffers[i], timestamp);
19137d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        // Note: stream may be deallocated at this point, if this buffer was the
19147d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        // last reference to it.
19157d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        if (res != OK) {
1916e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            ALOGE("Can't return buffer %zu for frame %d to its stream: "
191742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    " %s (%d)", i, frameNumber, strerror(-res), res);
19187d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        }
19197d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
19207d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
1921f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    if (result->input_buffer != NULL) {
1922c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He        if (hasInputBufferInRequest) {
1923c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            Camera3Stream *stream =
1924c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                Camera3Stream::cast(result->input_buffer->stream);
1925c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            res = stream->returnInputBuffer(*(result->input_buffer));
1926c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            // Note: stream may be deallocated at this point, if this buffer was the
1927c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            // last reference to it.
1928c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            if (res != OK) {
1929c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
1930c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                      "  its stream:%s (%d)",  __FUNCTION__,
1931c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He                      frameNumber, strerror(-res), res);
19320ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            }
19330ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He        } else {
19340ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He            ALOGW("%s: Input buffer should be NULL if there is no input"
19350ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                    " buffer sent in the request, skipping input buffer return.",
19360ea8fa4ccbf9b2b179370b983f3887d3daf2381fZhijun He                    __FUNCTION__);
1937f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        }
1938f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    }
1939f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He
194046910bdc57c35ac36bd4adcbb76f4f3a590e3f21Eino-Ville Talvala    // Finally, signal any waiters for new frames
194142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
1942fd6ecdd39bd83ea020f78b425e96310380d66c35Eino-Ville Talvala    if (gotResult) {
19434345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin        mResultSignal.signal();
19444345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin    }
19454345d5b57a93ec6d003df84f5cce2db7cccfbd86Igor Murashkin
19467fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
19477fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
19487fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalavoid Camera3Device::notify(const camera3_notify_msg *msg) {
194917a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_CALL();
19507d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    NotificationListener *listener;
19517d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    {
19527d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        Mutex::Autolock l(mOutputLock);
19537d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        listener = mListener;
19547d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
19557fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
19567d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    if (msg == NULL) {
195742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        SET_ERR("HAL sent NULL notify message!");
19587d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        return;
19597d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
19607d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala
19617d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    switch (msg->type) {
19627d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        case CAMERA3_MSG_ERROR: {
19637d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            int streamId = 0;
19647d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            if (msg->message.error.error_stream != NULL) {
19657d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala                Camera3Stream *stream =
19667d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala                        Camera3Stream::cast(
19677d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala                                  msg->message.error.error_stream);
19687d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala                streamId = stream->getId();
19697d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            }
197017a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala            ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
197117a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala                    mId, __FUNCTION__, msg->message.error.frame_number,
197217a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala                    streamId, msg->message.error.error_code);
19731d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He
1974cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            CaptureResultExtras resultExtras;
19751d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He            // Set request error status for the request in the in-flight tracking
19761d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He            {
19771d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He                Mutex::Autolock l(mInFlightLock);
19781d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He                ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
19791d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He                if (idx >= 0) {
1980cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
1981cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    r.requestStatus = msg->message.error.error_code;
1982cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    resultExtras = r.resultExtras;
1983cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                } else {
1984cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    resultExtras.frameNumber = msg->message.error.frame_number;
1985cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64
1986cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                          " error", mId, __FUNCTION__, resultExtras.frameNumber);
19871d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He                }
19881d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He            }
19891d1f846c0dbaa36d0944e7b1e54cc07863e00a92Zhijun He
199042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            if (listener != NULL) {
1991cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
1992cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
1993cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                                          resultExtras);
1994cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                }
1995cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            } else {
1996cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
199742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            }
19987d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            break;
19997d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        }
20007d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        case CAMERA3_MSG_SHUTTER: {
200142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            ssize_t idx;
200242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            uint32_t frameNumber = msg->message.shutter.frame_number;
200342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            nsecs_t timestamp = msg->message.shutter.timestamp;
200442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            // Verify ordering of shutter notifications
200542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            {
200642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                Mutex::Autolock l(mOutputLock);
20073c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei                // TODO: need to track errors for tighter bounds on expected frame number.
20083c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei                if (frameNumber < mNextShutterFrameNumber) {
200942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    SET_ERR("Shutter notification out-of-order. Expected "
201042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                            "notification for frame %d, got frame %d",
201142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                            mNextShutterFrameNumber, frameNumber);
201242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    break;
201342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                }
20143c76fa3e73374dfe7bb93e1b03fed30749e1e4b9Jianing Wei                mNextShutterFrameNumber = frameNumber + 1;
201542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            }
201642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
2017cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            CaptureResultExtras resultExtras;
2018f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
201942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            // Set timestamp for the request in the in-flight tracking
2020f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            // and get the request ID to send upstream
202142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            {
202242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                Mutex::Autolock l(mInFlightLock);
202342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                idx = mInFlightMap.indexOfKey(frameNumber);
202442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                if (idx >= 0) {
2025f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    InFlightRequest &r = mInFlightMap.editValueAt(idx);
2026f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    r.captureTimestamp = timestamp;
2027cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    resultExtras = r.resultExtras;
202842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                }
202942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            }
203042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            if (idx < 0) {
203142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                SET_ERR("Shutter notification for non-existent frame number %d",
203242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                        frameNumber);
203342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                break;
203442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            }
2035e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
2036cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                    mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp);
203742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            // Call listener, if any
203842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            if (listener != NULL) {
2039cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei                listener->notifyShutter(resultExtras, timestamp);
204042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            }
20417d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala            break;
20427d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        }
20437d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala        default:
204442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            SET_ERR("Unknown notify message from HAL: %d",
2045b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                    msg->type);
20467d346fa448551703f98e8892ae7f4eb56675b92aEino-Ville Talvala    }
20477fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
20487fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
2049f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville TalvalaCameraMetadata Camera3Device::getLatestRequestLocked() {
20501e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    ALOGV("%s", __FUNCTION__);
20511e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
20521e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    CameraMetadata retVal;
20531e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
20541e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    if (mRequestThread != NULL) {
20551e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        retVal = mRequestThread->getLatestRequest();
20561e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    }
20571e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
20581e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    return retVal;
20591e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin}
20601e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
2061cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
20627fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala/**
2063f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala * RequestThread inner class methods
2064f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala */
2065f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2066f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville TalvalaCamera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
2067f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker,
2068f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        camera3_device_t *hal3Device) :
2069f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        Thread(false),
2070f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mParent(parent),
2071f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        mStatusTracker(statusTracker),
2072f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mHal3Device(hal3Device),
207342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        mId(getId(parent)),
2074f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mReconfigured(false),
2075f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mDoPause(false),
2076f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mPaused(true),
20774d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        mFrameNumber(0),
2078cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei        mLatestRequestId(NAME_NOT_FOUND),
20792d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
2080f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mStatusId = statusTracker->addComponent();
2081f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2082f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2083f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalavoid Camera3Device::RequestThread::configurationComplete() {
2084f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mRequestLock);
2085f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mReconfigured = true;
2086f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2087f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
208890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Weistatus_t Camera3Device::RequestThread::queueRequestList(
20892d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        List<sp<CaptureRequest> > &requests,
20902d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        /*out*/
20912d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        int64_t *lastFrameNumber) {
209290e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    Mutex::Autolock l(mRequestLock);
209390e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
209490e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei            ++it) {
209590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei        mRequestQueue.push_back(*it);
209690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    }
209790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
20982d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    if (lastFrameNumber != NULL) {
20992d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
21002d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
21012d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei              __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
21022d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei              *lastFrameNumber);
21032d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    }
2104cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
210590e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    unpauseForNewRequests();
210690e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
210790e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei    return OK;
210890e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei}
210990e59c98c343e941b1a75307ffa4b4b5f1eb50d6Jianing Wei
21104d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21114d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkinstatus_t Camera3Device::RequestThread::queueTrigger(
21124d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        RequestTrigger trigger[],
21134d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        size_t count) {
21144d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21154d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    Mutex::Autolock l(mTriggerMutex);
21164d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    status_t ret;
21174d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21184d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    for (size_t i = 0; i < count; ++i) {
21194d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        ret = queueTriggerLocked(trigger[i]);
21204d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21214d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        if (ret != OK) {
21224d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            return ret;
21234d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
21244d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
21254d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21264d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return OK;
21274d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin}
21284d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
212942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvalaint Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
213042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    sp<Camera3Device> d = device.promote();
213142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    if (d != NULL) return d->mId;
213242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    return 0;
213342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala}
213442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
21354d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkinstatus_t Camera3Device::RequestThread::queueTriggerLocked(
21364d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        RequestTrigger trigger) {
21374d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21384d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    uint32_t tag = trigger.metadataTag;
21394d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    ssize_t index = mTriggerMap.indexOfKey(tag);
21404d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21414d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    switch (trigger.getTagType()) {
21424d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        case TYPE_BYTE:
21434d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        // fall-through
21444d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        case TYPE_INT32:
21454d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            break;
21464d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        default:
214742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala            ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
214842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                    trigger.getTagType());
21494d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            return INVALID_OPERATION;
21504d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
21514d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21524d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    /**
21534d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     * Collect only the latest trigger, since we only have 1 field
21544d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     * in the request settings per trigger tag, and can't send more than 1
21554d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     * trigger per request.
21564d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     */
21574d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    if (index != NAME_NOT_FOUND) {
21584d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        mTriggerMap.editValueAt(index) = trigger;
21594d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    } else {
21604d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        mTriggerMap.add(tag, trigger);
21614d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
21624d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
21634d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return OK;
21644d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin}
21654d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2166f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalastatus_t Camera3Device::RequestThread::setRepeatingRequests(
21672d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        const RequestList &requests,
21682d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        /*out*/
21692d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        int64_t *lastFrameNumber) {
2170f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mRequestLock);
21712d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    if (lastFrameNumber != NULL) {
21722d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        *lastFrameNumber = mRepeatingLastFrameNumber;
21732d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    }
2174f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mRepeatingRequests.clear();
2175f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mRepeatingRequests.insert(mRepeatingRequests.begin(),
2176f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            requests.begin(), requests.end());
217726fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala
217826fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    unpauseForNewRequests();
217926fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala
21802d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2181f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return OK;
2182f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2183f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
21848684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yehbool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest> requestIn) {
21858684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    if (mRepeatingRequests.empty()) {
21868684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh        return false;
21878684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    }
21888684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    int32_t requestId = requestIn->mResultExtras.requestId;
21898684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    const RequestList &repeatRequests = mRepeatingRequests;
21908684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    // All repeating requests are guaranteed to have same id so only check first quest
21918684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
21928684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    return (firstRequest->mResultExtras.requestId == requestId);
21938684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh}
21948684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh
21952d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Weistatus_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
2196f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mRequestLock);
2197f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mRepeatingRequests.clear();
21982d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    if (lastFrameNumber != NULL) {
21992d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        *lastFrameNumber = mRepeatingLastFrameNumber;
22002d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    }
22012d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2202f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return OK;
2203f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2204f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
22052d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Weistatus_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) {
2206abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    Mutex::Autolock l(mRequestLock);
22072d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    ALOGV("RequestThread::%s:", __FUNCTION__);
2208abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    mRepeatingRequests.clear();
22098684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh
22108684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    // Decrement repeating frame count for those requests never sent to device
22118684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    // TODO: Remove this after we have proper error handling so these requests
22128684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    // will generate an error callback. This might be the only place calling
22138684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    // isRepeatingRequestLocked. If so, isRepeatingRequestLocked should also be removed.
22148684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    const RequestList &requests = mRequestQueue;
22158684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    for (RequestList::const_iterator it = requests.begin();
22168684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh            it != requests.end(); ++it) {
22178684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh        if (isRepeatingRequestLocked(*it)) {
22188684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh            mRepeatingLastFrameNumber--;
22198684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh        }
22208684b7f7977f535260367040931c1fd994cca3b4Yin-Chia Yeh    }
2221abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    mRequestQueue.clear();
2222abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    mTriggerMap.clear();
22232d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    if (lastFrameNumber != NULL) {
22242d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        *lastFrameNumber = mRepeatingLastFrameNumber;
22252d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    }
22262d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
2227abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala    return OK;
2228abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala}
2229abaa51d3ca31f0eda99e1d271e6dc64c877dbf58Eino-Ville Talvala
2230f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalavoid Camera3Device::RequestThread::setPaused(bool paused) {
2231f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mPauseLock);
2232f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mDoPause = paused;
2233f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mDoPauseSignal.signal();
2234f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2235f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
22364d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkinstatus_t Camera3Device::RequestThread::waitUntilRequestProcessed(
22374d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        int32_t requestId, nsecs_t timeout) {
22384d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    Mutex::Autolock l(mLatestRequestMutex);
22394d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    status_t res;
22404d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    while (mLatestRequestId != requestId) {
22414d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        nsecs_t startTime = systemTime();
22424d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
22434d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
22444d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        if (res != OK) return res;
22454d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
22464d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        timeout -= (systemTime() - startTime);
22474d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
22484d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
22494d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return OK;
22504d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin}
22514d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2252f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid Camera3Device::RequestThread::requestExit() {
2253f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Call parent to set up shutdown
2254f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    Thread::requestExit();
2255f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // The exit from any possible waits
2256f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mDoPauseSignal.signal();
2257f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mRequestSignal.signal();
2258f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}
22594d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2260f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalabool Camera3Device::RequestThread::threadLoop() {
2261f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2262f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
2263f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2264f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Handle paused state.
2265f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (waitIfPaused()) {
2266f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return true;
2267f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2268f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2269f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Get work to do
2270f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2271f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    sp<CaptureRequest> nextRequest = waitForNextRequest();
2272f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (nextRequest == NULL) {
2273f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return true;
2274f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2275f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2276f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Create request to HAL
2277f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    camera3_capture_request_t request = camera3_capture_request_t();
22782d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    request.frame_number = nextRequest->mResultExtras.frameNumber;
22794d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    Vector<camera3_stream_buffer_t> outputBuffers;
2280f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2281f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Get the request ID, if any
2282f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    int requestId;
2283f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    camera_metadata_entry_t requestIdEntry =
2284f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2285f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (requestIdEntry.count > 0) {
2286f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        requestId = requestIdEntry.data.i32[0];
2287f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    } else {
2288f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGW("%s: Did not have android.request.id set in the request",
2289f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                __FUNCTION__);
2290f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        requestId = NAME_NOT_FOUND;
2291f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
2292f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
22934d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    // Insert any queued triggers (before metadata is locked)
22944d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    int32_t triggerCount;
22954d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    res = insertTriggers(nextRequest);
22964d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    if (res < 0) {
2297b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR("RequestThread: Unable to insert triggers "
2298b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala                "(capture request %d, HAL device: %s (%d)",
22992d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei                request.frame_number, strerror(-res), res);
23004d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        cleanUpFailedRequest(request, nextRequest, outputBuffers);
23014d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        return false;
23024d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
23034d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    triggerCount = res;
23044d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
23054d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
23064d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
23074d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    // If the request is the same as last, or we had triggers last time
23084d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    if (mPrevRequest != nextRequest || triggersMixedIn) {
23094d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        /**
23102f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala         * HAL workaround:
23112f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala         * Insert a dummy trigger ID if a trigger is set but no trigger ID is
23122f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala         */
23132f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        res = addDummyTriggerIds(nextRequest);
23142f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        if (res != OK) {
23152f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
23162f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala                    "(capture request %d, HAL device: %s (%d)",
23172d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei                    request.frame_number, strerror(-res), res);
23182f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            cleanUpFailedRequest(request, nextRequest, outputBuffers);
23192f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            return false;
23202f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        }
23212f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala
23222f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        /**
23234d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin         * The request should be presorted so accesses in HAL
23244d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin         *   are O(logn). Sidenote, sorting a sorted metadata is nop.
23254d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin         */
23264d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        nextRequest->mSettings.sort();
2327f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        request.settings = nextRequest->mSettings.getAndLock();
2328f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mPrevRequest = nextRequest;
23294d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        ALOGVV("%s: Request settings are NEW", __FUNCTION__);
23304d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
23314d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        IF_ALOGV() {
23324d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
23334d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            find_camera_metadata_ro_entry(
23344d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                    request.settings,
23354d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                    ANDROID_CONTROL_AF_TRIGGER,
23364d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                    &e
23374d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            );
23384d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            if (e.count > 0) {
23394d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
23404d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                      __FUNCTION__,
23412d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei                      request.frame_number,
23424d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                      e.data.u8[0]);
23434d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            }
23444d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
23454d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    } else {
23464d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        // leave request.settings NULL to indicate 'reuse latest given'
23474d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        ALOGVV("%s: Request settings are REUSED",
23484d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin               __FUNCTION__);
23494d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
2350f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2351f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    camera3_stream_buffer_t inputBuffer;
2352f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    uint32_t totalNumBuffers = 0;
2353f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2354f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Fill in buffers
2355f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2356f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (nextRequest->mInputStream != NULL) {
2357f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        request.input_buffer = &inputBuffer;
23585a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
2359f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (res != OK) {
236007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala            ALOGE("RequestThread: Can't get input buffer, skipping request:"
2361f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                    " %s (%d)", strerror(-res), res);
2362f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2363f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return true;
2364f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
2365f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        totalNumBuffers += 1;
2366f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    } else {
2367f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        request.input_buffer = NULL;
2368f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2369f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2370f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2371f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            nextRequest->mOutputStreams.size());
2372f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    request.output_buffers = outputBuffers.array();
2373f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2374f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        res = nextRequest->mOutputStreams.editItemAt(i)->
2375f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                getBuffer(&outputBuffers.editItemAt(i));
2376f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (res != OK) {
237707d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala            ALOGE("RequestThread: Can't get output buffer, skipping request:"
237807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala                    " %s (%d)", strerror(-res), res);
2379f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            cleanUpFailedRequest(request, nextRequest, outputBuffers);
2380f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return true;
2381f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
2382f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        request.num_output_buffers++;
2383f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2384f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He    totalNumBuffers += request.num_output_buffers;
2385f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
238642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    // Log request in the in-flight queue
238742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    sp<Camera3Device> parent = mParent.promote();
238842368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    if (parent == NULL) {
238942368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        CLOGE("RequestThread: Parent is gone");
239042368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        cleanUpFailedRequest(request, nextRequest, outputBuffers);
239142368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        return false;
239242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    }
239342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala
2394cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei    res = parent->registerInFlight(request.frame_number,
2395c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            totalNumBuffers, nextRequest->mResultExtras,
2396c98bd8d9bf81663b5cd9c79e79d6e7869c1146e6Zhijun He            /*hasInput*/request.input_buffer != NULL);
23972d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
23982d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei           ", burstId = %" PRId32 ".",
2399cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            __FUNCTION__,
2400cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
2401cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei            nextRequest->mResultExtras.burstId);
240242368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    if (res != OK) {
240342368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        SET_ERR("RequestThread: Unable to register new in-flight request:"
240442368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala                " %s (%d)", strerror(-res), res);
240542368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        cleanUpFailedRequest(request, nextRequest, outputBuffers);
240642368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala        return false;
240742368d9308db27a47c9ac706f9b040fa269257a9Eino-Ville Talvala    }
24084d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2409cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He    // Inform waitUntilRequestProcessed thread of a new request ID
2410cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He    {
2411cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He        Mutex::Autolock al(mLatestRequestMutex);
2412cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He
2413cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He        mLatestRequestId = requestId;
2414cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He        mLatestRequestSignal.signal();
2415cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He    }
2416cc27e117ed01c9a2b4def5a9c7a3103af83ee47eZhijun He
2417f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Submit request and block until ready for next one
241817a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
241917a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_BEGIN("camera3->process_capture_request");
2420f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
242117a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala    ATRACE_END();
242217a61adbd7cc1abe432deeffc11660daa74f6496Eino-Ville Talvala
2423f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (res != OK) {
2424b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2425f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                " device: %s (%d)", request.frame_number, strerror(-res), res);
2426f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        cleanUpFailedRequest(request, nextRequest, outputBuffers);
2427f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        return false;
2428f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2429f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
24301e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    // Update the latest request sent to HAL
24311e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    if (request.settings != NULL) { // Don't update them if they were unchanged
24321e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        Mutex::Autolock al(mLatestRequestMutex);
24331e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
24341e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        camera_metadata_t* cloned = clone_camera_metadata(request.settings);
24351e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin        mLatestRequest.acquire(cloned);
24361e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    }
24371e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
2438f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (request.settings != NULL) {
2439f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        nextRequest->mSettings.unlock(request.settings);
2440f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
24414d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
24424d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    // Remove any previously queued triggers (after unlock)
24434d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    res = removeTriggers(mPrevRequest);
24444d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    if (res != OK) {
2445b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        SET_ERR("RequestThread: Unable to remove triggers "
24464d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin              "(capture request %d, HAL device: %s (%d)",
24474d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin              request.frame_number, strerror(-res), res);
24484d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        return false;
24494d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
24504d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    mPrevTriggers = triggerCount;
24514d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2452f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return true;
2453f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2454f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
24551e479c0f4cb3e2174dde0b02e5656fb658f73495Igor MurashkinCameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
24561e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    Mutex::Autolock al(mLatestRequestMutex);
24571e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
24581e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    ALOGV("RequestThread::%s", __FUNCTION__);
24591e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
24601e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin    return mLatestRequest;
24611e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin}
24621e479c0f4cb3e2174dde0b02e5656fb658f73495Igor Murashkin
2463cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
2464f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalavoid Camera3Device::RequestThread::cleanUpFailedRequest(
2465f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        camera3_capture_request_t &request,
2466f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        sp<CaptureRequest> &nextRequest,
2467f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        Vector<camera3_stream_buffer_t> &outputBuffers) {
2468f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2469f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (request.settings != NULL) {
2470f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        nextRequest->mSettings.unlock(request.settings);
2471f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2472f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (request.input_buffer != NULL) {
2473f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
24745a269fa72b419e7fe4bf6bf9b27eec8782b3a963Igor Murashkin        nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
2475f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2476f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    for (size_t i = 0; i < request.num_output_buffers; i++) {
2477f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2478f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2479f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            outputBuffers[i], 0);
2480f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2481f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2482f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2483f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalasp<Camera3Device::CaptureRequest>
2484f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        Camera3Device::RequestThread::waitForNextRequest() {
2485f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
2486f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    sp<CaptureRequest> nextRequest;
2487f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2488f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Optimized a bit for the simple steady-state case (single repeating
2489f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // request), to avoid putting that request in the queue temporarily.
2490f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mRequestLock);
2491f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2492f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    while (mRequestQueue.empty()) {
2493f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (!mRepeatingRequests.empty()) {
2494f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // Always atomically enqueue all requests in a repeating request
2495f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // list. Guarantees a complete in-sequence set of captures to
2496f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // application.
2497f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            const RequestList &requests = mRepeatingRequests;
2498f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            RequestList::const_iterator firstRequest =
2499f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                    requests.begin();
2500f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            nextRequest = *firstRequest;
2501f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            mRequestQueue.insert(mRequestQueue.end(),
2502f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                    ++firstRequest,
2503f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                    requests.end());
2504f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // No need to wait any longer
2505cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
25062d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei            mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
2507cb0652e5a850b2fcd919e977247e87239efaf70eJianing Wei
2508f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            break;
2509f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
2510f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2511f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2512f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2513f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2514f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                exitPending()) {
2515f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            Mutex::Autolock pl(mPauseLock);
2516f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            if (mPaused == false) {
2517f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
2518f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                mPaused = true;
2519f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                // Let the tracker know
2520f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                sp<StatusTracker> statusTracker = mStatusTracker.promote();
2521f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                if (statusTracker != 0) {
2522f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2523f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                }
2524f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            }
2525f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            // Stop waiting for now and let thread management happen
2526f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return NULL;
2527f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
2528f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2529f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2530f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (nextRequest == NULL) {
2531f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // Don't have a repeating request already in hand, so queue
2532f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        // must have an entry now.
2533f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        RequestList::iterator firstRequest =
2534f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala                mRequestQueue.begin();
2535f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        nextRequest = *firstRequest;
2536f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mRequestQueue.erase(firstRequest);
2537f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2538f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
253926fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    // In case we've been unpaused by setPaused clearing mDoPause, need to
254026fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    // update internal pause state (capture/setRepeatingRequest unpause
254126fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    // directly).
2542f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock pl(mPauseLock);
2543f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    if (mPaused) {
2544f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2545f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
2546f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
2547f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentActive(mStatusId);
2548f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
2549f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
2550f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    mPaused = false;
2551f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2552f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // Check if we've reconfigured since last time, and reset the preview
2553f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // request if so. Can't use 'NULL request == repeat' across configure calls.
2554f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    if (mReconfigured) {
2555f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mPrevRequest.clear();
2556f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        mReconfigured = false;
2557f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2558f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
25592d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    if (nextRequest != NULL) {
25602d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei        nextRequest->mResultExtras.frameNumber = mFrameNumber++;
25612d6bb3f9e3e7cc1c7debbbe3d74bf9c70b6f39d4Jianing Wei    }
2562f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return nextRequest;
2563f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2564f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
2565f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvalabool Camera3Device::RequestThread::waitIfPaused() {
2566f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    status_t res;
2567f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    Mutex::Autolock l(mPauseLock);
2568f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    while (mDoPause) {
2569f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        if (mPaused == false) {
2570f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            mPaused = true;
2571f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2572f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            // Let the tracker know
2573f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2574f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            if (statusTracker != 0) {
2575f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2576f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            }
2577f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
2578f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
2579f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
2580f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (res == TIMED_OUT || exitPending()) {
2581f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala            return true;
2582f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala        }
2583f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    }
2584f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // We don't set mPaused to false here, because waitForNextRequest needs
2585f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    // to further manage the paused state in case of starvation.
2586f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala    return false;
2587f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala}
2588f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala
258926fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvalavoid Camera3Device::RequestThread::unpauseForNewRequests() {
259026fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    // With work to do, mark thread as unpaused.
259126fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    // If paused by request (setPaused), don't resume, to avoid
259226fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    // extra signaling/waiting overhead to waitUntilPaused
2593f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    mRequestSignal.signal();
259426fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    Mutex::Autolock p(mPauseLock);
259526fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    if (!mDoPause) {
2596f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2597f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (mPaused) {
2598f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            sp<StatusTracker> statusTracker = mStatusTracker.promote();
2599f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            if (statusTracker != 0) {
2600f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala                statusTracker->markComponentActive(mStatusId);
2601f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            }
2602f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
260326fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala        mPaused = false;
260426fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala    }
260526fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala}
260626fe6c7c56477ef227205c68f17df07ca3501d65Eino-Ville Talvala
2607b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvalavoid Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2608b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    sp<Camera3Device> parent = mParent.promote();
2609b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    if (parent != NULL) {
2610b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        va_list args;
2611b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        va_start(args, fmt);
2612b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
2613b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        parent->setErrorStateV(fmt, args);
2614b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
2615b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala        va_end(args);
2616b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala    }
2617b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala}
2618b2058d19297e508133a66b033d29380924b5d267Eino-Ville Talvala
26194d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkinstatus_t Camera3Device::RequestThread::insertTriggers(
26204d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        const sp<CaptureRequest> &request) {
26214d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26224d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    Mutex::Autolock al(mTriggerMutex);
26234d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2624741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh    sp<Camera3Device> parent = mParent.promote();
2625741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh    if (parent == NULL) {
2626741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        CLOGE("RequestThread: Parent is gone");
2627741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        return DEAD_OBJECT;
2628741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh    }
2629741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh
26304d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    CameraMetadata &metadata = request->mSettings;
26314d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    size_t count = mTriggerMap.size();
26324d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26334d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    for (size_t i = 0; i < count; ++i) {
26344d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        RequestTrigger trigger = mTriggerMap.valueAt(i);
26354d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        uint32_t tag = trigger.metadataTag;
2636741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh
2637741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
2638741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
2639741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
2640741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            isAeTrigger ? request->mResultExtras.precaptureTriggerId = triggerId :
2641741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh                          request->mResultExtras.afTriggerId = triggerId;
2642741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            if (parent->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2643741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh                continue; // Trigger ID tag is deprecated since device HAL 3.2
2644741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh            }
2645741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh        }
2646741ace8776f052245e33a47a0b99400f75996f45Yin-Chia Yeh
26474d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        camera_metadata_entry entry = metadata.find(tag);
26484d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26494d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        if (entry.count > 0) {
26504d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            /**
26514d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin             * Already has an entry for this trigger in the request.
26524d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin             * Rewrite it with our requested trigger value.
26534d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin             */
26544d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            RequestTrigger oldTrigger = trigger;
26554d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26564d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            oldTrigger.entryValue = entry.data.u8[0];
26574d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26584d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            mTriggerReplacedMap.add(tag, oldTrigger);
26594d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        } else {
26604d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            /**
26614d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin             * More typical, no trigger entry, so we just add it
26624d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin             */
26634d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            mTriggerRemovedMap.add(tag, trigger);
26644d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
26654d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26664d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        status_t res;
26674d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26684d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        switch (trigger.getTagType()) {
26694d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            case TYPE_BYTE: {
26704d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
26714d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                res = metadata.update(tag,
26724d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      &entryValue,
26734d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      /*count*/1);
26744d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                break;
26754d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            }
26764d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            case TYPE_INT32:
26774d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                res = metadata.update(tag,
26784d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      &trigger.entryValue,
26794d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      /*count*/1);
26804d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                break;
26814d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            default:
26824d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                ALOGE("%s: Type not supported: 0x%x",
26834d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                      __FUNCTION__,
26844d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                      trigger.getTagType());
26854d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                return INVALID_OPERATION;
26864d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
26874d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26884d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        if (res != OK) {
26894d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ALOGE("%s: Failed to update request metadata with trigger tag %s"
26904d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                  ", value %d", __FUNCTION__, trigger.getTagName(),
26914d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                  trigger.entryValue);
26924d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            return res;
26934d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
26944d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
26954d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
26964d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin              trigger.getTagName(),
26974d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin              trigger.entryValue);
26984d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
26994d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27004d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    mTriggerMap.clear();
27014d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27024d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return count;
27034d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin}
27044d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27054d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkinstatus_t Camera3Device::RequestThread::removeTriggers(
27064d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        const sp<CaptureRequest> &request) {
27074d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    Mutex::Autolock al(mTriggerMutex);
27084d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27094d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    CameraMetadata &metadata = request->mSettings;
27104d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27114d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    /**
27124d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     * Replace all old entries with their old values.
27134d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     */
27144d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
27154d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
27164d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27174d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        status_t res;
27184d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27194d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        uint32_t tag = trigger.metadataTag;
27204d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        switch (trigger.getTagType()) {
27214d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            case TYPE_BYTE: {
27224d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
27234d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                res = metadata.update(tag,
27244d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      &entryValue,
27254d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      /*count*/1);
27264d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                break;
27274d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            }
27284d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            case TYPE_INT32:
27294d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                res = metadata.update(tag,
27304d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      &trigger.entryValue,
27314d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                                      /*count*/1);
27324d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                break;
27334d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            default:
27344d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                ALOGE("%s: Type not supported: 0x%x",
27354d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                      __FUNCTION__,
27364d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                      trigger.getTagType());
27374d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                return INVALID_OPERATION;
27384d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
27394d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27404d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        if (res != OK) {
27414d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ALOGE("%s: Failed to restore request metadata with trigger tag %s"
27424d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                  ", trigger value %d", __FUNCTION__,
27434d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                  trigger.getTagName(), trigger.entryValue);
27444d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            return res;
27454d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
27464d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
27474d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    mTriggerReplacedMap.clear();
27484d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27494d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    /**
27504d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     * Remove all new entries.
27514d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin     */
27524d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
27534d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
27544d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        status_t res = metadata.erase(trigger.metadataTag);
27554d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27564d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        if (res != OK) {
27574d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            ALOGE("%s: Failed to erase metadata with trigger tag %s"
27584d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                  ", trigger value %d", __FUNCTION__,
27594d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin                  trigger.getTagName(), trigger.entryValue);
27604d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin            return res;
27614d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin        }
27624d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    }
27634d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    mTriggerRemovedMap.clear();
27644d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27654d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin    return OK;
27664d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin}
27674d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
27682f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvalastatus_t Camera3Device::RequestThread::addDummyTriggerIds(
27692f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        const sp<CaptureRequest> &request) {
27702f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
27712f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    static const int32_t dummyTriggerId = 1;
27722f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    status_t res;
27732f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala
27742f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    CameraMetadata &metadata = request->mSettings;
27752f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala
27762f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    // If AF trigger is active, insert a dummy AF trigger ID if none already
27772f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    // exists
27782f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
27792f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
27802f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    if (afTrigger.count > 0 &&
27812f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
27822f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            afId.count == 0) {
27832f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
27842f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        if (res != OK) return res;
27852f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    }
27862f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala
27872f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    // If AE precapture trigger is active, insert a dummy precapture trigger ID
27882f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    // if none already exists
27892f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    camera_metadata_entry pcTrigger =
27902f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
27912f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
27922f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    if (pcTrigger.count > 0 &&
27932f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
27942f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala            pcId.count == 0) {
27952f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
27962f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala                &dummyTriggerId, 1);
27972f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala        if (res != OK) return res;
27982f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    }
27992f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala
28002f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala    return OK;
28012f876f9ee63396e4e0117f85c5b3132cac7e2c9dEino-Ville Talvala}
28024d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
28034d2f2e8414df33337d4f09e5235719dfcc705674Igor Murashkin
2804f76e027c43f531fc6f9287838b5c332236a4338aEino-Ville Talvala/**
28057fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala * Static callback forwarding methods from HAL to instance
28067fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala */
28077fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
28087fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalavoid Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
28097fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        const camera3_capture_result *result) {
28107fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    Camera3Device *d =
28117fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
28127fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    d->processCaptureResult(result);
28137fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
28147fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
28157fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvalavoid Camera3Device::sNotify(const camera3_callback_ops *cb,
28167fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala        const camera3_notify_msg *msg) {
28177fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    Camera3Device *d =
28187fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
28197fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala    d->notify(msg);
28207fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}
28217fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala
28227fa43f376ebd63fda24d85c9ebf97e0ddf534083Eino-Ville Talvala}; // namespace android
2823