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 bool first_time = false;
191 {
192 std::unique_lock<std::mutex> lock(callbacks_lock_);
193 first_time = callbacks_ == nullptr;
194 callbacks_ = callback;
195 }
196 google_camera_provider_->TriggerDeferredCallbacks();
197 #ifdef __ANDROID_APEX__
198 if (first_time) {
199 std::string ready_property_name = "vendor.camera.hal.ready.count";
200 int ready_count = property_get_int32(ready_property_name.c_str(), 0);
201 property_set(ready_property_name.c_str(),
202 std::to_string(++ready_count).c_str());
203 ALOGI("AidlCameraProvider::setCallback() first time ready count: %d ",
204 ready_count);
205 }
206 #endif
207 return ScopedAStatus::ok();
208 }
209
getVendorTags(std::vector<VendorTagSection> * vts)210 ScopedAStatus AidlCameraProvider::getVendorTags(
211 std::vector<VendorTagSection>* vts) {
212 if (vts == nullptr) {
213 return ScopedAStatus::fromServiceSpecificError(
214 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
215 }
216 vts->clear();
217 std::vector<google_camera_hal::VendorTagSection> hal_vendor_tag_sections;
218
219 status_t res =
220 google_camera_provider_->GetVendorTags(&hal_vendor_tag_sections);
221 if (res != OK) {
222 ALOGE("%s: Getting vendor tags failed: %s(%d)", __FUNCTION__,
223 strerror(-res), res);
224 return ScopedAStatus::fromServiceSpecificError(
225 static_cast<int32_t>(Status::INTERNAL_ERROR));
226 }
227
228 res = aidl_utils::ConvertToAidlVendorTagSections(hal_vendor_tag_sections, vts);
229 if (res != OK) {
230 ALOGE("%s: Converting to aidl vendor tags failed: %s(%d)", __FUNCTION__,
231 strerror(-res), res);
232 return ScopedAStatus::fromServiceSpecificError(
233 static_cast<int32_t>(Status::INTERNAL_ERROR));
234 }
235 return ScopedAStatus::ok();
236 }
237
getCameraIdList(std::vector<std::string> * camera_ids_ret)238 ScopedAStatus AidlCameraProvider::getCameraIdList(
239 std::vector<std::string>* camera_ids_ret) {
240 if (camera_ids_ret == nullptr) {
241 return ScopedAStatus::fromServiceSpecificError(
242 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
243 }
244 camera_ids_ret->clear();
245 std::vector<uint32_t> camera_ids;
246 status_t res = google_camera_provider_->GetCameraIdList(&camera_ids);
247 if (res != OK) {
248 ALOGE("%s: Getting camera ID list failed: %s(%d)", __FUNCTION__,
249 strerror(-res), res);
250 return ScopedAStatus::fromServiceSpecificError(
251 static_cast<int32_t>(Status::INTERNAL_ERROR));
252 }
253
254 camera_ids_ret->resize(camera_ids.size());
255 for (uint32_t i = 0; i < camera_ids_ret->size(); i++) {
256 // camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
257 (*camera_ids_ret)[i] =
258 "device@" + device::implementation::AidlCameraDevice::kDeviceVersion +
259 "/" + kProviderName + "/" + std::to_string(camera_ids[i]);
260 }
261 return ScopedAStatus::ok();
262 }
263
getConcurrentCameraIds(std::vector<ConcurrentCameraIdCombination> * aidl_camera_id_combinations)264 ScopedAStatus AidlCameraProvider::getConcurrentCameraIds(
265 std::vector<ConcurrentCameraIdCombination>* aidl_camera_id_combinations) {
266 if (aidl_camera_id_combinations == nullptr) {
267 return ScopedAStatus::fromServiceSpecificError(
268 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
269 }
270 aidl_camera_id_combinations->clear();
271 std::vector<std::unordered_set<uint32_t>> camera_id_combinations;
272 status_t res = google_camera_provider_->GetConcurrentStreamingCameraIds(
273 &camera_id_combinations);
274 if (res != OK) {
275 ALOGE(
276 "%s: Getting the combinations of concurrent streaming camera ids "
277 "failed: %s(%d)",
278 __FUNCTION__, strerror(-res), res);
279 return ScopedAStatus::fromServiceSpecificError(
280 static_cast<int32_t>(Status::INTERNAL_ERROR));
281 }
282 aidl_camera_id_combinations->resize(camera_id_combinations.size());
283 int i = 0;
284 for (auto& combination : camera_id_combinations) {
285 std::vector<std::string> aidl_combination(combination.size());
286 int c = 0;
287 for (auto& camera_id : combination) {
288 aidl_combination[c] = std::to_string(camera_id);
289 c++;
290 }
291 (*aidl_camera_id_combinations)[i].combination = aidl_combination;
292 i++;
293 }
294 return ScopedAStatus::ok();
295 }
296
isConcurrentStreamCombinationSupported(const std::vector<CameraIdAndStreamCombination> & configs,bool * supported)297 ScopedAStatus AidlCameraProvider::isConcurrentStreamCombinationSupported(
298 const std::vector<CameraIdAndStreamCombination>& configs, bool* supported) {
299 *supported = false;
300 std::vector<google_camera_hal::CameraIdAndStreamConfiguration>
301 devices_stream_configs(configs.size());
302 status_t res = OK;
303 size_t c = 0;
304 std::vector<CameraIdAndStreamCombination> configsWithOverriddenSensorPixelModes =
305 configs;
306 for (auto& config : configsWithOverriddenSensorPixelModes) {
307 aidl_utils::FixSensorPixelModesInStreamConfig(&config.streamConfiguration);
308 }
309
310 for (auto& config : configsWithOverriddenSensorPixelModes) {
311 res = aidl_utils::ConvertToHalStreamConfig(
312 config.streamConfiguration,
313 &devices_stream_configs[c].stream_configuration);
314 if (res != OK) {
315 ALOGE("%s: ConverToHalStreamConfig failed", __FUNCTION__);
316 return ScopedAStatus::fromServiceSpecificError(
317 static_cast<int32_t>(Status::INTERNAL_ERROR));
318 }
319 uint32_t camera_id = atoi(config.cameraId.c_str());
320 devices_stream_configs[c].camera_id = camera_id;
321 c++;
322 }
323 res = google_camera_provider_->IsConcurrentStreamCombinationSupported(
324 devices_stream_configs, supported);
325 if (res != OK) {
326 ALOGE("%s: IsConcurrentStreamCombinationSupported failed", __FUNCTION__);
327 return ScopedAStatus::fromServiceSpecificError(
328 static_cast<int32_t>(Status::INTERNAL_ERROR));
329 }
330 return ScopedAStatus::ok();
331 }
332
ParseDeviceName(const std::string & device_name,std::string * device_version,std::string * camera_id)333 bool AidlCameraProvider::ParseDeviceName(const std::string& device_name,
334 std::string* device_version,
335 std::string* camera_id) {
336 std::string device_name_std(device_name.c_str());
337 std::smatch sm;
338
339 if (std::regex_match(device_name_std, sm,
340 AidlCameraProvider::kDeviceNameRegex)) {
341 if (device_version != nullptr) {
342 *device_version = sm[1];
343 }
344 if (camera_id != nullptr) {
345 *camera_id = sm[2];
346 }
347 return true;
348 }
349 return false;
350 }
351
getCameraDeviceInterface(const std::string & camera_device_name,std::shared_ptr<ICameraDevice> * device)352 ScopedAStatus AidlCameraProvider::getCameraDeviceInterface(
353 const std::string& camera_device_name,
354 std::shared_ptr<ICameraDevice>* device) {
355 std::unique_ptr<CameraDevice> google_camera_device;
356 if (device == nullptr) {
357 ALOGE("%s: device is nullptr. ", __FUNCTION__);
358 return ScopedAStatus::fromServiceSpecificError(
359 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
360 }
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 return ScopedAStatus::fromServiceSpecificError(
369 static_cast<int32_t>(Status::ILLEGAL_ARGUMENT));
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 return aidl_utils::ConvertToAidlReturn(res);
378 }
379
380 *device = device::implementation::AidlCameraDevice::Create(
381 std::move(google_camera_device));
382 if (*device == nullptr) {
383 ALOGE("%s: Creating AidlCameraDevice failed", __FUNCTION__);
384 return ScopedAStatus::fromServiceSpecificError(
385 static_cast<int32_t>(Status::INTERNAL_ERROR));
386 }
387 return ScopedAStatus::ok();
388 }
389
notifyDeviceStateChange(int64_t new_state)390 ScopedAStatus AidlCameraProvider::notifyDeviceStateChange(int64_t new_state) {
391 google_camera_hal::DeviceState device_state =
392 google_camera_hal::DeviceState::kNormal;
393 ::android::hardware::camera::implementation::aidl_utils::ConvertToHalDeviceState(
394 new_state, device_state);
395 google_camera_provider_->NotifyDeviceStateChange(device_state);
396 return ScopedAStatus::ok();
397 }
398
399 } // namespace implementation
400 } // namespace provider
401 } // namespace camera
402 } // namespace hardware
403 } // namespace android
404