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_TAG "GCH_HidlCameraProvider"
18 //#define LOG_NDEBUG 0
19 #include <log/log.h>
20 #include <regex>
21 
22 #include "camera_device.h"
23 #include "hidl_camera_device.h"
24 #include "hidl_camera_provider.h"
25 #include "hidl_utils.h"
26 
27 namespace android {
28 namespace hardware {
29 namespace camera {
30 namespace provider {
31 namespace V2_7 {
32 namespace implementation {
33 
34 namespace hidl_utils = ::android::hardware::camera::implementation::hidl_utils;
35 
36 using ::android::google_camera_hal::CameraDevice;
37 using ::android::hardware::Void;
38 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
39 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
40 using ::android::hardware::camera::common::V1_0::VendorTagSection;
41 
42 const std::string HidlCameraProvider::kProviderName = "internal";
43 // "device@<version>/internal/<id>"
44 const std::regex HidlCameraProvider::kDeviceNameRegex(
45     "device@([0-9]+\\.[0-9]+)/internal/(.+)");
46 
Create()47 android::sp<HidlCameraProvider> HidlCameraProvider::Create() {
48   android::sp<HidlCameraProvider> provider = new HidlCameraProvider();
49 
50   status_t res = provider->Initialize();
51   if (res != OK) {
52     ALOGE("%s: Initializing HidlCameraProvider failed: %s(%d)", __FUNCTION__,
53           strerror(-res), res);
54     return nullptr;
55   }
56 
57   return provider;
58 }
59 
Initialize()60 status_t HidlCameraProvider::Initialize() {
61   google_camera_provider_ = CameraProvider::Create();
62   if (google_camera_provider_ == nullptr) {
63     ALOGE("%s: Creating CameraProvider failed.", __FUNCTION__);
64     return NO_INIT;
65   }
66 
67   camera_provider_callback_ = {
68       .camera_device_status_change = google_camera_hal::CameraDeviceStatusChangeFunc(
69           [this](std::string camera_id,
70                  google_camera_hal::CameraDeviceStatus new_status) {
71             if (callbacks_ == nullptr) {
72               ALOGE("%s: callbacks_ is null", __FUNCTION__);
73               return;
74             }
75             CameraDeviceStatus hidl_camera_device_status;
76             status_t res = hidl_utils::ConvertToHidlCameraDeviceStatus(
77                 new_status, &hidl_camera_device_status);
78             if (res != OK) {
79               ALOGE(
80                   "%s: Converting to hidl camera device status failed: %s(%d)",
81                   __FUNCTION__, strerror(-res), res);
82               return;
83             }
84 
85             std::unique_lock<std::mutex> lock(callbacks_lock_);
86             callbacks_->cameraDeviceStatusChange(
87                 "device@" +
88                     device::V3_7::implementation::HidlCameraDevice::kDeviceVersion +
89                     "/" + kProviderName + "/" + camera_id,
90                 hidl_camera_device_status);
91           }),
92       .physical_camera_device_status_change = google_camera_hal::
93           PhysicalCameraDeviceStatusChangeFunc([this](
94                                                    std::string camera_id,
95                                                    std::string physical_camera_id,
96                                                    google_camera_hal::CameraDeviceStatus
97                                                        new_status) {
98             if (callbacks_ == nullptr) {
99               ALOGE("%s: callbacks_ is null", __FUNCTION__);
100               return;
101             }
102             auto castResult =
103                 provider::V2_6::ICameraProviderCallback::castFrom(callbacks_);
104             if (!castResult.isOk()) {
105               ALOGE("%s: callbacks_ cannot be casted to version 2.6",
106                     __FUNCTION__);
107               return;
108             }
109             sp<provider::V2_6::ICameraProviderCallback> callbacks_2_6_ =
110                 castResult;
111             if (callbacks_2_6_ == nullptr) {
112               ALOGE("%s: callbacks_2_6_ is null", __FUNCTION__);
113               return;
114             }
115 
116             CameraDeviceStatus hidl_camera_device_status;
117             status_t res = hidl_utils::ConvertToHidlCameraDeviceStatus(
118                 new_status, &hidl_camera_device_status);
119             if (res != OK) {
120               ALOGE(
121                   "%s: Converting to hidl camera device status failed: %s(%d)",
122                   __FUNCTION__, strerror(-res), res);
123               return;
124             }
125 
126             std::unique_lock<std::mutex> lock(callbacks_lock_);
127             callbacks_2_6_->physicalCameraDeviceStatusChange(
128                 "device@" +
129                     device::V3_7::implementation::HidlCameraDevice::kDeviceVersion +
130                     "/" + kProviderName + "/" + camera_id,
131                 physical_camera_id, hidl_camera_device_status);
132           }),
133       .torch_mode_status_change = google_camera_hal::TorchModeStatusChangeFunc(
134           [this](std::string camera_id,
135                  google_camera_hal::TorchModeStatus new_status) {
136             if (callbacks_ == nullptr) {
137               ALOGE("%s: callbacks_ is null", __FUNCTION__);
138               return;
139             }
140 
141             TorchModeStatus hidl_torch_status;
142             status_t res = hidl_utils::ConvertToHidlTorchModeStatus(
143                 new_status, &hidl_torch_status);
144             if (res != OK) {
145               ALOGE("%s: Converting to hidl torch status failed: %s(%d)",
146                     __FUNCTION__, strerror(-res), res);
147               return;
148             }
149 
150             std::unique_lock<std::mutex> lock(callbacks_lock_);
151             callbacks_->torchModeStatusChange(
152                 "device@" +
153                     device::V3_7::implementation::HidlCameraDevice::kDeviceVersion +
154                     "/" + kProviderName + "/" + camera_id,
155                 hidl_torch_status);
156           }),
157   };
158 
159   google_camera_provider_->SetCallback(&camera_provider_callback_);
160   // purge pending malloc pages after initialization
161   mallopt(M_PURGE, 0);
162   return OK;
163 }
164 
setCallback(const sp<ICameraProviderCallback> & callback)165 Return<Status> HidlCameraProvider::setCallback(
166     const sp<ICameraProviderCallback>& callback) {
167   bool first_time = false;
168   {
169     std::unique_lock<std::mutex> lock(callbacks_lock_);
170     first_time = callbacks_ == nullptr;
171     callbacks_ = callback;
172   }
173   google_camera_provider_->TriggerDeferredCallbacks();
174 #ifdef __ANDROID_APEX__
175   if (first_time) {
176     std::string ready_property_name = "vendor.camera.hal.ready.count";
177     int ready_count = property_get_int32(ready_property_name.c_str(), 0);
178     property_set(ready_property_name.c_str(),
179                  std::to_string(++ready_count).c_str());
180     ALOGI("HidlCameraProvider::setCallback() first time ready count: %d ",
181           ready_count);
182   }
183 #endif
184   return Status::OK;
185 }
186 
getVendorTags(getVendorTags_cb _hidl_cb)187 Return<void> HidlCameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
188   hidl_vec<VendorTagSection> hidl_vendor_tag_sections;
189   std::vector<google_camera_hal::VendorTagSection> hal_vendor_tag_sections;
190 
191   status_t res =
192       google_camera_provider_->GetVendorTags(&hal_vendor_tag_sections);
193   if (res != OK) {
194     ALOGE("%s: Getting vendor tags failed: %s(%d)", __FUNCTION__,
195           strerror(-res), res);
196     _hidl_cb(Status::INTERNAL_ERROR, hidl_vendor_tag_sections);
197     return Void();
198   }
199 
200   res = hidl_utils::ConvertToHidlVendorTagSections(hal_vendor_tag_sections,
201                                                    &hidl_vendor_tag_sections);
202   if (res != OK) {
203     ALOGE("%s: Converting to hidl vendor tags failed: %s(%d)", __FUNCTION__,
204           strerror(-res), res);
205     _hidl_cb(Status::INTERNAL_ERROR, hidl_vendor_tag_sections);
206     return Void();
207   }
208 
209   _hidl_cb(Status::OK, hidl_vendor_tag_sections);
210   return Void();
211 }
212 
getCameraIdList(getCameraIdList_cb _hidl_cb)213 Return<void> HidlCameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
214   std::vector<uint32_t> camera_ids;
215   hidl_vec<hidl_string> hidl_camera_ids;
216   status_t res = google_camera_provider_->GetCameraIdList(&camera_ids);
217   if (res != OK) {
218     ALOGE("%s: Getting camera ID list failed: %s(%d)", __FUNCTION__,
219           strerror(-res), res);
220     _hidl_cb(Status::INTERNAL_ERROR, hidl_camera_ids);
221     return Void();
222   }
223 
224   hidl_camera_ids.resize(camera_ids.size());
225   for (uint32_t i = 0; i < hidl_camera_ids.size(); i++) {
226     // camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
227     hidl_camera_ids[i] =
228         "device@" +
229         device::V3_7::implementation::HidlCameraDevice::kDeviceVersion + "/" +
230         kProviderName + "/" + std::to_string(camera_ids[i]);
231   }
232 
233   _hidl_cb(Status::OK, hidl_camera_ids);
234   return Void();
235 }
236 
getConcurrentStreamingCameraIds(getConcurrentStreamingCameraIds_cb _hidl_cb)237 Return<void> HidlCameraProvider::getConcurrentStreamingCameraIds(
238     getConcurrentStreamingCameraIds_cb _hidl_cb) {
239   hidl_vec<hidl_vec<hidl_string>> hidl_camera_id_combinations;
240   std::vector<std::unordered_set<uint32_t>> camera_id_combinations;
241   status_t res = google_camera_provider_->GetConcurrentStreamingCameraIds(
242       &camera_id_combinations);
243   if (res != OK) {
244     ALOGE(
245         "%s: Getting the combinations of concurrent streaming camera ids "
246         "failed: %s(%d)",
247         __FUNCTION__, strerror(-res), res);
248     _hidl_cb(Status::INTERNAL_ERROR, hidl_camera_id_combinations);
249     return Void();
250   }
251   hidl_camera_id_combinations.resize(camera_id_combinations.size());
252   int i = 0;
253   for (auto& combination : camera_id_combinations) {
254     hidl_vec<hidl_string> hidl_combination(combination.size());
255     int c = 0;
256     for (auto& camera_id : combination) {
257       hidl_combination[c] = std::to_string(camera_id);
258       c++;
259     }
260     hidl_camera_id_combinations[i] = hidl_combination;
261     i++;
262   }
263   _hidl_cb(Status::OK, hidl_camera_id_combinations);
264   return Void();
265 }
266 
isConcurrentStreamCombinationSupported(const hidl_vec<provider::V2_6::CameraIdAndStreamCombination> & configs,isConcurrentStreamCombinationSupported_cb _hidl_cb)267 Return<void> HidlCameraProvider::isConcurrentStreamCombinationSupported(
268     const hidl_vec<provider::V2_6::CameraIdAndStreamCombination>& configs,
269     isConcurrentStreamCombinationSupported_cb _hidl_cb) {
270   hidl_vec<CameraIdAndStreamCombination> configs2_7;
271   configs2_7.resize(configs.size());
272   for (size_t i = 0; i < configs.size(); i++) {
273     configs2_7[i].cameraId = configs[i].cameraId;
274 
275     hidl_utils::ConvertStreamConfigurationV34ToV37(
276         configs[i].streamConfiguration, &configs2_7[i].streamConfiguration);
277   }
278 
279   return isConcurrentStreamCombinationSupported_2_7(configs2_7, _hidl_cb);
280 }
281 
isConcurrentStreamCombinationSupported_2_7(const hidl_vec<CameraIdAndStreamCombination> & configs,isConcurrentStreamCombinationSupported_cb _hidl_cb)282 Return<void> HidlCameraProvider::isConcurrentStreamCombinationSupported_2_7(
283     const hidl_vec<CameraIdAndStreamCombination>& configs,
284     isConcurrentStreamCombinationSupported_cb _hidl_cb) {
285   std::vector<google_camera_hal::CameraIdAndStreamConfiguration>
286       devices_stream_configs(configs.size());
287   status_t res = OK;
288   size_t c = 0;
289   for (auto& config : configs) {
290     res = hidl_utils::ConverToHalStreamConfig(
291         config.streamConfiguration,
292         &devices_stream_configs[c].stream_configuration);
293     if (res != OK) {
294       ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
295       _hidl_cb(Status::INTERNAL_ERROR, false);
296       return Void();
297     }
298     uint32_t camera_id = atoi(config.cameraId.c_str());
299     devices_stream_configs[c].camera_id = camera_id;
300     c++;
301   }
302   bool is_supported = false;
303   res = google_camera_provider_->IsConcurrentStreamCombinationSupported(
304       devices_stream_configs, &is_supported);
305   if (res != OK) {
306     ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
307     _hidl_cb(Status::INTERNAL_ERROR, false);
308     return Void();
309   }
310   _hidl_cb(Status::OK, is_supported);
311   return Void();
312 }
313 
isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb)314 Return<void> HidlCameraProvider::isSetTorchModeSupported(
315     isSetTorchModeSupported_cb _hidl_cb) {
316   bool is_supported = google_camera_provider_->IsSetTorchModeSupported();
317   _hidl_cb(Status::OK, is_supported);
318   return Void();
319 }
320 
getCameraDeviceInterface_V1_x(const hidl_string &,getCameraDeviceInterface_V1_x_cb _hidl_cb)321 Return<void> HidlCameraProvider::getCameraDeviceInterface_V1_x(
322     const hidl_string& /*cameraDeviceName*/,
323     getCameraDeviceInterface_V1_x_cb _hidl_cb) {
324   _hidl_cb(Status::OPERATION_NOT_SUPPORTED, nullptr);
325   return Void();
326 }
327 
ParseDeviceName(const hidl_string & device_name,std::string * device_version,std::string * camera_id)328 bool HidlCameraProvider::ParseDeviceName(const hidl_string& device_name,
329                                          std::string* device_version,
330                                          std::string* camera_id) {
331   std::string device_name_std(device_name.c_str());
332   std::smatch sm;
333 
334   if (std::regex_match(device_name_std, sm,
335                        HidlCameraProvider::kDeviceNameRegex)) {
336     if (device_version != nullptr) {
337       *device_version = sm[1];
338     }
339     if (camera_id != nullptr) {
340       *camera_id = sm[2];
341     }
342     return true;
343   }
344   return false;
345 }
346 
getCameraDeviceInterface_V3_x(const hidl_string & camera_device_name,getCameraDeviceInterface_V3_x_cb _hidl_cb)347 Return<void> HidlCameraProvider::getCameraDeviceInterface_V3_x(
348     const hidl_string& camera_device_name,
349     getCameraDeviceInterface_V3_x_cb _hidl_cb) {
350   std::unique_ptr<CameraDevice> google_camera_device;
351 
352   // Parse camera_device_name.
353   std::string camera_id, device_version;
354 
355   bool match = ParseDeviceName(camera_device_name, &device_version, &camera_id);
356   if (!match) {
357     ALOGE("%s: Device name parse fail. ", __FUNCTION__);
358     _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
359     return Void();
360   }
361 
362   status_t res = google_camera_provider_->CreateCameraDevice(
363       atoi(camera_id.c_str()), &google_camera_device);
364   if (res != OK) {
365     ALOGE("%s: Creating CameraDevice failed: %s(%d)", __FUNCTION__,
366           strerror(-res), res);
367     _hidl_cb(hidl_utils::ConvertToHidlStatus(res), nullptr);
368     return Void();
369   }
370 
371   auto hidl_camera_device =
372       device::V3_7::implementation::HidlCameraDevice::Create(
373           std::move(google_camera_device));
374   if (hidl_camera_device == nullptr) {
375     ALOGE("%s: Creating HidlCameraDevice failed", __FUNCTION__);
376     _hidl_cb(Status::INTERNAL_ERROR, nullptr);
377     return Void();
378   }
379 
380   _hidl_cb(Status::OK, hidl_camera_device.release());
381   return Void();
382 }
383 
notifyDeviceStateChange(hardware::hidl_bitfield<DeviceState> new_state)384 Return<void> HidlCameraProvider::notifyDeviceStateChange(
385     hardware::hidl_bitfield<DeviceState> new_state) {
386   google_camera_hal::DeviceState device_state =
387       google_camera_hal::DeviceState::kNormal;
388   ::android::hardware::camera::implementation::hidl_utils::ConvertToHalDeviceState(
389       new_state, device_state);
390   google_camera_provider_->NotifyDeviceStateChange(device_state);
391   return Void();
392 }
393 
394 }  // namespace implementation
395 }  // namespace V2_7
396 }  // namespace provider
397 }  // namespace camera
398 }  // namespace hardware
399 }  // namespace android
400