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