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