1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_CameraDeviceSession"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "camera_device_session.h"
21
22 #include <dlfcn.h>
23 #include <inttypes.h>
24 #include <log/log.h>
25 #include <sys/stat.h>
26 #include <utils/Trace.h>
27
28 #include "basic_capture_session.h"
29 #include "dual_ir_capture_session.h"
30 #include "hal_utils.h"
31 #include "hdrplus_capture_session.h"
32 #include "rgbird_capture_session.h"
33 #include "vendor_tag_defs.h"
34 #include "vendor_tag_types.h"
35 #include "vendor_tags.h"
36
37 namespace android {
38 namespace google_camera_hal {
39
40 std::vector<CaptureSessionEntryFuncs>
41 CameraDeviceSession::kCaptureSessionEntries = {
42 {.IsStreamConfigurationSupported =
43 HdrplusCaptureSession::IsStreamConfigurationSupported,
44 .CreateSession = HdrplusCaptureSession::Create},
45 {.IsStreamConfigurationSupported =
46 RgbirdCaptureSession::IsStreamConfigurationSupported,
47 .CreateSession = RgbirdCaptureSession::Create},
48 {.IsStreamConfigurationSupported =
49 DualIrCaptureSession::IsStreamConfigurationSupported,
50 .CreateSession = DualIrCaptureSession::Create},
51 // BasicCaptureSession is supposed to be the last resort.
52 {.IsStreamConfigurationSupported =
53 BasicCaptureSession::IsStreamConfigurationSupported,
54 .CreateSession = BasicCaptureSession::Create}};
55
56 // HAL external capture session library path
57 #if defined(_LP64)
58 constexpr char kExternalCaptureSessionDir[] =
59 "/vendor/lib64/camera/capture_sessions/";
60 #else // defined(_LP64)
61 constexpr char kExternalCaptureSessionDir[] =
62 "/vendor/lib/camera/capture_sessions/";
63 #endif
64
Create(std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,CameraBufferAllocatorHwl * camera_allocator_hwl)65 std::unique_ptr<CameraDeviceSession> CameraDeviceSession::Create(
66 std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,
67 CameraBufferAllocatorHwl* camera_allocator_hwl) {
68 ATRACE_CALL();
69 if (device_session_hwl == nullptr) {
70 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
71 return nullptr;
72 }
73
74 uint32_t camera_id = device_session_hwl->GetCameraId();
75 std::vector<uint32_t> physical_camera_ids =
76 device_session_hwl->GetPhysicalCameraIds();
77
78 auto session =
79 std::unique_ptr<CameraDeviceSession>(new CameraDeviceSession());
80 if (session == nullptr) {
81 ALOGE("%s: Creating CameraDeviceSession failed.", __FUNCTION__);
82 return nullptr;
83 }
84
85 status_t res =
86 session->Initialize(std::move(device_session_hwl), camera_allocator_hwl);
87 if (res != OK) {
88 ALOGE("%s: Initializing CameraDeviceSession failed: %s (%d).", __FUNCTION__,
89 strerror(-res), res);
90 return nullptr;
91 }
92
93 // Construct a string of physical camera IDs.
94 std::string physical_camera_ids_string;
95 if (physical_camera_ids.size() > 0) {
96 physical_camera_ids_string += ": ";
97
98 for (auto& id : physical_camera_ids) {
99 physical_camera_ids_string += std::to_string(id) + " ";
100 }
101 }
102
103 ALOGI(
104 "%s: Created a device session for camera %d with %zu physical cameras%s",
105 __FUNCTION__, camera_id, physical_camera_ids.size(),
106 physical_camera_ids_string.c_str());
107
108 return session;
109 }
110
UpdatePendingRequest(CaptureResult * result)111 status_t CameraDeviceSession::UpdatePendingRequest(CaptureResult* result) {
112 std::lock_guard<std::mutex> lock(request_record_lock_);
113 if (result == nullptr) {
114 ALOGE("%s: result is nullptr.", __FUNCTION__);
115 return BAD_VALUE;
116 }
117
118 if (result->output_buffers.empty()) {
119 // Nothing to do if the result doesn't contain any output buffers.
120 return OK;
121 }
122
123 // Update inflight request records and notify SBC for flushing if needed
124 uint32_t frame_number = result->frame_number;
125 if (pending_request_streams_.find(frame_number) ==
126 pending_request_streams_.end()) {
127 ALOGE("%s: Can't find frame %u in result holder.", __FUNCTION__,
128 frame_number);
129 return UNKNOWN_ERROR;
130 }
131
132 // Remove streams from pending request streams for buffers in the result.
133 auto& streams = pending_request_streams_.at(frame_number);
134 for (auto& stream_buffer : result->output_buffers) {
135 int32_t stream_id = stream_buffer.stream_id;
136 if (streams.find(stream_id) == streams.end()) {
137 ALOGE(
138 "%s: Can't find stream %d in frame %u result holder. It may"
139 " have been returned or have not been requested.",
140 __FUNCTION__, stream_id, frame_number);
141 // Ignore this buffer and continue handling other buffers in the
142 // result.
143 } else {
144 streams.erase(stream_id);
145 }
146 }
147
148 if (streams.empty()) {
149 pending_request_streams_.erase(frame_number);
150 }
151
152 if (pending_request_streams_.empty()) {
153 status_t res = stream_buffer_cache_manager_->NotifyFlushingAll();
154 if (res != OK) {
155 ALOGE("%s: Failed to notify SBC manager to flush all streams.",
156 __FUNCTION__);
157 }
158 ALOGI(
159 "%s: [sbc] All inflight requests/streams cleared. Notified SBC for "
160 "flushing.",
161 __FUNCTION__);
162 }
163 return OK;
164 }
165
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)166 void CameraDeviceSession::ProcessCaptureResult(
167 std::unique_ptr<CaptureResult> result) {
168 if (result == nullptr) {
169 ALOGE("%s: result is nullptr", __FUNCTION__);
170 return;
171 }
172 zoom_ratio_mapper_.UpdateCaptureResult(result.get());
173
174 // If buffer management is not supported, simply send the result to the client.
175 if (!buffer_management_supported_) {
176 std::shared_lock lock(session_callback_lock_);
177 session_callback_.process_capture_result(std::move(result));
178 return;
179 }
180
181 status_t res = UpdatePendingRequest(result.get());
182 if (res != OK) {
183 ALOGE("%s: Updating inflight requests/streams failed.", __FUNCTION__);
184 }
185
186 for (auto& stream_buffer : result->output_buffers) {
187 ALOGV("%s: [sbc] <= Return result buf[%p], bid[%" PRIu64
188 "], strm[%d], frm[%u]",
189 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
190 stream_buffer.stream_id, result->frame_number);
191 }
192
193 // If there is dummy buffer or a dummy buffer has been observed of this frame,
194 // handle the capture result specifically.
195 bool result_handled = false;
196 res = TryHandleDummyResult(result.get(), &result_handled);
197 if (res != OK) {
198 ALOGE("%s: Failed to handle dummy result.", __FUNCTION__);
199 return;
200 }
201 if (result_handled == true) {
202 return;
203 }
204
205 // Update pending request tracker with returned buffers.
206 std::vector<StreamBuffer> buffers;
207 buffers.insert(buffers.end(), result->output_buffers.begin(),
208 result->output_buffers.end());
209
210 if (result->result_metadata) {
211 std::lock_guard<std::mutex> lock(request_record_lock_);
212 pending_results_.erase(result->frame_number);
213 }
214
215 {
216 std::shared_lock lock(session_callback_lock_);
217 session_callback_.process_capture_result(std::move(result));
218 }
219
220 if (!buffers.empty()) {
221 if (pending_requests_tracker_->TrackReturnedAcquiredBuffers(buffers) != OK) {
222 ALOGE("%s: Tracking requested acquired buffers failed", __FUNCTION__);
223 }
224 if (pending_requests_tracker_->TrackReturnedResultBuffers(buffers) != OK) {
225 ALOGE("%s: Tracking requested quota buffers failed", __FUNCTION__);
226 }
227 }
228 }
229
Notify(const NotifyMessage & result)230 void CameraDeviceSession::Notify(const NotifyMessage& result) {
231 if (buffer_management_supported_) {
232 uint32_t frame_number = 0;
233 if (result.type == MessageType::kError) {
234 frame_number = result.message.error.frame_number;
235 } else if (result.type == MessageType::kShutter) {
236 frame_number = result.message.shutter.frame_number;
237 }
238 std::lock_guard<std::mutex> lock(request_record_lock_);
239 // Strip out results for frame number that has been notified as ERROR_REQUEST
240 if (error_notified_requests_.find(frame_number) !=
241 error_notified_requests_.end()) {
242 return;
243 }
244
245 if (result.type == MessageType::kError &&
246 result.message.error.error_code == ErrorCode::kErrorResult) {
247 pending_results_.erase(frame_number);
248 }
249 }
250
251 if (ATRACE_ENABLED() && result.type == MessageType::kShutter) {
252 int64_t timestamp_ns_diff = 0;
253 int64_t current_timestamp_ns = result.message.shutter.timestamp_ns;
254 if (last_timestamp_ns_for_trace_ != 0) {
255 timestamp_ns_diff = current_timestamp_ns - last_timestamp_ns_for_trace_;
256 }
257
258 last_timestamp_ns_for_trace_ = current_timestamp_ns;
259
260 ATRACE_INT64("sensor_timestamp_diff", timestamp_ns_diff);
261 ATRACE_INT("timestamp_frame_number", result.message.shutter.frame_number);
262 }
263
264 std::shared_lock lock(session_callback_lock_);
265 session_callback_.notify(result);
266 }
267
InitializeBufferMapper()268 status_t CameraDeviceSession::InitializeBufferMapper() {
269 buffer_mapper_v4_ =
270 android::hardware::graphics::mapper::V4_0::IMapper::getService();
271 if (buffer_mapper_v4_ != nullptr) {
272 return OK;
273 }
274
275 buffer_mapper_v3_ =
276 android::hardware::graphics::mapper::V3_0::IMapper::getService();
277 if (buffer_mapper_v3_ != nullptr) {
278 return OK;
279 }
280
281 buffer_mapper_v2_ =
282 android::hardware::graphics::mapper::V2_0::IMapper::getService();
283 if (buffer_mapper_v2_ != nullptr) {
284 return OK;
285 }
286
287 ALOGE("%s: Getting buffer mapper failed.", __FUNCTION__);
288 return UNKNOWN_ERROR;
289 }
290
InitializeCallbacks()291 void CameraDeviceSession::InitializeCallbacks() {
292 std::lock_guard lock(session_callback_lock_);
293
294 // Initialize callback to
295 session_callback_.process_capture_result =
296 ProcessCaptureResultFunc([](std::unique_ptr<CaptureResult> /*result*/) {
297 ALOGW("%s: No session callback was set.", __FUNCTION__);
298 });
299
300 session_callback_.notify = NotifyFunc([](const NotifyMessage& /*message*/) {
301 ALOGW("%s: No session callback was set.", __FUNCTION__);
302 });
303
304 session_callback_.request_stream_buffers = RequestStreamBuffersFunc(
305 [](const std::vector<BufferRequest>& /*hal_buffer_requests*/,
306 std::vector<BufferReturn>* /*hal_buffer_returns*/) {
307 ALOGW("%s: No session callback was set.", __FUNCTION__);
308 return google_camera_hal::BufferRequestStatus::kFailedUnknown;
309 });
310
311 session_callback_.return_stream_buffers = ReturnStreamBuffersFunc(
312 [](const std::vector<StreamBuffer>& /*return_hal_buffers*/) {
313 ALOGW("%s: No session callback was set.", __FUNCTION__);
314 return google_camera_hal::BufferRequestStatus::kFailedUnknown;
315 });
316
317 camera_device_session_callback_.process_capture_result =
318 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
319 ProcessCaptureResult(std::move(result));
320 });
321
322 camera_device_session_callback_.notify =
323 NotifyFunc([this](const NotifyMessage& result) { Notify(result); });
324
325 hwl_session_callback_.request_stream_buffers = HwlRequestBuffersFunc(
326 [this](int32_t stream_id, uint32_t num_buffers,
327 std::vector<StreamBuffer>* buffers, uint32_t frame_number) {
328 return RequestBuffersFromStreamBufferCacheManager(
329 stream_id, num_buffers, buffers, frame_number);
330 });
331
332 hwl_session_callback_.return_stream_buffers =
333 HwlReturnBuffersFunc([this](const std::vector<StreamBuffer>& buffers) {
334 return ReturnStreamBuffers(buffers);
335 });
336
337 device_session_hwl_->SetSessionCallback(hwl_session_callback_);
338 }
339
InitializeBufferManagement(HalCameraMetadata * characteristics)340 status_t CameraDeviceSession::InitializeBufferManagement(
341 HalCameraMetadata* characteristics) {
342 ATRACE_CALL();
343
344 if (characteristics == nullptr) {
345 ALOGE("%s: characteristics cannot be nullptr.", __FUNCTION__);
346 return BAD_VALUE;
347 }
348
349 camera_metadata_ro_entry entry = {};
350 status_t res = characteristics->Get(
351 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
352 if (res == OK && entry.count > 0) {
353 buffer_management_supported_ =
354 (entry.data.u8[0] >=
355 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
356 }
357
358 return OK;
359 }
360
Initialize(std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,CameraBufferAllocatorHwl * camera_allocator_hwl)361 status_t CameraDeviceSession::Initialize(
362 std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,
363 CameraBufferAllocatorHwl* camera_allocator_hwl) {
364 ATRACE_CALL();
365 if (device_session_hwl == nullptr) {
366 ALOGE("%s: device_session_hwl cannot be nullptr.", __FUNCTION__);
367 return BAD_VALUE;
368 }
369
370 camera_id_ = device_session_hwl->GetCameraId();
371 device_session_hwl_ = std::move(device_session_hwl);
372 camera_allocator_hwl_ = camera_allocator_hwl;
373
374 status_t res = InitializeBufferMapper();
375 if (res != OK) {
376 ALOGE("%s: Initialize buffer mapper failed: %s(%d)", __FUNCTION__,
377 strerror(-res), res);
378 return res;
379 }
380
381 InitializeCallbacks();
382
383 std::unique_ptr<google_camera_hal::HalCameraMetadata> characteristics;
384 res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
385 if (res != OK) {
386 ALOGE("%s: Get camera characteristics failed: %s(%d)", __FUNCTION__,
387 strerror(-res), res);
388 return res;
389 }
390
391 res = InitializeBufferManagement(characteristics.get());
392 if (res != OK) {
393 ALOGE("%s: Initialize buffer management failed: %s(%d)", __FUNCTION__,
394 strerror(-res), res);
395 return res;
396 }
397
398 res = LoadExternalCaptureSession();
399 if (res != OK) {
400 ALOGE("%s: Loading external capture sessions failed: %s(%d)", __FUNCTION__,
401 strerror(-res), res);
402 return res;
403 }
404
405 InitializeZoomRatioMapper(characteristics.get());
406
407 return OK;
408 }
409
InitializeZoomRatioMapper(HalCameraMetadata * characteristics)410 void CameraDeviceSession::InitializeZoomRatioMapper(
411 HalCameraMetadata* characteristics) {
412 if (characteristics == nullptr) {
413 ALOGE("%s: characteristics cannot be nullptr.", __FUNCTION__);
414 return;
415 }
416
417 Rect active_array_size;
418 status_t res =
419 utils::GetSensorActiveArraySize(characteristics, &active_array_size);
420 if (res != OK) {
421 ALOGE("%s: Failed to get the active array size: %s(%d)", __FUNCTION__,
422 strerror(-res), res);
423 return;
424 }
425
426 ZoomRatioMapper::InitParams params;
427 params.active_array_dimension = {
428 active_array_size.right - active_array_size.left + 1,
429 active_array_size.bottom - active_array_size.top + 1};
430
431 std::vector<uint32_t> physical_camera_ids =
432 device_session_hwl_->GetPhysicalCameraIds();
433 for (uint32_t id : physical_camera_ids) {
434 std::unique_ptr<google_camera_hal::HalCameraMetadata>
435 physical_cam_characteristics;
436 res = device_session_hwl_->GetPhysicalCameraCharacteristics(
437 id, &physical_cam_characteristics);
438 if (res != OK) {
439 ALOGE("%s: Get camera: %u characteristics failed: %s(%d)", __FUNCTION__,
440 id, strerror(-res), res);
441 return;
442 }
443
444 res = utils::GetSensorActiveArraySize(physical_cam_characteristics.get(),
445 &active_array_size);
446 if (res != OK) {
447 ALOGE("%s: Failed to get cam: %u, active array size: %s(%d)",
448 __FUNCTION__, id, strerror(-res), res);
449 return;
450 }
451 Dimension active_array_dimension = {
452 active_array_size.right - active_array_size.left + 1,
453 active_array_size.bottom - active_array_size.top + 1};
454 params.physical_cam_active_array_dimension.emplace(id,
455 active_array_dimension);
456 }
457
458 res = utils::GetZoomRatioRange(characteristics, ¶ms.zoom_ratio_range);
459 if (res != OK) {
460 ALOGW("%s: Failed to get the zoom ratio range: %s(%d)", __FUNCTION__,
461 strerror(-res), res);
462 return;
463 }
464
465 params.zoom_ratio_mapper_hwl = device_session_hwl_->GetZoomRatioMapperHwl();
466
467 zoom_ratio_mapper_.Initialize(¶ms);
468 }
469
470 // Returns an array of regular files under dir_path.
FindLibraryPaths(const char * dir_path)471 static std::vector<std::string> FindLibraryPaths(const char* dir_path) {
472 std::vector<std::string> libs;
473
474 errno = 0;
475 DIR* dir = opendir(dir_path);
476 if (!dir) {
477 ALOGD("%s: Unable to open directory %s (%s)", __FUNCTION__, dir_path,
478 strerror(errno));
479 return libs;
480 }
481
482 struct dirent* entry = nullptr;
483 while ((entry = readdir(dir)) != nullptr) {
484 std::string lib_path(dir_path);
485 lib_path += entry->d_name;
486 struct stat st;
487 if (stat(lib_path.c_str(), &st) == 0) {
488 if (S_ISREG(st.st_mode)) {
489 libs.push_back(lib_path);
490 }
491 }
492 }
493
494 return libs;
495 }
496
LoadExternalCaptureSession()497 status_t CameraDeviceSession::LoadExternalCaptureSession() {
498 ATRACE_CALL();
499
500 if (external_capture_session_entries_.size() > 0) {
501 ALOGI("%s: External capture session libraries already loaded; skip.",
502 __FUNCTION__);
503 return OK;
504 }
505
506 for (const auto& lib_path : FindLibraryPaths(kExternalCaptureSessionDir)) {
507 ALOGI("%s: Loading %s", __FUNCTION__, lib_path.c_str());
508 void* lib_handle = nullptr;
509 lib_handle = dlopen(lib_path.c_str(), RTLD_NOW);
510 if (lib_handle == nullptr) {
511 ALOGW("Failed loading %s.", lib_path.c_str());
512 continue;
513 }
514
515 GetCaptureSessionFactoryFunc external_session_factory_t =
516 reinterpret_cast<GetCaptureSessionFactoryFunc>(
517 dlsym(lib_handle, "GetCaptureSessionFactory"));
518 if (external_session_factory_t == nullptr) {
519 ALOGE("%s: dlsym failed (%s) when loading %s.", __FUNCTION__,
520 "GetCaptureSessionFactory", lib_path.c_str());
521 dlclose(lib_handle);
522 lib_handle = nullptr;
523 continue;
524 }
525
526 ExternalCaptureSessionFactory* external_session =
527 external_session_factory_t();
528 if (!external_session) {
529 ALOGE("%s: External session from (%s) may be incomplete", __FUNCTION__,
530 lib_path.c_str());
531 continue;
532 }
533
534 external_capture_session_entries_.push_back(external_session);
535 external_capture_session_lib_handles_.push_back(lib_handle);
536 }
537
538 return OK;
539 }
540
~CameraDeviceSession()541 CameraDeviceSession::~CameraDeviceSession() {
542 UnregisterThermalCallback();
543
544 capture_session_ = nullptr;
545 device_session_hwl_ = nullptr;
546
547 for (auto external_session : external_capture_session_entries_) {
548 delete external_session;
549 }
550
551 for (auto lib_handle : external_capture_session_lib_handles_) {
552 dlclose(lib_handle);
553 }
554
555 if (buffer_mapper_v4_ != nullptr) {
556 FreeImportedBufferHandles<android::hardware::graphics::mapper::V4_0::IMapper>(
557 buffer_mapper_v4_);
558 } else if (buffer_mapper_v3_ != nullptr) {
559 FreeImportedBufferHandles<android::hardware::graphics::mapper::V3_0::IMapper>(
560 buffer_mapper_v3_);
561 } else if (buffer_mapper_v2_ != nullptr) {
562 FreeImportedBufferHandles<android::hardware::graphics::mapper::V2_0::IMapper>(
563 buffer_mapper_v2_);
564 }
565 }
566
UnregisterThermalCallback()567 void CameraDeviceSession::UnregisterThermalCallback() {
568 std::shared_lock lock(session_callback_lock_);
569 if (thermal_callback_.unregister_thermal_changed_callback != nullptr) {
570 thermal_callback_.unregister_thermal_changed_callback();
571 }
572 }
573
SetSessionCallback(const CameraDeviceSessionCallback & session_callback,const ThermalCallback & thermal_callback)574 void CameraDeviceSession::SetSessionCallback(
575 const CameraDeviceSessionCallback& session_callback,
576 const ThermalCallback& thermal_callback) {
577 ATRACE_CALL();
578 std::lock_guard lock(session_callback_lock_);
579 session_callback_ = session_callback;
580 thermal_callback_ = thermal_callback;
581
582 status_t res = thermal_callback_.register_thermal_changed_callback(
583 NotifyThrottlingFunc([this](const Temperature& temperature) {
584 NotifyThrottling(temperature);
585 }),
586 /*filter_type=*/false,
587 /*type=*/TemperatureType::kUnknown);
588 if (res != OK) {
589 ALOGW("%s: Registering thermal callback failed: %s(%d)", __FUNCTION__,
590 strerror(-res), res);
591 }
592 }
593
NotifyThrottling(const Temperature & temperature)594 void CameraDeviceSession::NotifyThrottling(const Temperature& temperature) {
595 switch (temperature.throttling_status) {
596 case ThrottlingSeverity::kNone:
597 case ThrottlingSeverity::kLight:
598 case ThrottlingSeverity::kModerate:
599 ALOGI("%s: temperature type: %d, severity: %u, value: %f", __FUNCTION__,
600 temperature.type, temperature.throttling_status, temperature.value);
601 return;
602 case ThrottlingSeverity::kSevere:
603 case ThrottlingSeverity::kCritical:
604 case ThrottlingSeverity::kEmergency:
605 case ThrottlingSeverity::kShutdown:
606 ALOGW("%s: temperature type: %d, severity: %u, value: %f", __FUNCTION__,
607 temperature.type, temperature.throttling_status, temperature.value);
608 {
609 std::lock_guard<std::mutex> lock(session_lock_);
610 thermal_throttling_ = true;
611 }
612 return;
613 default:
614 ALOGE("%s: Unknown throttling status %u for type %d", __FUNCTION__,
615 temperature.throttling_status, temperature.type);
616 return;
617 }
618 }
619
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * default_settings)620 status_t CameraDeviceSession::ConstructDefaultRequestSettings(
621 RequestTemplate type,
622 std::unique_ptr<HalCameraMetadata>* default_settings) {
623 ATRACE_CALL();
624 status_t res = device_session_hwl_->ConstructDefaultRequestSettings(
625 type, default_settings);
626 if (res != OK) {
627 ALOGE("%s: Construct default settings for type %d failed: %s(%d)",
628 __FUNCTION__, type, strerror(-res), res);
629 return res;
630 }
631
632 return hal_vendor_tag_utils::ModifyDefaultRequestSettings(
633 type, default_settings->get());
634 }
635
ConfigureStreams(const StreamConfiguration & stream_config,std::vector<HalStream> * hal_config)636 status_t CameraDeviceSession::ConfigureStreams(
637 const StreamConfiguration& stream_config,
638 std::vector<HalStream>* hal_config) {
639 ATRACE_CALL();
640 std::lock_guard<std::mutex> lock(session_lock_);
641
642 std::lock_guard lock_capture_session(capture_session_lock_);
643 if (capture_session_ != nullptr) {
644 capture_session_ = nullptr;
645 }
646
647 pending_requests_tracker_ = nullptr;
648
649 if (!configured_streams_map_.empty()) {
650 CleanupStaleStreamsLocked(stream_config.streams);
651 }
652
653 hal_utils::DumpStreamConfiguration(stream_config, "App stream configuration");
654
655 operation_mode_ = stream_config.operation_mode;
656
657 // first pass: check loaded external capture sessions
658 for (auto externalSession : external_capture_session_entries_) {
659 if (externalSession->IsStreamConfigurationSupported(
660 device_session_hwl_.get(), stream_config)) {
661 capture_session_ = externalSession->CreateSession(
662 device_session_hwl_.get(), stream_config,
663 camera_device_session_callback_.process_capture_result,
664 camera_device_session_callback_.notify,
665 hwl_session_callback_.request_stream_buffers, hal_config,
666 camera_allocator_hwl_);
667 break;
668 }
669 }
670
671 // second pass: check predefined capture sessions
672 if (capture_session_ == nullptr) {
673 for (auto sessionEntry : kCaptureSessionEntries) {
674 if (sessionEntry.IsStreamConfigurationSupported(device_session_hwl_.get(),
675 stream_config)) {
676 capture_session_ = sessionEntry.CreateSession(
677 device_session_hwl_.get(), stream_config,
678 camera_device_session_callback_.process_capture_result,
679 camera_device_session_callback_.notify,
680 hwl_session_callback_.request_stream_buffers, hal_config,
681 camera_allocator_hwl_);
682 break;
683 }
684 }
685 }
686
687 if (capture_session_ == nullptr) {
688 ALOGE("%s: Cannot find a capture session compatible with stream config",
689 __FUNCTION__);
690 return BAD_VALUE;
691 }
692
693 if (buffer_management_supported_) {
694 stream_buffer_cache_manager_ = StreamBufferCacheManager::Create();
695 if (stream_buffer_cache_manager_ == nullptr) {
696 ALOGE("%s: Failed to create stream buffer cache manager.", __FUNCTION__);
697 return UNKNOWN_ERROR;
698 }
699
700 status_t res =
701 RegisterStreamsIntoCacheManagerLocked(stream_config, *hal_config);
702 if (res != OK) {
703 ALOGE("%s: Failed to register streams into stream buffer cache manager.",
704 __FUNCTION__);
705 return res;
706 }
707 }
708
709 // (b/129561652): Framework assumes HalStream is sorted.
710 std::sort(hal_config->begin(), hal_config->end(),
711 [](const HalStream& a, const HalStream& b) { return a.id < b.id; });
712
713 // Backup the streams received from frameworks into configured_streams_map_,
714 // and we can find out specific streams through stream id in output_buffers.
715 for (auto& stream : stream_config.streams) {
716 configured_streams_map_[stream.id] = stream;
717 }
718
719 // If buffer management is support, create a pending request tracker for
720 // capture request throttling.
721 if (buffer_management_supported_) {
722 pending_requests_tracker_ = PendingRequestsTracker::Create(*hal_config);
723 if (pending_requests_tracker_ == nullptr) {
724 ALOGE("%s: Cannot create a pending request tracker.", __FUNCTION__);
725 return UNKNOWN_ERROR;
726 }
727
728 {
729 std::lock_guard<std::mutex> lock(request_record_lock_);
730 pending_request_streams_.clear();
731 error_notified_requests_.clear();
732 dummy_buffer_observed_.clear();
733 pending_results_.clear();
734 }
735 }
736
737 has_valid_settings_ = false;
738 thermal_throttling_ = false;
739 thermal_throttling_notified_ = false;
740 last_request_settings_ = nullptr;
741 last_timestamp_ns_for_trace_ = 0;
742
743 return OK;
744 }
745
UpdateBufferHandlesLocked(std::vector<StreamBuffer> * buffers)746 status_t CameraDeviceSession::UpdateBufferHandlesLocked(
747 std::vector<StreamBuffer>* buffers) {
748 ATRACE_CALL();
749 if (buffers == nullptr) {
750 ALOGE("%s: buffers cannot be nullptr", __FUNCTION__);
751 return BAD_VALUE;
752 }
753
754 for (auto& buffer : *buffers) {
755 // Get the buffer handle from buffer handle map.
756 BufferCache buffer_cache = {buffer.stream_id, buffer.buffer_id};
757 auto buffer_handle_it = imported_buffer_handle_map_.find(buffer_cache);
758 if (buffer_handle_it == imported_buffer_handle_map_.end()) {
759 ALOGE("%s: Cannot find buffer handle for stream %u, buffer %" PRIu64,
760 __FUNCTION__, buffer.stream_id, buffer.buffer_id);
761 return NAME_NOT_FOUND;
762 }
763
764 buffer.buffer = buffer_handle_it->second;
765 }
766
767 return OK;
768 }
769
CreateCaptureRequestLocked(const CaptureRequest & request,CaptureRequest * updated_request)770 status_t CameraDeviceSession::CreateCaptureRequestLocked(
771 const CaptureRequest& request, CaptureRequest* updated_request) {
772 ATRACE_CALL();
773 if (updated_request == nullptr) {
774 return BAD_VALUE;
775 }
776
777 if (request.settings != nullptr) {
778 last_request_settings_ = HalCameraMetadata::Clone(request.settings.get());
779 }
780
781 updated_request->frame_number = request.frame_number;
782 updated_request->settings = HalCameraMetadata::Clone(request.settings.get());
783 updated_request->input_buffers = request.input_buffers;
784 updated_request->input_buffer_metadata.clear();
785 updated_request->output_buffers = request.output_buffers;
786
787 // Returns -1 if kThermalThrottling is not defined, skip following process.
788 if (get_camera_metadata_tag_type(VendorTagIds::kThermalThrottling) != -1) {
789 // Create settings to set thermal throttling key if needed.
790 if (thermal_throttling_ && !thermal_throttling_notified_ &&
791 updated_request->settings == nullptr) {
792 updated_request->settings =
793 HalCameraMetadata::Clone(last_request_settings_.get());
794 thermal_throttling_notified_ = true;
795 }
796
797 if (updated_request->settings != nullptr) {
798 status_t res = updated_request->settings->Set(
799 VendorTagIds::kThermalThrottling, &thermal_throttling_,
800 /*data_count=*/1);
801 if (res != OK) {
802 ALOGE("%s: Setting thermal throttling key failed: %s(%d)", __FUNCTION__,
803 strerror(-res), res);
804 return res;
805 }
806 }
807 }
808
809 AppendOutputIntentToSettingsLocked(request, updated_request);
810
811 // If buffer management API is supported, buffers will be requested via
812 // RequestStreamBuffersFunc.
813 if (!buffer_management_supported_) {
814 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
815
816 status_t res = UpdateBufferHandlesLocked(&updated_request->input_buffers);
817 if (res != OK) {
818 ALOGE("%s: Updating input buffer handles failed: %s(%d)", __FUNCTION__,
819 strerror(-res), res);
820 return res;
821 }
822
823 res = UpdateBufferHandlesLocked(&updated_request->output_buffers);
824 if (res != OK) {
825 ALOGE("%s: Updating output buffer handles failed: %s(%d)", __FUNCTION__,
826 strerror(-res), res);
827 return res;
828 }
829 }
830
831 zoom_ratio_mapper_.UpdateCaptureRequest(updated_request);
832
833 return OK;
834 }
835
836 template <class T, class U>
ImportBufferHandleLocked(const sp<T> buffer_mapper,const StreamBuffer & buffer)837 status_t CameraDeviceSession::ImportBufferHandleLocked(
838 const sp<T> buffer_mapper, const StreamBuffer& buffer) {
839 ATRACE_CALL();
840 U mapper_error;
841 buffer_handle_t imported_buffer_handle;
842
843 auto hidl_res = buffer_mapper->importBuffer(
844 android::hardware::hidl_handle(buffer.buffer),
845 [&](const auto& error, const auto& buffer_handle) {
846 mapper_error = error;
847 imported_buffer_handle = static_cast<buffer_handle_t>(buffer_handle);
848 });
849 if (!hidl_res.isOk() || mapper_error != U::NONE) {
850 ALOGE("%s: Importing buffer failed: %s, mapper error %u", __FUNCTION__,
851 hidl_res.description().c_str(), mapper_error);
852 return UNKNOWN_ERROR;
853 }
854
855 BufferCache buffer_cache = {buffer.stream_id, buffer.buffer_id};
856 return AddImportedBufferHandlesLocked(buffer_cache, imported_buffer_handle);
857 }
858
ImportBufferHandles(const std::vector<StreamBuffer> & buffers)859 status_t CameraDeviceSession::ImportBufferHandles(
860 const std::vector<StreamBuffer>& buffers) {
861 ATRACE_CALL();
862 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
863
864 // Import buffers that are new to HAL.
865 for (auto& buffer : buffers) {
866 if (!IsBufferImportedLocked(buffer.stream_id, buffer.buffer_id)) {
867 status_t res = OK;
868 if (buffer_mapper_v4_ != nullptr) {
869 res = ImportBufferHandleLocked<
870 android::hardware::graphics::mapper::V4_0::IMapper,
871 android::hardware::graphics::mapper::V4_0::Error>(buffer_mapper_v4_,
872 buffer);
873 } else if (buffer_mapper_v3_ != nullptr) {
874 res = ImportBufferHandleLocked<
875 android::hardware::graphics::mapper::V3_0::IMapper,
876 android::hardware::graphics::mapper::V3_0::Error>(buffer_mapper_v3_,
877 buffer);
878 } else {
879 res = ImportBufferHandleLocked<
880 android::hardware::graphics::mapper::V2_0::IMapper,
881 android::hardware::graphics::mapper::V2_0::Error>(buffer_mapper_v2_,
882 buffer);
883 }
884
885 if (res != OK) {
886 ALOGE("%s: Importing buffer %" PRIu64 " from stream %d failed: %s(%d)",
887 __FUNCTION__, buffer.buffer_id, buffer.stream_id, strerror(-res),
888 res);
889 return res;
890 }
891 }
892 }
893
894 return OK;
895 }
896
ImportRequestBufferHandles(const CaptureRequest & request)897 status_t CameraDeviceSession::ImportRequestBufferHandles(
898 const CaptureRequest& request) {
899 ATRACE_CALL();
900
901 if (buffer_management_supported_) {
902 ALOGV(
903 "%s: Buffer management is enabled. Skip importing buffers in "
904 "requests.",
905 __FUNCTION__);
906 return OK;
907 }
908
909 status_t res = ImportBufferHandles(request.input_buffers);
910 if (res != OK) {
911 ALOGE("%s: Importing input buffer handles failed: %s(%d)", __FUNCTION__,
912 strerror(-res), res);
913 return res;
914 }
915
916 res = ImportBufferHandles(request.output_buffers);
917 if (res != OK) {
918 ALOGE("%s: Importing output buffer handles failed: %s(%d)", __FUNCTION__,
919 strerror(-res), res);
920 return res;
921 }
922
923 return OK;
924 }
925
NotifyErrorMessage(uint32_t frame_number,int32_t stream_id,ErrorCode error_code)926 void CameraDeviceSession::NotifyErrorMessage(uint32_t frame_number,
927 int32_t stream_id,
928 ErrorCode error_code) {
929 ALOGI("%s: [sbc] Request %d with stream (%d), return error code (%d)",
930 __FUNCTION__, frame_number, stream_id, error_code);
931
932 if ((error_code == ErrorCode::kErrorResult ||
933 error_code == ErrorCode::kErrorRequest) &&
934 stream_id != kInvalidStreamId) {
935 ALOGW("%s: [sbc] Request %d reset setream id again", __FUNCTION__,
936 frame_number);
937 stream_id = kInvalidStreamId;
938 }
939 NotifyMessage message = {.type = MessageType::kError,
940 .message.error = {.frame_number = frame_number,
941 .error_stream_id = stream_id,
942 .error_code = error_code}};
943
944 std::shared_lock lock(session_callback_lock_);
945 session_callback_.notify(message);
946 }
947
TryHandleDummyResult(CaptureResult * result,bool * result_handled)948 status_t CameraDeviceSession::TryHandleDummyResult(CaptureResult* result,
949 bool* result_handled) {
950 if (result == nullptr || result_handled == nullptr) {
951 ALOGE("%s: result or result_handled is nullptr.", __FUNCTION__);
952 return BAD_VALUE;
953 }
954
955 uint32_t frame_number = result->frame_number;
956 *result_handled = false;
957 bool need_to_handle_result = false;
958 bool need_to_notify_error_result = false;
959 {
960 std::lock_guard<std::mutex> lock(request_record_lock_);
961 if (error_notified_requests_.find(frame_number) ==
962 error_notified_requests_.end()) {
963 for (auto& stream_buffer : result->output_buffers) {
964 if (dummy_buffer_observed_.find(stream_buffer.buffer) !=
965 dummy_buffer_observed_.end()) {
966 error_notified_requests_.insert(frame_number);
967 if (pending_results_.find(frame_number) != pending_results_.end()) {
968 need_to_notify_error_result = true;
969 pending_results_.erase(frame_number);
970 }
971 need_to_handle_result = true;
972 break;
973 }
974 }
975 } else {
976 need_to_handle_result = true;
977 }
978 }
979
980 if (need_to_notify_error_result) {
981 NotifyErrorMessage(frame_number, kInvalidStreamId, ErrorCode::kErrorResult);
982 }
983
984 if (need_to_handle_result) {
985 for (auto& stream_buffer : result->output_buffers) {
986 bool is_dummy_buffer = false;
987 {
988 std::lock_guard<std::mutex> lock(request_record_lock_);
989 is_dummy_buffer = (dummy_buffer_observed_.find(stream_buffer.buffer) !=
990 dummy_buffer_observed_.end());
991 }
992
993 uint64_t buffer_id = (is_dummy_buffer ? /*Use invalid for dummy*/ 0
994 : stream_buffer.buffer_id);
995 // To avoid publishing duplicated error buffer message, only publish
996 // it here when getting normal buffer status from HWL
997 if (stream_buffer.status == BufferStatus::kOk) {
998 NotifyErrorMessage(frame_number, stream_buffer.stream_id,
999 ErrorCode::kErrorBuffer);
1000 }
1001 NotifyBufferError(frame_number, stream_buffer.stream_id, buffer_id);
1002 }
1003
1004 std::vector<StreamBuffer> buffers;
1005 buffers.insert(buffers.end(), result->output_buffers.begin(),
1006 result->output_buffers.end());
1007
1008 if (!buffers.empty()) {
1009 if (pending_requests_tracker_->TrackReturnedResultBuffers(buffers) != OK) {
1010 ALOGE("%s: Tracking requested quota buffers failed", __FUNCTION__);
1011 }
1012 std::vector<StreamBuffer> acquired_buffers;
1013 {
1014 std::lock_guard<std::mutex> lock(request_record_lock_);
1015 for (auto& buffer : buffers) {
1016 if (dummy_buffer_observed_.find(buffer.buffer) ==
1017 dummy_buffer_observed_.end()) {
1018 acquired_buffers.push_back(buffer);
1019 }
1020 }
1021 }
1022
1023 if (pending_requests_tracker_->TrackReturnedAcquiredBuffers(
1024 acquired_buffers) != OK) {
1025 ALOGE("%s: Tracking requested acquired buffers failed", __FUNCTION__);
1026 }
1027 }
1028 }
1029
1030 *result_handled = need_to_handle_result;
1031 return OK;
1032 }
1033
NotifyBufferError(const CaptureRequest & request)1034 void CameraDeviceSession::NotifyBufferError(const CaptureRequest& request) {
1035 ALOGI("%s: [sbc] Return Buffer Error Status for frame %d", __FUNCTION__,
1036 request.frame_number);
1037
1038 auto result = std::make_unique<CaptureResult>(CaptureResult({}));
1039 result->frame_number = request.frame_number;
1040 for (auto& stream_buffer : request.output_buffers) {
1041 StreamBuffer buffer;
1042 buffer.stream_id = stream_buffer.stream_id;
1043 buffer.status = BufferStatus::kError;
1044 result->output_buffers.push_back(buffer);
1045 }
1046 for (auto& stream_buffer : request.input_buffers) {
1047 result->input_buffers.push_back(stream_buffer);
1048 }
1049 result->partial_result = 1;
1050
1051 std::shared_lock lock(session_callback_lock_);
1052 session_callback_.process_capture_result(std::move(result));
1053 }
1054
NotifyBufferError(uint32_t frame_number,int32_t stream_id,uint64_t buffer_id)1055 void CameraDeviceSession::NotifyBufferError(uint32_t frame_number,
1056 int32_t stream_id,
1057 uint64_t buffer_id) {
1058 ALOGI("%s: [sbc] Return Buffer Error Status for frame %d stream %d",
1059 __FUNCTION__, frame_number, stream_id);
1060
1061 auto result = std::make_unique<CaptureResult>(CaptureResult({}));
1062 result->frame_number = frame_number;
1063 StreamBuffer stream_buffer;
1064 stream_buffer.buffer_id = buffer_id;
1065 stream_buffer.stream_id = stream_id;
1066 stream_buffer.status = BufferStatus::kError;
1067 result->output_buffers.push_back(stream_buffer);
1068 result->partial_result = 1;
1069
1070 std::shared_lock lock(session_callback_lock_);
1071 session_callback_.process_capture_result(std::move(result));
1072 }
1073
HandleInactiveStreams(const CaptureRequest & request,bool * all_active)1074 status_t CameraDeviceSession::HandleInactiveStreams(const CaptureRequest& request,
1075 bool* all_active) {
1076 if (all_active == nullptr) {
1077 ALOGE("%s: all_active is nullptr", __FUNCTION__);
1078 return BAD_VALUE;
1079 }
1080
1081 *all_active = true;
1082 for (auto& stream_buffer : request.output_buffers) {
1083 bool is_active = true;
1084 status_t res = stream_buffer_cache_manager_->IsStreamActive(
1085 stream_buffer.stream_id, &is_active);
1086 if (res != OK) {
1087 ALOGE("%s: Failed to check if stream is active.", __FUNCTION__);
1088 return UNKNOWN_ERROR;
1089 }
1090 if (!is_active) {
1091 ALOGI("%s: Stream %d is not active when submitting frame %d request.",
1092 __FUNCTION__, stream_buffer.stream_id, request.frame_number);
1093 *all_active = false;
1094 break;
1095 }
1096 }
1097 if (*all_active == false) {
1098 NotifyErrorMessage(request.frame_number, kInvalidStreamId,
1099 ErrorCode::kErrorRequest);
1100 NotifyBufferError(request);
1101 }
1102
1103 return OK;
1104 }
1105
CheckRequestForStreamBufferCacheManager(const CaptureRequest & request,bool * need_to_process)1106 void CameraDeviceSession::CheckRequestForStreamBufferCacheManager(
1107 const CaptureRequest& request, bool* need_to_process) {
1108 ATRACE_CALL();
1109
1110 // If any stream in the stream buffer cache manager has been labeld as inactive,
1111 // return ERROR_REQUEST immediately. No need to send the request to HWL.
1112 status_t res = HandleInactiveStreams(request, need_to_process);
1113 if (res != OK) {
1114 ALOGE("%s: Failed to check if streams are active.", __FUNCTION__);
1115 return;
1116 }
1117
1118 // Add streams into pending_request_streams_
1119 uint32_t frame_number = request.frame_number;
1120 if (*need_to_process) {
1121 std::lock_guard<std::mutex> lock(request_record_lock_);
1122 pending_results_.insert(frame_number);
1123 for (auto& stream_buffer : request.output_buffers) {
1124 pending_request_streams_[frame_number].insert(stream_buffer.stream_id);
1125 }
1126 }
1127 }
1128
ValidateRequestLocked(const CaptureRequest & request)1129 status_t CameraDeviceSession::ValidateRequestLocked(
1130 const CaptureRequest& request) {
1131 // First request must have valid settings.
1132 if (!has_valid_settings_) {
1133 if (request.settings == nullptr ||
1134 request.settings->GetCameraMetadataSize() == 0) {
1135 ALOGE("%s: First request must have valid settings", __FUNCTION__);
1136 return BAD_VALUE;
1137 }
1138
1139 has_valid_settings_ = true;
1140 }
1141
1142 if (request.output_buffers.empty()) {
1143 ALOGE("%s: there is no output buffer.", __FUNCTION__);
1144 return BAD_VALUE;
1145 }
1146
1147 // Check all output streams are configured.
1148 for (auto& buffer : request.input_buffers) {
1149 if (configured_streams_map_.find(buffer.stream_id) ==
1150 configured_streams_map_.end()) {
1151 ALOGE("%s: input stream %d is not configured.", __FUNCTION__,
1152 buffer.stream_id);
1153 return BAD_VALUE;
1154 }
1155 }
1156
1157 for (auto& buffer : request.output_buffers) {
1158 if (configured_streams_map_.find(buffer.stream_id) ==
1159 configured_streams_map_.end()) {
1160 ALOGE("%s: output stream %d is not configured.", __FUNCTION__,
1161 buffer.stream_id);
1162 return BAD_VALUE;
1163 }
1164 }
1165
1166 return OK;
1167 }
1168
ProcessCaptureRequest(const std::vector<CaptureRequest> & requests,uint32_t * num_processed_requests)1169 status_t CameraDeviceSession::ProcessCaptureRequest(
1170 const std::vector<CaptureRequest>& requests,
1171 uint32_t* num_processed_requests) {
1172 ATRACE_CALL();
1173 std::lock_guard<std::mutex> lock(session_lock_);
1174 if (num_processed_requests == nullptr) {
1175 return BAD_VALUE;
1176 }
1177
1178 if (requests.empty()) {
1179 ALOGE("%s: requests is empty.", __FUNCTION__);
1180 return BAD_VALUE;
1181 }
1182
1183 status_t res;
1184 *num_processed_requests = 0;
1185
1186 for (auto& request : requests) {
1187 if (ATRACE_ENABLED()) {
1188 ATRACE_INT("request_frame_number", request.frame_number);
1189 }
1190
1191 res = ValidateRequestLocked(request);
1192 if (res != OK) {
1193 ALOGE("%s: Request %d is not valid.", __FUNCTION__, request.frame_number);
1194 return res;
1195 }
1196
1197 res = ImportRequestBufferHandles(request);
1198 if (res != OK) {
1199 ALOGE("%s: Importing request buffer handles failed: %s(%d)", __FUNCTION__,
1200 strerror(-res), res);
1201 return res;
1202 }
1203
1204 CaptureRequest updated_request;
1205 res = CreateCaptureRequestLocked(request, &updated_request);
1206 if (res != OK) {
1207 ALOGE("%s: Updating buffer handles failed for frame %u", __FUNCTION__,
1208 request.frame_number);
1209 return res;
1210 }
1211
1212 bool need_to_process = true;
1213 // If a processCaptureRequest() call is made during flushing,
1214 // notify CAMERA3_MSG_ERROR_REQUEST directly.
1215 if (is_flushing_) {
1216 NotifyErrorMessage(request.frame_number, kInvalidStreamId,
1217 ErrorCode::kErrorRequest);
1218 NotifyBufferError(request);
1219 need_to_process = false;
1220 } else if (buffer_management_supported_) {
1221 CheckRequestForStreamBufferCacheManager(updated_request, &need_to_process);
1222 }
1223
1224 if (need_to_process) {
1225 // If buffer management is supported, framework does not throttle requests
1226 // with stream's max buffers. We need to throttle on our own.
1227 if (buffer_management_supported_) {
1228 std::vector<int32_t> first_requested_stream_ids;
1229
1230 res = pending_requests_tracker_->WaitAndTrackRequestBuffers(
1231 updated_request, &first_requested_stream_ids);
1232 if (res != OK) {
1233 ALOGE("%s: Waiting until capture ready failed: %s(%d)", __FUNCTION__,
1234 strerror(-res), res);
1235 return res;
1236 }
1237
1238 for (auto& stream_id : first_requested_stream_ids) {
1239 ALOGI("%s: [sbc] Stream %d 1st req arrived, notify SBC Manager.",
1240 __FUNCTION__, stream_id);
1241 res = stream_buffer_cache_manager_->NotifyProviderReadiness(stream_id);
1242 if (res != OK) {
1243 ALOGE("%s: Notifying provider readiness failed: %s(%d)",
1244 __FUNCTION__, strerror(-res), res);
1245 return res;
1246 }
1247 }
1248 }
1249
1250 // Check the flush status again to prevent flush being called while we are
1251 // waiting for the request buffers(request throttling).
1252 if (buffer_management_supported_ && is_flushing_) {
1253 std::vector<StreamBuffer> buffers = updated_request.output_buffers;
1254 {
1255 std::lock_guard<std::mutex> lock(request_record_lock_);
1256 pending_request_streams_.erase(updated_request.frame_number);
1257 pending_results_.erase(updated_request.frame_number);
1258 }
1259 NotifyErrorMessage(updated_request.frame_number, kInvalidStreamId,
1260 ErrorCode::kErrorRequest);
1261 NotifyBufferError(updated_request);
1262 if (pending_requests_tracker_->TrackReturnedResultBuffers(buffers) !=
1263 OK) {
1264 ALOGE("%s: Tracking requested quota buffers failed", __FUNCTION__);
1265 }
1266 } else {
1267 std::shared_lock lock(capture_session_lock_);
1268 if (capture_session_ == nullptr) {
1269 ALOGE("%s: Capture session wasn't created.", __FUNCTION__);
1270 return NO_INIT;
1271 }
1272
1273 res = capture_session_->ProcessRequest(updated_request);
1274 if (res != OK) {
1275 ALOGE("%s: Submitting request to HWL session failed: %s (%d)",
1276 __FUNCTION__, strerror(-res), res);
1277 return res;
1278 }
1279 }
1280 }
1281
1282 (*num_processed_requests)++;
1283 }
1284
1285 return OK;
1286 }
1287
IsBufferImportedLocked(int32_t stream_id,uint32_t buffer_id)1288 bool CameraDeviceSession::IsBufferImportedLocked(int32_t stream_id,
1289 uint32_t buffer_id) {
1290 BufferCache buffer_cache = {stream_id, buffer_id};
1291 return imported_buffer_handle_map_.find(buffer_cache) !=
1292 imported_buffer_handle_map_.end();
1293 }
1294
AddImportedBufferHandlesLocked(const BufferCache & buffer_cache,buffer_handle_t buffer_handle)1295 status_t CameraDeviceSession::AddImportedBufferHandlesLocked(
1296 const BufferCache& buffer_cache, buffer_handle_t buffer_handle) {
1297 ATRACE_CALL();
1298 auto buffer_handle_it = imported_buffer_handle_map_.find(buffer_cache);
1299 if (buffer_handle_it == imported_buffer_handle_map_.end()) {
1300 // Add a new buffer cache if it doesn't exist.
1301 imported_buffer_handle_map_.emplace(buffer_cache, buffer_handle);
1302 } else if (buffer_handle_it->second != buffer_handle) {
1303 ALOGE(
1304 "%s: Cached buffer handle %p doesn't match %p for stream %u buffer "
1305 "%" PRIu64,
1306 __FUNCTION__, buffer_handle_it->second, buffer_handle,
1307 buffer_cache.stream_id, buffer_cache.buffer_id);
1308 return BAD_VALUE;
1309 }
1310
1311 return OK;
1312 }
1313
RemoveBufferCache(const std::vector<BufferCache> & buffer_caches)1314 void CameraDeviceSession::RemoveBufferCache(
1315 const std::vector<BufferCache>& buffer_caches) {
1316 ATRACE_CALL();
1317 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1318
1319 for (auto& buffer_cache : buffer_caches) {
1320 auto buffer_handle_it = imported_buffer_handle_map_.find(buffer_cache);
1321 if (buffer_handle_it == imported_buffer_handle_map_.end()) {
1322 ALOGW("%s: Could not find buffer cache for stream %u buffer %" PRIu64,
1323 __FUNCTION__, buffer_cache.stream_id, buffer_cache.buffer_id);
1324 continue;
1325 }
1326
1327 auto free_buffer_mapper = [&buffer_handle_it](auto buffer_mapper) {
1328 auto hidl_res = buffer_mapper->freeBuffer(
1329 const_cast<native_handle_t*>(buffer_handle_it->second));
1330 if (!hidl_res.isOk()) {
1331 ALOGE("%s: Freeing imported buffer failed: %s", __FUNCTION__,
1332 hidl_res.description().c_str());
1333 }
1334 };
1335
1336 if (buffer_mapper_v4_ != nullptr) {
1337 free_buffer_mapper(buffer_mapper_v4_);
1338 } else if (buffer_mapper_v3_ != nullptr) {
1339 free_buffer_mapper(buffer_mapper_v3_);
1340 } else {
1341 free_buffer_mapper(buffer_mapper_v2_);
1342 ;
1343 }
1344
1345 imported_buffer_handle_map_.erase(buffer_handle_it);
1346 }
1347 }
1348
1349 template <class T>
FreeBufferHandlesLocked(const sp<T> buffer_mapper,int32_t stream_id)1350 void CameraDeviceSession::FreeBufferHandlesLocked(const sp<T> buffer_mapper,
1351 int32_t stream_id) {
1352 for (auto buffer_handle_it = imported_buffer_handle_map_.begin();
1353 buffer_handle_it != imported_buffer_handle_map_.end();) {
1354 if (buffer_handle_it->first.stream_id == stream_id) {
1355 auto hidl_res = buffer_mapper->freeBuffer(
1356 const_cast<native_handle_t*>(buffer_handle_it->second));
1357 if (!hidl_res.isOk()) {
1358 ALOGE("%s: Freeing imported buffer failed: %s", __FUNCTION__,
1359 hidl_res.description().c_str());
1360 }
1361 buffer_handle_it = imported_buffer_handle_map_.erase(buffer_handle_it);
1362 } else {
1363 buffer_handle_it++;
1364 }
1365 }
1366 }
1367
1368 template <class T>
FreeImportedBufferHandles(const sp<T> buffer_mapper)1369 void CameraDeviceSession::FreeImportedBufferHandles(const sp<T> buffer_mapper) {
1370 ATRACE_CALL();
1371 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1372
1373 if (buffer_mapper == nullptr) {
1374 return;
1375 }
1376
1377 for (auto buffer_handle_it : imported_buffer_handle_map_) {
1378 auto hidl_res = buffer_mapper->freeBuffer(
1379 const_cast<native_handle_t*>(buffer_handle_it.second));
1380 if (!hidl_res.isOk()) {
1381 ALOGE("%s: Freeing imported buffer failed: %s", __FUNCTION__,
1382 hidl_res.description().c_str());
1383 }
1384 }
1385
1386 imported_buffer_handle_map_.clear();
1387 }
1388
CleanupStaleStreamsLocked(const std::vector<Stream> & new_streams)1389 void CameraDeviceSession::CleanupStaleStreamsLocked(
1390 const std::vector<Stream>& new_streams) {
1391 for (auto stream_it = configured_streams_map_.begin();
1392 stream_it != configured_streams_map_.end();) {
1393 int32_t stream_id = stream_it->first;
1394 bool found = false;
1395 for (const Stream& stream : new_streams) {
1396 if (stream.id == stream_id) {
1397 found = true;
1398 break;
1399 }
1400 }
1401 if (!found) {
1402 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1403 stream_it = configured_streams_map_.erase(stream_it);
1404 if (buffer_mapper_v4_ != nullptr) {
1405 FreeBufferHandlesLocked<android::hardware::graphics::mapper::V4_0::IMapper>(
1406 buffer_mapper_v4_, stream_id);
1407 } else if (buffer_mapper_v3_ != nullptr) {
1408 FreeBufferHandlesLocked<android::hardware::graphics::mapper::V3_0::IMapper>(
1409 buffer_mapper_v3_, stream_id);
1410 } else {
1411 FreeBufferHandlesLocked<android::hardware::graphics::mapper::V2_0::IMapper>(
1412 buffer_mapper_v2_, stream_id);
1413 }
1414 } else {
1415 stream_it++;
1416 }
1417 }
1418 }
1419
Flush()1420 status_t CameraDeviceSession::Flush() {
1421 ATRACE_CALL();
1422 std::shared_lock lock(capture_session_lock_);
1423 if (capture_session_ == nullptr) {
1424 return OK;
1425 }
1426
1427 is_flushing_ = true;
1428 status_t res = capture_session_->Flush();
1429 is_flushing_ = false;
1430
1431 return res;
1432 }
1433
AppendOutputIntentToSettingsLocked(const CaptureRequest & request,CaptureRequest * updated_request)1434 void CameraDeviceSession::AppendOutputIntentToSettingsLocked(
1435 const CaptureRequest& request, CaptureRequest* updated_request) {
1436 if (updated_request == nullptr || updated_request->settings == nullptr) {
1437 // The frameworks may have no settings and just do nothing here.
1438 return;
1439 }
1440
1441 bool has_video = false;
1442 bool has_snapshot = false;
1443 bool has_zsl = false;
1444
1445 // From request output_buffers to find stream id and then find the stream.
1446 for (auto& buffer : request.output_buffers) {
1447 auto stream = configured_streams_map_.find(buffer.stream_id);
1448 if (stream != configured_streams_map_.end()) {
1449 if (utils::IsVideoStream(stream->second)) {
1450 has_video = true;
1451 } else if (utils::IsJPEGSnapshotStream(stream->second)) {
1452 has_snapshot = true;
1453 }
1454 }
1455 }
1456
1457 for (auto& buffer : request.input_buffers) {
1458 auto stream = configured_streams_map_.find(buffer.stream_id);
1459 if (stream != configured_streams_map_.end()) {
1460 if ((stream->second.usage & GRALLOC_USAGE_HW_CAMERA_ZSL) != 0) {
1461 has_zsl = true;
1462 break;
1463 }
1464 }
1465 }
1466
1467 uint8_t output_intent = static_cast<uint8_t>(OutputIntent::kPreview);
1468
1469 if (has_video && has_snapshot) {
1470 output_intent = static_cast<uint8_t>(OutputIntent::kVideoSnapshot);
1471 } else if (has_snapshot) {
1472 output_intent = static_cast<uint8_t>(OutputIntent::kSnapshot);
1473 } else if (has_video) {
1474 output_intent = static_cast<uint8_t>(OutputIntent::kVideo);
1475 } else if (has_zsl) {
1476 output_intent = static_cast<uint8_t>(OutputIntent::kZsl);
1477 }
1478
1479 status_t res = updated_request->settings->Set(VendorTagIds::kOutputIntent,
1480 &output_intent,
1481 /*data_count=*/1);
1482 if (res != OK) {
1483 ALOGE("%s: Failed to set vendor tag OutputIntent: %s(%d).", __FUNCTION__,
1484 strerror(-res), res);
1485 }
1486 }
1487
IsReconfigurationRequired(const HalCameraMetadata * old_session,const HalCameraMetadata * new_session,bool * reconfiguration_required)1488 status_t CameraDeviceSession::IsReconfigurationRequired(
1489 const HalCameraMetadata* old_session, const HalCameraMetadata* new_session,
1490 bool* reconfiguration_required) {
1491 if (old_session == nullptr || new_session == nullptr ||
1492 reconfiguration_required == nullptr) {
1493 ALOGE(
1494 "%s: old_session or new_session or reconfiguration_required is "
1495 "nullptr.",
1496 __FUNCTION__);
1497 return BAD_VALUE;
1498 }
1499
1500 return device_session_hwl_->IsReconfigurationRequired(
1501 old_session, new_session, reconfiguration_required);
1502 }
1503
UpdateRequestedBufferHandles(std::vector<StreamBuffer> * buffers)1504 status_t CameraDeviceSession::UpdateRequestedBufferHandles(
1505 std::vector<StreamBuffer>* buffers) {
1506 if (buffers == nullptr) {
1507 ALOGE("%s: buffer is nullptr.", __FUNCTION__);
1508 return BAD_VALUE;
1509 }
1510
1511 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1512
1513 status_t res;
1514 for (auto& buffer : *buffers) {
1515 // If buffer handle is not nullptr, we need to add the new buffer handle
1516 // to buffer cache.
1517 if (buffer.buffer != nullptr) {
1518 BufferCache buffer_cache = {buffer.stream_id, buffer.buffer_id};
1519 res = AddImportedBufferHandlesLocked(buffer_cache, buffer.buffer);
1520 if (res != OK) {
1521 ALOGE("%s: Adding imported buffer handle failed: %s(%d)", __FUNCTION__,
1522 strerror(-res), res);
1523 return res;
1524 }
1525 }
1526 }
1527
1528 res = UpdateBufferHandlesLocked(buffers);
1529 if (res != OK) {
1530 ALOGE("%s: Updating output buffer handles failed: %s(%d)", __FUNCTION__,
1531 strerror(-res), res);
1532 return res;
1533 }
1534
1535 return OK;
1536 }
1537
RegisterStreamsIntoCacheManagerLocked(const StreamConfiguration & stream_config,const std::vector<HalStream> & hal_stream)1538 status_t CameraDeviceSession::RegisterStreamsIntoCacheManagerLocked(
1539 const StreamConfiguration& stream_config,
1540 const std::vector<HalStream>& hal_stream) {
1541 ATRACE_CALL();
1542
1543 for (auto& stream : stream_config.streams) {
1544 uint64_t producer_usage = 0;
1545 uint64_t consumer_usage = 0;
1546 int32_t stream_id = -1;
1547 for (auto& hal_stream : hal_stream) {
1548 if (hal_stream.id == stream.id) {
1549 producer_usage = hal_stream.producer_usage;
1550 consumer_usage = hal_stream.consumer_usage;
1551 stream_id = hal_stream.id;
1552 }
1553 }
1554 if (stream_id == -1) {
1555 ALOGE("%s: Could not fine framework stream in hal configured stream list",
1556 __FUNCTION__);
1557 return UNKNOWN_ERROR;
1558 }
1559
1560 StreamBufferRequestFunc session_request_func = StreamBufferRequestFunc(
1561 [this, stream_id](uint32_t num_buffer,
1562 std::vector<StreamBuffer>* buffers,
1563 StreamBufferRequestError* status) -> status_t {
1564 if (buffers == nullptr) {
1565 ALOGE("%s: buffers is nullptr.", __FUNCTION__);
1566 return BAD_VALUE;
1567 }
1568
1569 if (num_buffer == 0) {
1570 ALOGE("%s: num_buffer is 0", __FUNCTION__);
1571 return BAD_VALUE;
1572 }
1573
1574 if (status == nullptr) {
1575 ALOGE("%s: status is nullptr.", __FUNCTION__);
1576 return BAD_VALUE;
1577 }
1578
1579 return RequestStreamBuffers(stream_id, num_buffer, buffers, status);
1580 });
1581
1582 StreamBufferReturnFunc session_return_func = StreamBufferReturnFunc(
1583 [this](const std::vector<StreamBuffer>& buffers) -> status_t {
1584 ReturnStreamBuffers(buffers);
1585
1586 for (auto& stream_buffer : buffers) {
1587 ALOGI("%s: [sbc] Flushed buf[%p] bid[%" PRIu64 "] strm[%d] frm[xx]",
1588 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
1589 stream_buffer.stream_id);
1590 }
1591
1592 return OK;
1593 });
1594
1595 StreamBufferCacheRegInfo reg_info = {.request_func = session_request_func,
1596 .return_func = session_return_func,
1597 .stream_id = stream_id,
1598 .width = stream.width,
1599 .height = stream.height,
1600 .format = stream.format,
1601 .producer_flags = producer_usage,
1602 .consumer_flags = consumer_usage,
1603 .num_buffers_to_cache = 1};
1604
1605 status_t res = stream_buffer_cache_manager_->RegisterStream(reg_info);
1606 if (res != OK) {
1607 ALOGE("%s: Failed to register stream into stream buffer cache manager.",
1608 __FUNCTION__);
1609 return UNKNOWN_ERROR;
1610 }
1611 ALOGI("%s: [sbc] Registered stream %d into SBC manager.", __FUNCTION__,
1612 stream.id);
1613 }
1614
1615 return OK;
1616 }
1617
RequestBuffersFromStreamBufferCacheManager(int32_t stream_id,uint32_t num_buffers,std::vector<StreamBuffer> * buffers,uint32_t frame_number)1618 status_t CameraDeviceSession::RequestBuffersFromStreamBufferCacheManager(
1619 int32_t stream_id, uint32_t num_buffers, std::vector<StreamBuffer>* buffers,
1620 uint32_t frame_number) {
1621 if (num_buffers != 1) {
1622 ALOGE(
1623 "%s: Only one buffer per request can be handled now. num_buffers = %d",
1624 __FUNCTION__, num_buffers);
1625 // TODO(b/127988765): handle multiple buffers from multiple streams if
1626 // HWL needs this feature.
1627 return BAD_VALUE;
1628 }
1629
1630 StreamBufferRequestResult buffer_request_result;
1631
1632 status_t res = this->stream_buffer_cache_manager_->GetStreamBuffer(
1633 stream_id, &buffer_request_result);
1634 if (res != OK) {
1635 ALOGE("%s: Failed to get stream buffer from SBC manager.", __FUNCTION__);
1636 return UNKNOWN_ERROR;
1637 }
1638
1639 // This function fulfills requests from lower HAL level. It is hard for some
1640 // implementation of lower HAL level to handle the case of a request failure.
1641 // In case a framework buffer can not be delivered to the lower level, a dummy
1642 // buffer will be returned by the stream buffer cache manager.
1643 // The client at lower level can use that dummy buffer as a normal buffer for
1644 // writing and so forth. But that buffer will not be returned to the
1645 // framework. This avoids the troublesome for lower level to handle such
1646 // situation. An ERROR_REQUEST needs to be returned to the framework according
1647 // to ::android::hardware::camera::device::V3_5::StreamBufferRequestError.
1648 if (buffer_request_result.is_dummy_buffer) {
1649 ALOGI("%s: [sbc] Dummy buffer returned for stream: %d, frame: %d",
1650 __FUNCTION__, stream_id, frame_number);
1651 {
1652 std::lock_guard<std::mutex> lock(request_record_lock_);
1653 dummy_buffer_observed_.insert(buffer_request_result.buffer.buffer);
1654 }
1655 }
1656
1657 ALOGV("%s: [sbc] => HWL Acquired buf[%p] buf_id[%" PRIu64
1658 "] strm[%d] frm[%u] dummy[%d]",
1659 __FUNCTION__, buffer_request_result.buffer.buffer,
1660 buffer_request_result.buffer.buffer_id, stream_id, frame_number,
1661 buffer_request_result.is_dummy_buffer);
1662
1663 buffers->push_back(buffer_request_result.buffer);
1664 return OK;
1665 }
1666
RequestStreamBuffers(int32_t stream_id,uint32_t num_buffers,std::vector<StreamBuffer> * buffers,StreamBufferRequestError * request_status)1667 status_t CameraDeviceSession::RequestStreamBuffers(
1668 int32_t stream_id, uint32_t num_buffers, std::vector<StreamBuffer>* buffers,
1669 StreamBufferRequestError* request_status) {
1670 if (buffers == nullptr) {
1671 ALOGE("%s: buffers is nullptr", __FUNCTION__);
1672 return BAD_VALUE;
1673 }
1674
1675 if (num_buffers == 0) {
1676 ALOGE("%s: num_buffers is 0", __FUNCTION__);
1677 return BAD_VALUE;
1678 }
1679
1680 if (request_status == nullptr) {
1681 ALOGE("%s: request_status is nullptr", __FUNCTION__);
1682 return BAD_VALUE;
1683 }
1684
1685 *request_status = StreamBufferRequestError::kOk;
1686 status_t res = pending_requests_tracker_->WaitAndTrackAcquiredBuffers(
1687 stream_id, num_buffers);
1688 if (res != OK) {
1689 ALOGW("%s: Waiting until available buffer failed: %s(%d)", __FUNCTION__,
1690 strerror(-res), res);
1691 *request_status = StreamBufferRequestError::kNoBufferAvailable;
1692 return res;
1693 }
1694
1695 std::vector<BufferReturn> buffer_returns;
1696 std::vector<BufferRequest> buffer_requests = {{
1697 .stream_id = stream_id,
1698 .num_buffers_requested = num_buffers,
1699 }};
1700
1701 BufferRequestStatus status = BufferRequestStatus::kOk;
1702 {
1703 std::shared_lock lock(session_callback_lock_);
1704 status = session_callback_.request_stream_buffers(buffer_requests,
1705 &buffer_returns);
1706 }
1707
1708 // need this information when status is not kOk
1709 if (buffer_returns.size() > 0) {
1710 *request_status = buffer_returns[0].val.error;
1711 }
1712
1713 if (status != BufferRequestStatus::kOk || buffer_returns.size() != 1) {
1714 ALOGW(
1715 "%s: Requesting stream buffer failed. (buffer_returns has %zu "
1716 "entries)",
1717 __FUNCTION__, buffer_returns.size());
1718 for (auto& buffer_return : buffer_returns) {
1719 ALOGI("%s: stream %d, buffer request error %d", __FUNCTION__,
1720 buffer_return.stream_id, buffer_return.val.error);
1721 }
1722
1723 pending_requests_tracker_->TrackBufferAcquisitionFailure(stream_id,
1724 num_buffers);
1725 // TODO(b/129362905): Return partial buffers.
1726 return UNKNOWN_ERROR;
1727 }
1728
1729 *buffers = buffer_returns[0].val.buffers;
1730
1731 res = UpdateRequestedBufferHandles(buffers);
1732 if (res != OK) {
1733 ALOGE("%s: Updating requested buffer handles failed: %s(%d).", __FUNCTION__,
1734 strerror(-res), res);
1735 // TODO(b/129362905): Return partial buffers.
1736 return res;
1737 }
1738
1739 ALOGV("%s: [sbc] => CDS Acquired buf[%p] buf_id[%" PRIu64 "] strm[%d]",
1740 __FUNCTION__, buffers->at(0).buffer, buffers->at(0).buffer_id,
1741 stream_id);
1742
1743 return OK;
1744 }
1745
ReturnStreamBuffers(const std::vector<StreamBuffer> & buffers)1746 void CameraDeviceSession::ReturnStreamBuffers(
1747 const std::vector<StreamBuffer>& buffers) {
1748 {
1749 std::shared_lock lock(session_callback_lock_);
1750 session_callback_.return_stream_buffers(buffers);
1751 }
1752
1753 for (auto& stream_buffer : buffers) {
1754 ALOGV("%s: [sbc] <= Return extra buf[%p], bid[%" PRIu64 "], strm[%d]",
1755 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
1756 stream_buffer.stream_id);
1757 }
1758
1759 if (pending_requests_tracker_->TrackReturnedAcquiredBuffers(buffers) != OK) {
1760 ALOGE("%s: Tracking requested buffers failed.", __FUNCTION__);
1761 }
1762 }
1763
1764 } // namespace google_camera_hal
1765 } // namespace android
1766