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_CameraProvider"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "camera_provider.h"
21 
22 #include <dlfcn.h>
23 #include <log/log.h>
24 #include <utils/Trace.h>
25 
26 #include "vendor_tag_defs.h"
27 #include "vendor_tag_utils.h"
28 
29 #if GCH_HWL_USE_DLOPEN
30 // HWL layer implementation path
31 constexpr std::string_view kCameraHwlLib = "libgooglecamerahwl_impl.so";
32 #endif
33 
34 namespace android {
35 namespace google_camera_hal {
36 
~CameraProvider()37 CameraProvider::~CameraProvider() {
38   VendorTagManager::GetInstance().Reset();
39   if (hwl_lib_handle_ != nullptr) {
40     dlclose(hwl_lib_handle_);
41     hwl_lib_handle_ = nullptr;
42   }
43 }
44 
Create(std::unique_ptr<CameraProviderHwl> camera_provider_hwl)45 std::unique_ptr<CameraProvider> CameraProvider::Create(
46     std::unique_ptr<CameraProviderHwl> camera_provider_hwl) {
47   ATRACE_CALL();
48   auto provider = std::unique_ptr<CameraProvider>(new CameraProvider());
49   if (provider == nullptr) {
50     ALOGE("%s: Creating CameraProvider failed.", __FUNCTION__);
51     return nullptr;
52   }
53 
54   status_t res = provider->Initialize(std::move(camera_provider_hwl));
55   if (res != OK) {
56     ALOGE("%s: Initializing CameraProvider failed: %s (%d).", __FUNCTION__,
57           strerror(-res), res);
58     return nullptr;
59   }
60 
61   return provider;
62 }
63 
Initialize(std::unique_ptr<CameraProviderHwl> camera_provider_hwl)64 status_t CameraProvider::Initialize(
65     std::unique_ptr<CameraProviderHwl> camera_provider_hwl) {
66   ATRACE_CALL();
67   // Advertise the HAL vendor tags to the camera metadata framework before
68   // creating a HWL provider.
69   status_t res = VendorTagManager::GetInstance().AddTags(kHalVendorTagSections);
70   if (res != OK) {
71     ALOGE("%s: Initializing VendorTagManager failed: %s(%d)", __FUNCTION__,
72           strerror(-res), res);
73     return res;
74   }
75 
76   if (camera_provider_hwl == nullptr) {
77     status_t res = CreateHwl(&camera_provider_hwl);
78     if (res != OK) {
79       ALOGE("%s: Creating CameraProviderHwlImpl failed.", __FUNCTION__);
80       return NO_INIT;
81     }
82   }
83 
84   res = camera_provider_hwl->CreateBufferAllocatorHwl(&camera_allocator_hwl_);
85   if (res == INVALID_OPERATION) {
86     camera_allocator_hwl_ = nullptr;
87     ALOGE("%s: HWL doesn't support vendor buffer allocation %s(%d)",
88           __FUNCTION__, strerror(-res), res);
89   } else if (res != OK) {
90     camera_allocator_hwl_ = nullptr;
91     ALOGE("%s: Creating CameraBufferAllocatorHwl failed: %s(%d)", __FUNCTION__,
92           strerror(-res), res);
93     return NO_INIT;
94   }
95 
96   camera_provider_hwl_ = std::move(camera_provider_hwl);
97   res = InitializeVendorTags();
98   if (res != OK) {
99     ALOGE("%s InitailizeVendorTags() failed: %s (%d).", __FUNCTION__,
100           strerror(-res), res);
101     camera_provider_hwl_ = nullptr;
102     return res;
103   }
104 
105   return OK;
106 }
107 
InitializeVendorTags()108 status_t CameraProvider::InitializeVendorTags() {
109   std::vector<VendorTagSection> hwl_tag_sections;
110   status_t res = camera_provider_hwl_->GetVendorTags(&hwl_tag_sections);
111   if (res != OK) {
112     ALOGE("%s: GetVendorTags() for HWL tags failed: %s(%d)", __FUNCTION__,
113           strerror(-res), res);
114     return res;
115   }
116 
117   // Combine HAL and HWL vendor tag sections
118   res = vendor_tag_utils::CombineVendorTags(
119       kHalVendorTagSections, hwl_tag_sections, &vendor_tag_sections_);
120   if (res != OK) {
121     ALOGE("%s: CombineVendorTags() failed: %s(%d)", __FUNCTION__,
122           strerror(-res), res);
123     return res;
124   }
125 
126   return OK;
127 }
128 
SetCallback(const CameraProviderCallback * callback)129 status_t CameraProvider::SetCallback(const CameraProviderCallback* callback) {
130   ATRACE_CALL();
131   if (callback == nullptr) {
132     return BAD_VALUE;
133   }
134 
135   provider_callback_ = callback;
136   if (camera_provider_hwl_ == nullptr) {
137     ALOGE("%s: Camera provider HWL was not initialized to set callback.",
138           __FUNCTION__);
139     return NO_INIT;
140   }
141 
142   hwl_provider_callback_.camera_device_status_change =
143       HwlCameraDeviceStatusChangeFunc(
144           [this](uint32_t camera_id, CameraDeviceStatus new_status) {
145             provider_callback_->camera_device_status_change(
146                 std::to_string(camera_id), new_status);
147           });
148 
149   hwl_provider_callback_.physical_camera_device_status_change =
150       HwlPhysicalCameraDeviceStatusChangeFunc(
151           [this](uint32_t camera_id, uint32_t physical_camera_id,
152                  CameraDeviceStatus new_status) {
153             provider_callback_->physical_camera_device_status_change(
154                 std::to_string(camera_id), std::to_string(physical_camera_id),
155                 new_status);
156           });
157 
158   hwl_provider_callback_.torch_mode_status_change = HwlTorchModeStatusChangeFunc(
159       [this](uint32_t camera_id, TorchModeStatus new_status) {
160         provider_callback_->torch_mode_status_change(std::to_string(camera_id),
161                                                      new_status);
162       });
163 
164   camera_provider_hwl_->SetCallback(hwl_provider_callback_);
165   return OK;
166 }
167 
TriggerDeferredCallbacks()168 status_t CameraProvider::TriggerDeferredCallbacks() {
169   ATRACE_CALL();
170   return camera_provider_hwl_->TriggerDeferredCallbacks();
171 }
172 
GetVendorTags(std::vector<VendorTagSection> * vendor_tag_sections) const173 status_t CameraProvider::GetVendorTags(
174     std::vector<VendorTagSection>* vendor_tag_sections) const {
175   ATRACE_CALL();
176   if (vendor_tag_sections == nullptr) {
177     return BAD_VALUE;
178   }
179 
180   if (camera_provider_hwl_ == nullptr) {
181     ALOGE("%s: Camera provider HWL was not initialized.", __FUNCTION__);
182     return NO_INIT;
183   }
184 
185   *vendor_tag_sections = vendor_tag_sections_;
186   return OK;
187 }
188 
GetCameraIdList(std::vector<uint32_t> * camera_ids) const189 status_t CameraProvider::GetCameraIdList(std::vector<uint32_t>* camera_ids) const {
190   ATRACE_CALL();
191   if (camera_ids == nullptr) {
192     ALOGE("%s: camera_ids is nullptr", __FUNCTION__);
193     return BAD_VALUE;
194   }
195 
196   status_t res = camera_provider_hwl_->GetVisibleCameraIds(camera_ids);
197   if (res != OK) {
198     ALOGE("%s: failed to get visible camera IDs from the camera provider",
199           __FUNCTION__);
200     return res;
201   }
202   return OK;
203 }
204 
IsSetTorchModeSupported() const205 bool CameraProvider::IsSetTorchModeSupported() const {
206   ATRACE_CALL();
207   if (camera_provider_hwl_ == nullptr) {
208     ALOGE("%s: Camera provider HWL was not initialized.", __FUNCTION__);
209     return NO_INIT;
210   }
211 
212   return camera_provider_hwl_->IsSetTorchModeSupported();
213 }
214 
IsConcurrentStreamCombinationSupported(const std::vector<CameraIdAndStreamConfiguration> & configs,bool * is_supported)215 status_t CameraProvider::IsConcurrentStreamCombinationSupported(
216     const std::vector<CameraIdAndStreamConfiguration>& configs,
217     bool* is_supported) {
218   ATRACE_CALL();
219   if (camera_provider_hwl_ == nullptr) {
220     ALOGE("%s: Camera provider HWL was not initialized.", __FUNCTION__);
221     return NO_INIT;
222   }
223   return camera_provider_hwl_->IsConcurrentStreamCombinationSupported(
224       configs, is_supported);
225 }
226 
227 // Get the combinations of camera ids which support concurrent streaming
GetConcurrentStreamingCameraIds(std::vector<std::unordered_set<uint32_t>> * camera_id_combinations)228 status_t CameraProvider::GetConcurrentStreamingCameraIds(
229     std::vector<std::unordered_set<uint32_t>>* camera_id_combinations) {
230   if (camera_id_combinations == nullptr) {
231     return BAD_VALUE;
232   }
233 
234   ATRACE_CALL();
235   if (camera_provider_hwl_ == nullptr) {
236     ALOGE("%s: Camera provider HWL was not initialized.", __FUNCTION__);
237     return NO_INIT;
238   }
239 
240   return camera_provider_hwl_->GetConcurrentStreamingCameraIds(
241       camera_id_combinations);
242 }
243 
CreateCameraDevice(uint32_t camera_id,std::unique_ptr<CameraDevice> * device)244 status_t CameraProvider::CreateCameraDevice(
245     uint32_t camera_id, std::unique_ptr<CameraDevice>* device) {
246   ATRACE_CALL();
247   std::vector<uint32_t> camera_ids;
248   if (device == nullptr) {
249     return BAD_VALUE;
250   }
251 
252   if (camera_provider_hwl_ == nullptr) {
253     ALOGE("%s: Camera provider HWL was not initialized.", __FUNCTION__);
254     return NO_INIT;
255   }
256 
257   // Check camera_id is valid.
258   status_t res = camera_provider_hwl_->GetVisibleCameraIds(&camera_ids);
259   if (res != OK) {
260     ALOGE("%s: failed to get visible camera IDs from the camera provider",
261           __FUNCTION__);
262     return res;
263   }
264 
265   if (std::find(camera_ids.begin(), camera_ids.end(), camera_id) ==
266       camera_ids.end()) {
267     ALOGE("%s: camera_id: %u  invalid.", __FUNCTION__, camera_id);
268     return BAD_VALUE;
269   }
270 
271   std::unique_ptr<CameraDeviceHwl> camera_device_hwl;
272   res = camera_provider_hwl_->CreateCameraDeviceHwl(camera_id,
273                                                     &camera_device_hwl);
274   if (res != OK) {
275     ALOGE("%s: Creating CameraProviderHwl failed: %s(%d)", __FUNCTION__,
276           strerror(-res), res);
277     return res;
278   }
279 
280   *device = CameraDevice::Create(
281       std::move(camera_device_hwl), camera_allocator_hwl_.get());
282   if (*device == nullptr) {
283     return NO_INIT;
284   }
285 
286   return OK;
287 }
288 
CreateHwl(std::unique_ptr<CameraProviderHwl> * camera_provider_hwl)289 status_t CameraProvider::CreateHwl(
290     std::unique_ptr<CameraProviderHwl>* camera_provider_hwl) {
291   ATRACE_CALL();
292 #if GCH_HWL_USE_DLOPEN
293   CreateCameraProviderHwl_t create_hwl;
294 
295   ALOGI("%s:Loading %s library", __FUNCTION__, kCameraHwlLib.data());
296   hwl_lib_handle_ = dlopen(kCameraHwlLib.data(), RTLD_NOW);
297 
298   if (hwl_lib_handle_ == nullptr) {
299     ALOGE("HWL loading %s failed due to error: %s", kCameraHwlLib.data(),
300           dlerror());
301     return NO_INIT;
302   }
303 
304   create_hwl = (CreateCameraProviderHwl_t)dlsym(hwl_lib_handle_,
305                                                 "CreateCameraProviderHwl");
306   if (create_hwl == nullptr) {
307     ALOGE("%s: dlsym failed (%s).", __FUNCTION__, kCameraHwlLib.data());
308     dlclose(hwl_lib_handle_);
309     hwl_lib_handle_ = nullptr;
310     return NO_INIT;
311   }
312 
313   // Create the HWL camera provider
314   camera_provider_hwl->reset(create_hwl());
315 #else
316   camera_provider_hwl->reset(CreateCameraProviderHwl());
317 #endif
318 
319   if (*camera_provider_hwl == nullptr) {
320     ALOGE("Error! Creating CameraProviderHwl failed");
321     return UNKNOWN_ERROR;
322   }
323 
324   return OK;
325 }
326 
NotifyDeviceStateChange(google_camera_hal::DeviceState device_state)327 status_t CameraProvider::NotifyDeviceStateChange(
328     google_camera_hal::DeviceState device_state) {
329   if (camera_provider_hwl_ == nullptr) {
330     ALOGE("%s: null provider hwl", __FUNCTION__);
331     return NO_INIT;
332   }
333   camera_provider_hwl_->NotifyDeviceStateChange(device_state);
334   return OK;
335 }
336 }  // namespace google_camera_hal
337 }  // namespace android
338