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