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