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