1734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen/*
2734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * Copyright (C) 2016 The Android Open Source Project
3734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen *
4734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * Licensed under the Apache License, Version 2.0 (the "License");
5734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * you may not use this file except in compliance with the License.
6734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * You may obtain a copy of the License at
7734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen *
8734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen *      http://www.apache.org/licenses/LICENSE-2.0
9734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen *
10734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * Unless required by applicable law or agreed to in writing, software
11734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * distributed under the License is distributed on an "AS IS" BASIS,
12734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * See the License for the specific language governing permissions and
14734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * limitations under the License.
15734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen */
16734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
17734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen// Modified from hardware/libhardware/modules/camera/Camera.cpp
18734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
19734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <cstdlib>
2024e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen#include <memory>
2124e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen#include <vector>
22734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <stdio.h>
23734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <hardware/camera3.h>
24734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <sync/sync.h>
25734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <system/camera_metadata.h>
26734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <system/graphics.h>
27734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <utils/Mutex.h>
28abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen
29abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen#include "metadata/metadata_common.h"
30734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
31734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen//#define LOG_NDEBUG 0
32734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#define LOG_TAG "Camera"
33734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <cutils/log.h>
34734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
35734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
36734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <utils/Trace.h>
37734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
383841a7f4951fe1498bf5ba88466def3ea18f8867Ari Hausman-Cohen#include "camera.h"
39734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
40734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
41734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
42734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohennamespace default_camera_hal {
43734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
44734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenextern "C" {
45734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen// Shim passed to the framework to close an opened device.
46734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int close_device(hw_device_t* dev)
47734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
48734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
49734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    Camera* cam = static_cast<Camera*>(cam_dev->priv);
50734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return cam->close();
51734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
52734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} // extern "C"
53734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
54734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-CohenCamera::Camera(int id)
55734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen  : mId(id),
56abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    mSettingsSet(false),
57734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mBusy(false),
58734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mCallbackOps(NULL),
590b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    mInFlightTracker(new RequestTracker)
60734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
61734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    memset(&mTemplates, 0, sizeof(mTemplates));
62734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    memset(&mDevice, 0, sizeof(mDevice));
63734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mDevice.common.tag    = HARDWARE_DEVICE_TAG;
64900c1e3a0c7eda1c630ff72414f061975a4e8379Ari Hausman-Cohen    mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
65734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mDevice.common.close  = close_device;
66734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mDevice.ops           = const_cast<camera3_device_ops_t*>(&sOps);
67734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mDevice.priv          = this;
68734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
69734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
70734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-CohenCamera::~Camera()
71734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
72734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
73734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
74345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohenint Camera::openDevice(const hw_module_t *module, hw_device_t **device)
75734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
76734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ALOGI("%s:%d: Opening camera device", __func__, mId);
77734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ATRACE_CALL();
78734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    android::Mutex::Autolock al(mDeviceLock);
79734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
80734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    if (mBusy) {
81734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
82734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return -EBUSY;
83734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
84734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
85345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen    int connectResult = connect();
86345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen    if (connectResult != 0) {
87345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen      return connectResult;
88345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen    }
89734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mBusy = true;
90734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mDevice.common.module = const_cast<hw_module_t*>(module);
91734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    *device = &mDevice.common;
92734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return 0;
93734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
94734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
95734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::getInfo(struct camera_info *info)
96734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
97734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    info->device_version = mDevice.common.version;
98734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    initDeviceInfo(info);
99e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    if (!mStaticInfo) {
100e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen        int res = loadStaticInfo();
101e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen        if (res) {
102e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen            return res;
103abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        }
104abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    }
105e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    info->static_camera_characteristics = mStaticInfo->raw_metadata();
106e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    info->facing = mStaticInfo->facing();
107e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    info->orientation = mStaticInfo->orientation();
108abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen
109734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return 0;
110734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
111734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
112e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohenint Camera::loadStaticInfo() {
113e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  // Using a lock here ensures |mStaticInfo| will only ever be set once,
114e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  // even in concurrent situations.
115e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  android::Mutex::Autolock al(mStaticInfoLock);
116e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen
117e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  if (mStaticInfo) {
118e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    return 0;
119e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  }
120e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen
121e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  std::unique_ptr<android::CameraMetadata> static_metadata =
122e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen      std::make_unique<android::CameraMetadata>();
123e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  int res = initStaticInfo(static_metadata.get());
124e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  if (res) {
125e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    ALOGE("%s:%d: Failed to get static info from device.",
126e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen          __func__, mId);
127e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    return res;
128e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  }
129e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen
130e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  mStaticInfo.reset(StaticProperties::NewStaticProperties(
131e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen      std::move(static_metadata)));
132e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  if (!mStaticInfo) {
133e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    ALOGE("%s:%d: Failed to initialize static properties from device metadata.",
134e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen          __func__, mId);
135e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen    return -ENODEV;
136e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  }
137e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen
138e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen  return 0;
139e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen}
140e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen
141734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::close()
142734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
143734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ALOGI("%s:%d: Closing camera device", __func__, mId);
144734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ATRACE_CALL();
145734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    android::Mutex::Autolock al(mDeviceLock);
146734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
147734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    if (!mBusy) {
148734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
149734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return -EINVAL;
150734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
151734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
152c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    flush();
1535acb400d18d40220df829193355736a0df782ab7Ari Hausman-Cohen    disconnect();
154734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mBusy = false;
155734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return 0;
156734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
157734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
158734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::initialize(const camera3_callback_ops_t *callback_ops)
159734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
160734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    int res;
161734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
162734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
163734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    mCallbackOps = callback_ops;
164734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    // per-device specific initialization
165734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    res = initDevice();
166734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    if (res != 0) {
167734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
168734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return res;
169734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
170734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return 0;
171734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
172734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
173734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::configureStreams(camera3_stream_configuration_t *stream_config)
174734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
175ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    android::Mutex::Autolock al(mDeviceLock);
176abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen
177734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
178734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ATRACE_CALL();
179734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
180ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Check that there are no in-flight requests.
181ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (!mInFlightTracker->Empty()) {
182ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Can't configure streams while frames are in flight.",
183ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen              __func__, mId);
184734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return -EINVAL;
185734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
186734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
187ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Verify the set of streams in aggregate, and perform configuration if valid.
188ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    int res = validateStreamConfiguration(stream_config);
18972fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    if (res) {
190ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Failed to validate stream set", __func__, mId);
191ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    } else {
192ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // Set up all streams. Since they've been validated,
193ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // this should only result in fatal (-ENODEV) errors.
194ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // This occurs after validation to ensure that if there
195ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // is a non-fatal error, the stream configuration doesn't change states.
196ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        res = setupStreams(stream_config);
197ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        if (res) {
198ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen            ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
199ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        }
20072fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    }
201734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
202ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Set trackers based on result.
20372fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    if (!res) {
204ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // Success, set up the in-flight trackers for the new streams.
205ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        mInFlightTracker->SetStreamConfiguration(*stream_config);
206ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // Must provide new settings for the new configuration.
207ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        mSettingsSet = false;
2080b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    } else if (res != -EINVAL) {
209ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // Fatal error, the old configuration is invalid.
2100b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen        mInFlightTracker->ClearStreamConfiguration();
21172fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    }
212ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // On a non-fatal error the old configuration, if any, remains valid.
21372fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    return res;
214734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
215734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
216ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohenint Camera::validateStreamConfiguration(
217ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    const camera3_stream_configuration_t* stream_config)
218734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
219ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Check that the configuration is well-formed.
220ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (stream_config == nullptr) {
221ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
222ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        return -EINVAL;
223ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    } else if (stream_config->num_streams == 0) {
224ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
225ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        return -EINVAL;
226ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    } else if (stream_config->streams == nullptr) {
227734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
228ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        return -EINVAL;
229734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
23072fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen
231ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Check that the configuration is supported.
232ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Make sure static info has been initialized before trying to use it.
233ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (!mStaticInfo) {
234ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        int res = loadStaticInfo();
23572fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen        if (res) {
236ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen            return res;
23772fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen        }
238734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
239ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (!mStaticInfo->StreamConfigurationSupported(stream_config)) {
240ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Stream configuration does not match static "
241ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen              "metadata restrictions.", __func__, mId);
242ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        return -EINVAL;
243ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    }
244ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen
245ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Dataspace support is poorly documented - unclear if the expectation
246ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // is that a device supports ALL dataspaces that could match a given
247ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // format. For now, defer to child class implementation.
248ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Rotation support isn't described by metadata, so must defer to device.
249ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (!validateDataspacesAndRotations(stream_config)) {
250ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Device can not handle configuration "
251ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen              "dataspaces or rotations.", __func__, mId);
252ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        return -EINVAL;
253ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    }
254ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen
25572fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    return 0;
256734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
257734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
258734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenbool Camera::isValidTemplateType(int type)
259734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
260900c1e3a0c7eda1c630ff72414f061975a4e8379Ari Hausman-Cohen    return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
261734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
262734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
263734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenconst camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
264734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
265734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ALOGV("%s:%d: type=%d", __func__, mId, type);
266734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
267734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    if (!isValidTemplateType(type)) {
268734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
269734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return NULL;
270734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
271499258437667b7aaaf31d27c1dbe0bfa0281c75dAri Hausman-Cohen
272abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    if (!mTemplates[type]) {
273e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen        // Check if the device has the necessary features
274e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen        // for the requested template. If not, don't bother.
275e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen        if (!mStaticInfo->TemplateSupported(type)) {
276e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen            ALOGW("%s:%d: Camera does not support template type %d",
277e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen                  __func__, mId, type);
278e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen            return NULL;
279e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen        }
280e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen
281abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        // Initialize this template if it hasn't been initialized yet.
282abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        std::unique_ptr<android::CameraMetadata> new_template =
283abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen            std::make_unique<android::CameraMetadata>();
284abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        int res = initTemplate(type, new_template.get());
285abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        if (res || !new_template) {
286abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen            ALOGE("%s:%d: Failed to generate template of type: %d",
287abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen                  __func__, mId, type);
288abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen            return NULL;
289abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        }
290abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        mTemplates[type] = std::move(new_template);
291abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    }
292abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen
293abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    // The "locking" here only causes non-const methods to fail,
294abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    // which is not a problem since the CameraMetadata being locked
295abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    // is already const. Destructing automatically "unlocks".
296abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen    return mTemplates[type]->getAndLock();
297734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
298734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
2992738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohenint Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
300734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
30124e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen    int res;
302c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // TODO(b/32917568): A capture request submitted or ongoing during a flush
303c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // should be returned with an error; for now they are mutually exclusive.
304c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    android::Mutex::Autolock al(mFlushLock);
305734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
306734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ATRACE_CALL();
307734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
3082738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    if (temp_request == NULL) {
309734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: NULL request recieved", __func__, mId);
310734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return -EINVAL;
311734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
312734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
3132738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Make a persistent copy of request, since otherwise it won't live
3142738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // past the end of this method.
3152738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
316734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
317ad6fe2b033997ab0401b0a519b18cea6e957dac0Ari Hausman-Cohen    ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
3182738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen
319ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (!mInFlightTracker->CanAddRequest(*request)) {
320ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        // Streams are full or frame number is not unique.
321ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Can not add request.", __func__, mId);
322ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        return -EINVAL;
323ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    }
324ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen
3252738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Null/Empty indicates use last settings
3262738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    if (request->settings.isEmpty() && !mSettingsSet) {
3272738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        ALOGE("%s:%d: NULL settings without previous set Frame:%d",
3282738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen              __func__, mId, request->frame_number);
329abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen        return -EINVAL;
330734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
331734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
332734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    if (request->input_buffer != NULL) {
333734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
3342738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen              request->input_buffer.get());
335734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    } else {
336734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGV("%s:%d: Capturing new frame.", __func__, mId);
3372738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    }
338734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
339ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    if (!isValidRequestSettings(request->settings)) {
340ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen        ALOGE("%s:%d: Invalid request settings.", __func__, mId);
3412738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        return -EINVAL;
342734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
343734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
3442738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Pre-process output buffers.
3452738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    if (request->output_buffers.size() <= 0) {
346734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
3472738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen              request->output_buffers.size());
348734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return -EINVAL;
349734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
3502738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    for (auto& output_buffer : request->output_buffers) {
3512738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        res = preprocessCaptureBuffer(&output_buffer);
352734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        if (res)
35324e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen            return -ENODEV;
35424e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen    }
355734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
3560b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    // Add the request to tracking.
3570b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    if (!mInFlightTracker->Add(request)) {
3580b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen        ALOGE("%s:%d: Failed to track request for frame %d.",
3590b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen              __func__, mId, request->frame_number);
3600b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen        return -ENODEV;
3610b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    }
3620b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen
363ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // Valid settings have been provided (mSettingsSet is a misnomer;
364ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // all that matters is that a previous request with valid settings
365ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    // has been passed to the device, not that they've been set).
366ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen    mSettingsSet = true;
367ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen
3682738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Send the request off to the device for completion.
3692738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    enqueueRequest(request);
370734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
3712738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Request is now in flight. The device will call completeRequest
3722738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // asynchronously when it is done filling buffers and metadata.
373734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return 0;
374734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
375734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
3762738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohenvoid Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
377734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
3780b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    if (!mInFlightTracker->Remove(request)) {
379c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen        ALOGE("%s:%d: Completed request %p is not being tracked. "
380c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen              "It may have been cleared out during a flush.",
3810b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen              __func__, mId, request.get());
3822738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        return;
3832738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    }
3842738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen
3850b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    // Since |request| has been removed from the tracking, this method
3860b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    // MUST call sendResult (can still return a result in an error state, e.g.
3870b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    // through completeRequestWithError) so the frame doesn't get lost.
3880b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen
3890b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    if (err) {
3900b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen      ALOGE("%s:%d: Error completing request for frame %d.",
3910b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen            __func__, mId, request->frame_number);
3920b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen      completeRequestWithError(request);
3930b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen      return;
3940b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen    }
3950b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen
3962738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Notify the framework with the shutter time (extracted from the result).
3972738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    int64_t timestamp = 0;
3982738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // TODO(b/31360070): The general metadata methods should be part of the
3992738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // default_camera_hal namespace, not the v4l2_camera_hal namespace.
4002738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    int res = v4l2_camera_hal::SingleTagValue(
4012738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
4022738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    if (res) {
4032738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        ALOGE("%s:%d: Request for frame %d is missing required metadata.",
4042738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen              __func__, mId, request->frame_number);
405fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        // TODO(b/31653322): Send RESULT error.
406fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        // For now sending REQUEST error instead.
407fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        completeRequestWithError(request);
4082738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        return;
4092738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    }
4102738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    notifyShutter(request->frame_number, timestamp);
4112738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen
4122738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // TODO(b/31653322): Check all returned buffers for errors
4132738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // (if any, send BUFFER error).
4142738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen
415fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    sendResult(request);
416734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
417734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
418c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohenint Camera::flush()
419c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen{
420c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    ALOGV("%s:%d: Flushing.", __func__, mId);
421c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // TODO(b/32917568): Synchronization. Behave "appropriately"
422c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // (i.e. according to camera3.h) if process_capture_request()
423c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // is called concurrently with this (in either order).
424c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // Since the callback to completeRequest also may happen on a separate
425c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // thread, this function should behave nicely concurrently with that too.
426c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    android::Mutex::Autolock al(mFlushLock);
427c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen
428c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    std::set<std::shared_ptr<CaptureRequest>> requests;
429c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    mInFlightTracker->Clear(&requests);
430c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    for (auto& request : requests) {
431c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen        // TODO(b/31653322): See camera3.h. Should return different error
432c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen        // depending on status of the request.
433c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen        completeRequestWithError(request);
434c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    }
435c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen
436c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size());
437c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen
438c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    // Call down into the device flushing.
439c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    return flushBuffers();
440c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen}
441c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen
4422738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohenint Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
443734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
44424e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen    int res;
4452738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // TODO(b/29334616): This probably should be non-blocking; part
4462738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // of the asynchronous request processing.
4472738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    if (buffer->acquire_fence != -1) {
4482738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen        res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
449734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        if (res == -ETIME) {
450734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen            ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
451734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen                    __func__, mId);
452734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen            return res;
453734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        } else if (res) {
454734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen            ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
455734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen                    __func__, mId, strerror(-res), res);
456734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen            return res;
457734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        }
458eadafff6aeee592ba373c1465f5d8feac3ef9d48Eric Jeong        ::close(buffer->acquire_fence);
459734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
460734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
4612738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // Acquire fence has been waited upon.
4622738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    buffer->acquire_fence = -1;
4632738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    // No release fence waiting unless the device sets it.
4642738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    buffer->release_fence = -1;
46524e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen
4662738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen    buffer->status = CAMERA3_BUFFER_STATUS_OK;
467734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return 0;
468734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
469734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
470734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenvoid Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
471734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
472fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    camera3_notify_msg_t message;
473fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    memset(&message, 0, sizeof(message));
474fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.type = CAMERA3_MSG_SHUTTER;
475fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.message.shutter.frame_number = frame_number;
476fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.message.shutter.timestamp = timestamp;
477fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    mCallbackOps->notify(mCallbackOps, &message);
478fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen}
479fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen
480fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohenvoid Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
481fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen{
482fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    // Send an error notification.
483fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    camera3_notify_msg_t message;
484fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    memset(&message, 0, sizeof(message));
485fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.type = CAMERA3_MSG_ERROR;
486fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.message.error.frame_number = request->frame_number;
487fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.message.error.error_stream = nullptr;
488fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
489fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    mCallbackOps->notify(mCallbackOps, &message);
490fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen
491fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    // TODO(b/31856611): Ensure all the buffers indicate their error status.
492fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen
493fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    // Send the errored out result.
494fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    sendResult(request);
495fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen}
496fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen
497fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohenvoid Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
498fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    // Fill in the result struct
499fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    // (it only needs to live until the end of the framework callback).
500fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    camera3_capture_result_t result {
501fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        request->frame_number,
502fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        request->settings.getAndLock(),
5039df082e93368ae2cc86e706f1f106a4422df1e42Dmitry Shmidt        static_cast<uint32_t>(request->output_buffers.size()),
504fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        request->output_buffers.data(),
505fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        request->input_buffer.get(),
506fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen        1  // Total result; only 1 part.
507fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    };
508fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    // Make the framework callback.
509fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen    mCallbackOps->process_capture_result(mCallbackOps, &result);
510734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
511734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
512734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenvoid Camera::dump(int fd)
513734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
514734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
515734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    ATRACE_CALL();
516734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    android::Mutex::Autolock al(mDeviceLock);
517734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
518734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
519734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
520734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    // TODO: dump all settings
521734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
522734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
523734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenconst char* Camera::templateToString(int type)
524734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
525734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    switch (type) {
526734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    case CAMERA3_TEMPLATE_PREVIEW:
527734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return "CAMERA3_TEMPLATE_PREVIEW";
528734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    case CAMERA3_TEMPLATE_STILL_CAPTURE:
529734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return "CAMERA3_TEMPLATE_STILL_CAPTURE";
530734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    case CAMERA3_TEMPLATE_VIDEO_RECORD:
531734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return "CAMERA3_TEMPLATE_VIDEO_RECORD";
532734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
533734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
534734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
535734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
536734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    }
537734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    // TODO: support vendor templates
538734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return "Invalid template type!";
539734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
540734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
541734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenextern "C" {
542734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen// Get handle to camera from device priv data
543734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic Camera *camdev_to_camera(const camera3_device_t *dev)
544734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
545734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return reinterpret_cast<Camera*>(dev->priv);
546734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
547734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
548734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int initialize(const camera3_device_t *dev,
549734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        const camera3_callback_ops_t *callback_ops)
550734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
551734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return camdev_to_camera(dev)->initialize(callback_ops);
552734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
553734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
554734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int configure_streams(const camera3_device_t *dev,
555734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        camera3_stream_configuration_t *stream_list)
556734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
557734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return camdev_to_camera(dev)->configureStreams(stream_list);
558734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
559734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
560734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic const camera_metadata_t *construct_default_request_settings(
561734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        const camera3_device_t *dev, int type)
562734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
563734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
564734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
565734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
566734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int process_capture_request(const camera3_device_t *dev,
567734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        camera3_capture_request_t *request)
568734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
569734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    return camdev_to_camera(dev)->processCaptureRequest(request);
570734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
571734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
572734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic void dump(const camera3_device_t *dev, int fd)
573734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
574734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    camdev_to_camera(dev)->dump(fd);
575734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
576734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
577c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohenstatic int flush(const camera3_device_t *dev)
578734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{
579c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen    return camdev_to_camera(dev)->flush();
580734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}
581734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
582734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} // extern "C"
583734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
584734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenconst camera3_device_ops_t Camera::sOps = {
585734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .initialize = default_camera_hal::initialize,
586734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .configure_streams = default_camera_hal::configure_streams,
587900c1e3a0c7eda1c630ff72414f061975a4e8379Ari Hausman-Cohen    .register_stream_buffers = nullptr,
588734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .construct_default_request_settings
589734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen        = default_camera_hal::construct_default_request_settings,
590734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .process_capture_request = default_camera_hal::process_capture_request,
59172fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen    .get_metadata_vendor_tag_ops = nullptr,
592734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .dump = default_camera_hal::dump,
593734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .flush = default_camera_hal::flush,
594734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen    .reserved = {0},
595734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen};
596734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen
5973841a7f4951fe1498bf5ba88466def3ea18f8867Ari Hausman-Cohen}  // namespace default_camera_hal
598