1 /*
2 * Copyright (C) 2022 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_AidlCameraProvider"
18 // #define LOG_NDEBUG 0
19 #include "aidl_camera_provider.h"
20
21 #include <log/log.h>
22
23 #include <regex>
24
25 #include "aidl_camera_device.h"
26 #include "aidl_utils.h"
27 #include "camera_device.h"
28
29 namespace android {
30 namespace hardware {
31 namespace camera {
32 namespace provider {
33 namespace implementation {
34
35 namespace aidl_utils = ::android::hardware::camera::implementation::aidl_utils;
36
37 using aidl::android::hardware::camera::common::CameraDeviceStatus;
38 using aidl::android::hardware::camera::common::Status;
39 using aidl::android::hardware::camera::common::TorchModeStatus;
40 using aidl::android::hardware::camera::common::VendorTagSection;
41 using ::android::google_camera_hal::CameraDevice;
42
43 const std::string AidlCameraProvider::kProviderName = "internal";
44 // "device@<version>/internal/<id>"
45 const std::regex AidlCameraProvider::kDeviceNameRegex(
46 "device@([0-9]+\\.[0-9]+)/internal/(.+)");
47
Create()48 std::shared_ptr<AidlCameraProvider> AidlCameraProvider::Create() {
49 std::shared_ptr<AidlCameraProvider> provider =
50 ndk::SharedRefBase::make<AidlCameraProvider>();
51
52 status_t res = provider->Initialize();
53 if (res != OK) {
54 ALOGE("%s: Initializing AidlCameraProvider failed: %s(%d)", __FUNCTION__,
55 strerror(-res), res);
56 return nullptr;
57 }
58
59 return provider;
60 }
61
Initialize()62 status_t AidlCameraProvider::Initialize() {
63 google_camera_provider_ = CameraProvider::Create();
64 if (google_camera_provider_ == nullptr) {
65 ALOGE("%s: Creating CameraProvider failed.", __FUNCTION__);
66 return NO_INIT;
67 }
68
69 camera_provider_callback_ = {
70 .camera_device_status_change = google_camera_hal::CameraDeviceStatusChangeFunc(
71 [this](std::string camera_id,
72 google_camera_hal::CameraDeviceStatus new_status) {
73 if (callbacks_ == nullptr) {
74 ALOGE("%s: callbacks_ is null", __FUNCTION__);
75 return;
76 }
77 CameraDeviceStatus aidl_camera_device_status;
78 status_t res = aidl_utils::ConvertToAidlCameraDeviceStatus(
79 new_status, &aidl_camera_device_status);
80 if (res != OK) {
81 ALOGE(
82 "%s: Converting to aidl camera device status failed: %s(%d)",
83 __FUNCTION__, strerror(-res), res);
84 return;
85 }
86
87 std::unique_lock<std::mutex> lock(callbacks_lock_);
88 auto aidl_res = callbacks_->cameraDeviceStatusChange(
89 "device@" +
90 device::implementation::AidlCameraDevice::kDeviceVersion +
91 "/" + kProviderName + "/" + camera_id,
92 aidl_camera_device_status);
93 if (!aidl_res.isOk()) {
94 ALOGE("%s: device status change transaction error: %s",
95 __FUNCTION__, aidl_res.getMessage());
96 return;
97 }
98 }),
99 .physical_camera_device_status_change =
100 google_camera_hal::PhysicalCameraDeviceStatusChangeFunc(
101 [this](std::string camera_id, std::string physical_camera_id,
102 google_camera_hal::CameraDeviceStatus 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 aidl_camera_device_status;
122 status_t res = aidl_utils::ConvertToAidlCameraDeviceStatus(
123 new_status, &aidl_camera_device_status);
124 if (res != OK) {
125 ALOGE(
126 "%s: Converting to aidl camera device status failed: "
127 "%s(%d)",
128 __FUNCTION__, strerror(-res), res);
129 return;
130 }
131
132 std::unique_lock<std::mutex> lock(callbacks_lock_);
133 auto aidl_res = callbacks_->physicalCameraDeviceStatusChange(
134 "device@" +
135 device::implementation::AidlCameraDevice::kDeviceVersion +
136 "/" + kProviderName + "/" + camera_id,
137 physical_camera_id, aidl_camera_device_status);
138 if (!aidl_res.isOk()) {
139 ALOGE(
140 "%s: physical camera status change transaction error: %s",
141 __FUNCTION__, aidl_res.getMessage());
142 return;
143 }
144 }),
145 .torch_mode_status_change = google_camera_hal::TorchModeStatusChangeFunc(
146 [this](std::string camera_id,
147 google_camera_hal::TorchModeStatus new_status) {
148 if (callbacks_ == nullptr) {
149 ALOGE("%s: callbacks_ is null", __FUNCTION__);
150 return;
151 }
152
153 TorchModeStatus aidl_torch_status;
154 status_t res = aidl_utils::ConvertToAidlTorchModeStatus(
155 new_status, &aidl_torch_status);
156 if (res != OK) {
157 ALOGE("%s: Converting to aidl torch status failed: %s(%d)",
158 __FUNCTION__, strerror(-res), res);
159 return;
160 }
161
162 std::unique_lock<std::mutex> lock(callbacks_lock_);
163 auto aidl_res = callbacks_->torchModeStatusChange(
164 "device@" +
165 device::implementation::AidlCameraDevice::kDeviceVersion +
166 "/" + kProviderName + "/" + camera_id,
167 aidl_torch_status);
168 if (!aidl_res.isOk()) {
169 ALOGE("%s: torch status change transaction error: %s",
170 __FUNCTION__, aidl_res.getMessage());
171 return;
172 }
173 }),
174 };
175
176 google_camera_provider_->SetCallback(&camera_provider_callback_);
177 // purge pending malloc pages after initialization
178 mallopt(M_PURGE, 0);
179 return OK;
180 }
181
setCallback(const std::shared_ptr<ICameraProviderCallback> & callback)182 ScopedAStatus AidlCameraProvider::setCallback(
183 const std::shared_ptr<ICameraProviderCallback>& callback) {
184 if (callback == nullptr) {
185 ALOGE("AidlCameraProvider::setCallback() called with nullptr");
186 return ScopedAStatus::fromServiceSpecificError(
187 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
188 }
189
190 {
191 std::unique_lock<std::mutex> lock(callbacks_lock_);
192 callbacks_ = callback;
193 }
194 google_camera_provider_->TriggerDeferredCallbacks();
195 return ScopedAStatus::ok();
196 }
197
getVendorTags(std::vector<VendorTagSection> * vts)198 ScopedAStatus AidlCameraProvider::getVendorTags(
199 std::vector<VendorTagSection>* vts) {
200 if (vts == nullptr) {
201 return ScopedAStatus::fromServiceSpecificError(
202 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
203 }
204 vts->clear();
205 std::vector<google_camera_hal::VendorTagSection> hal_vendor_tag_sections;
206
207 status_t res =
208 google_camera_provider_->GetVendorTags(&hal_vendor_tag_sections);
209 if (res != OK) {
210 ALOGE("%s: Getting vendor tags failed: %s(%d)", __FUNCTION__,
211 strerror(-res), res);
212 return ScopedAStatus::fromServiceSpecificError(
213 static_cast<int32_t>(Status::INTERNAL_ERROR));
214 }
215
216 res = aidl_utils::ConvertToAidlVendorTagSections(hal_vendor_tag_sections, vts);
217 if (res != OK) {
218 ALOGE("%s: Converting to aidl vendor tags failed: %s(%d)", __FUNCTION__,
219 strerror(-res), res);
220 return ScopedAStatus::fromServiceSpecificError(
221 static_cast<int32_t>(Status::INTERNAL_ERROR));
222 }
223 return ScopedAStatus::ok();
224 }
225
getCameraIdList(std::vector<std::string> * camera_ids_ret)226 ScopedAStatus AidlCameraProvider::getCameraIdList(
227 std::vector<std::string>* camera_ids_ret) {
228 if (camera_ids_ret == nullptr) {
229 return ScopedAStatus::fromServiceSpecificError(
230 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
231 }
232 camera_ids_ret->clear();
233 std::vector<uint32_t> camera_ids;
234 status_t res = google_camera_provider_->GetCameraIdList(&camera_ids);
235 if (res != OK) {
236 ALOGE("%s: Getting camera ID list failed: %s(%d)", __FUNCTION__,
237 strerror(-res), res);
238 return ScopedAStatus::fromServiceSpecificError(
239 static_cast<int32_t>(Status::INTERNAL_ERROR));
240 }
241
242 camera_ids_ret->resize(camera_ids.size());
243 for (uint32_t i = 0; i < camera_ids_ret->size(); i++) {
244 // camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
245 (*camera_ids_ret)[i] =
246 "device@" + device::implementation::AidlCameraDevice::kDeviceVersion +
247 "/" + kProviderName + "/" + std::to_string(camera_ids[i]);
248 }
249 #ifdef __ANDROID_APEX__
250 if (!camera_device_initialized_ && available_camera_ids_.empty()) {
251 available_camera_ids_ =
252 std::unordered_set<uint32_t>(camera_ids.begin(), camera_ids.end());
253 }
254 #endif
255 return ScopedAStatus::ok();
256 }
257
getConcurrentCameraIds(std::vector<ConcurrentCameraIdCombination> * aidl_camera_id_combinations)258 ScopedAStatus AidlCameraProvider::getConcurrentCameraIds(
259 std::vector<ConcurrentCameraIdCombination>* aidl_camera_id_combinations) {
260 if (aidl_camera_id_combinations == nullptr) {
261 return ScopedAStatus::fromServiceSpecificError(
262 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
263 }
264 aidl_camera_id_combinations->clear();
265 std::vector<std::unordered_set<uint32_t>> camera_id_combinations;
266 status_t res = google_camera_provider_->GetConcurrentStreamingCameraIds(
267 &camera_id_combinations);
268 if (res != OK) {
269 ALOGE(
270 "%s: Getting the combinations of concurrent streaming camera ids "
271 "failed: %s(%d)",
272 __FUNCTION__, strerror(-res), res);
273 return ScopedAStatus::fromServiceSpecificError(
274 static_cast<int32_t>(Status::INTERNAL_ERROR));
275 }
276 aidl_camera_id_combinations->resize(camera_id_combinations.size());
277 int i = 0;
278 for (auto& combination : camera_id_combinations) {
279 std::vector<std::string> aidl_combination(combination.size());
280 int c = 0;
281 for (auto& camera_id : combination) {
282 aidl_combination[c] = std::to_string(camera_id);
283 c++;
284 }
285 (*aidl_camera_id_combinations)[i].combination = aidl_combination;
286 i++;
287 }
288 return ScopedAStatus::ok();
289 }
290
isConcurrentStreamCombinationSupported(const std::vector<CameraIdAndStreamCombination> & configs,bool * supported)291 ScopedAStatus AidlCameraProvider::isConcurrentStreamCombinationSupported(
292 const std::vector<CameraIdAndStreamCombination>& configs, bool* supported) {
293 *supported = false;
294 std::vector<google_camera_hal::CameraIdAndStreamConfiguration>
295 devices_stream_configs(configs.size());
296 status_t res = OK;
297 size_t c = 0;
298 std::vector<CameraIdAndStreamCombination> configsWithOverriddenSensorPixelModes =
299 configs;
300 for (auto& config : configsWithOverriddenSensorPixelModes) {
301 aidl_utils::FixSensorPixelModesInStreamConfig(&config.streamConfiguration);
302 }
303
304 for (auto& config : configsWithOverriddenSensorPixelModes) {
305 res = aidl_utils::ConvertToHalStreamConfig(
306 config.streamConfiguration,
307 &devices_stream_configs[c].stream_configuration);
308 if (res != OK) {
309 ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
310 return ScopedAStatus::fromServiceSpecificError(
311 static_cast<int32_t>(Status::INTERNAL_ERROR));
312 }
313 uint32_t camera_id = atoi(config.cameraId.c_str());
314 devices_stream_configs[c].camera_id = camera_id;
315 c++;
316 }
317 res = google_camera_provider_->IsConcurrentStreamCombinationSupported(
318 devices_stream_configs, supported);
319 if (res != OK) {
320 ALOGE("%s: IsConcurrentStreamCombinationSupported failed", __FUNCTION__);
321 return ScopedAStatus::fromServiceSpecificError(
322 static_cast<int32_t>(Status::INTERNAL_ERROR));
323 }
324 return ScopedAStatus::ok();
325 }
326
ParseDeviceName(const std::string & device_name,std::string * device_version,std::string * camera_id)327 bool AidlCameraProvider::ParseDeviceName(const std::string& device_name,
328 std::string* device_version,
329 std::string* camera_id) {
330 std::string device_name_std(device_name.c_str());
331 std::smatch sm;
332
333 if (std::regex_match(device_name_std, sm,
334 AidlCameraProvider::kDeviceNameRegex)) {
335 if (device_version != nullptr) {
336 *device_version = sm[1];
337 }
338 if (camera_id != nullptr) {
339 *camera_id = sm[2];
340 }
341 return true;
342 }
343 return false;
344 }
345
getCameraDeviceInterface(const std::string & camera_device_name,std::shared_ptr<ICameraDevice> * device)346 ScopedAStatus AidlCameraProvider::getCameraDeviceInterface(
347 const std::string& camera_device_name,
348 std::shared_ptr<ICameraDevice>* device) {
349 std::unique_ptr<CameraDevice> google_camera_device;
350 if (device == nullptr) {
351 ALOGE("%s: device is nullptr. ", __FUNCTION__);
352 return ScopedAStatus::fromServiceSpecificError(
353 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
354 }
355
356 // Parse camera_device_name.
357 std::string camera_id, device_version;
358
359 bool match = ParseDeviceName(camera_device_name, &device_version, &camera_id);
360 if (!match) {
361 ALOGE("%s: Device name parse fail. ", __FUNCTION__);
362 return ScopedAStatus::fromServiceSpecificError(
363 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
364 }
365
366 int camera_id_int = atoi(camera_id.c_str());
367 status_t res = google_camera_provider_->CreateCameraDevice(
368 camera_id_int, &google_camera_device);
369 if (res != OK) {
370 ALOGE("%s: Creating CameraDevice failed: %s(%d)", __FUNCTION__,
371 strerror(-res), res);
372 return aidl_utils::ConvertToAidlReturn(res);
373 }
374
375 *device = device::implementation::AidlCameraDevice::Create(
376 std::move(google_camera_device));
377 if (*device == nullptr) {
378 ALOGE("%s: Creating AidlCameraDevice failed", __FUNCTION__);
379 return ScopedAStatus::fromServiceSpecificError(
380 static_cast<int32_t>(Status::INTERNAL_ERROR));
381 }
382
383 #ifdef __ANDROID_APEX__
384 available_camera_ids_.erase(camera_id_int);
385 if (!camera_device_initialized_ && available_camera_ids_.empty()) {
386 camera_device_initialized_ = true;
387
388 std::string ready_property_name = "vendor.camera.hal.ready.count";
389 int ready_count = property_get_int32(ready_property_name.c_str(), 0);
390 property_set(ready_property_name.c_str(),
391 std::to_string(++ready_count).c_str());
392 ALOGI(
393 "AidlCameraProvider::getCameraDeviceInterface() first time ready "
394 "count: %d ",
395 ready_count);
396 }
397 #endif
398 return ScopedAStatus::ok();
399 }
400
notifyDeviceStateChange(int64_t new_state)401 ScopedAStatus AidlCameraProvider::notifyDeviceStateChange(int64_t new_state) {
402 google_camera_hal::DeviceState device_state =
403 google_camera_hal::DeviceState::kNormal;
404 ::android::hardware::camera::implementation::aidl_utils::ConvertToHalDeviceState(
405 new_state, device_state);
406 google_camera_provider_->NotifyDeviceStateChange(device_state);
407 return ScopedAStatus::ok();
408 }
409
410 } // namespace implementation
411 } // namespace provider
412 } // namespace camera
413 } // namespace hardware
414 } // namespace android
415