• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_NDEBUG 0
18 #define LOG_TAG "GCH_CameraDevice"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <dlfcn.h>
21 #include <log/log.h>
22 #include <sys/stat.h>
23 #include <utils/Trace.h>
24 
25 #include "camera_device.h"
26 #include "vendor_tags.h"
27 
28 namespace android {
29 namespace google_camera_hal {
30 
31 // HAL external capture session library path
32 #if defined(_LP64)
33 constexpr char kExternalCaptureSessionDir[] =
34     "/vendor/lib64/camera/capture_sessions/";
35 #else  // defined(_LP64)
36 constexpr char kExternalCaptureSessionDir[] =
37     "/vendor/lib/camera/capture_sessions/";
38 #endif
39 
Create(std::unique_ptr<CameraDeviceHwl> camera_device_hwl,CameraBufferAllocatorHwl * camera_allocator_hwl)40 std::unique_ptr<CameraDevice> CameraDevice::Create(
41     std::unique_ptr<CameraDeviceHwl> camera_device_hwl,
42     CameraBufferAllocatorHwl* camera_allocator_hwl) {
43   ATRACE_CALL();
44   auto device = std::unique_ptr<CameraDevice>(new CameraDevice());
45 
46   if (device == nullptr) {
47     ALOGE("%s: Creating CameraDevice failed.", __FUNCTION__);
48     return nullptr;
49   }
50 
51   status_t res =
52       device->Initialize(std::move(camera_device_hwl), camera_allocator_hwl);
53   if (res != OK) {
54     ALOGE("%s: Initializing CameraDevice failed: %s (%d).", __FUNCTION__,
55           strerror(-res), res);
56     return nullptr;
57   }
58 
59   ALOGI("%s: Created a camera device for public(%u)", __FUNCTION__,
60         device->GetPublicCameraId());
61 
62   return device;
63 }
64 
Initialize(std::unique_ptr<CameraDeviceHwl> camera_device_hwl,CameraBufferAllocatorHwl * camera_allocator_hwl)65 status_t CameraDevice::Initialize(
66     std::unique_ptr<CameraDeviceHwl> camera_device_hwl,
67     CameraBufferAllocatorHwl* camera_allocator_hwl) {
68   ATRACE_CALL();
69   if (camera_device_hwl == nullptr) {
70     ALOGE("%s: camera_device_hwl cannot be nullptr.", __FUNCTION__);
71     return BAD_VALUE;
72   }
73 
74   public_camera_id_ = camera_device_hwl->GetCameraId();
75   camera_device_hwl_ = std::move(camera_device_hwl);
76   camera_allocator_hwl_ = camera_allocator_hwl;
77   status_t res = LoadExternalCaptureSession();
78   if (res != OK) {
79     ALOGE("%s: Loading external capture sessions failed: %s(%d)", __FUNCTION__,
80           strerror(-res), res);
81     return res;
82   }
83 
84   return OK;
85 }
86 
GetResourceCost(CameraResourceCost * cost)87 status_t CameraDevice::GetResourceCost(CameraResourceCost* cost) {
88   ATRACE_CALL();
89   return camera_device_hwl_->GetResourceCost(cost);
90 }
91 
GetCameraCharacteristics(std::unique_ptr<HalCameraMetadata> * characteristics)92 status_t CameraDevice::GetCameraCharacteristics(
93     std::unique_ptr<HalCameraMetadata>* characteristics) {
94   ATRACE_CALL();
95   status_t res = camera_device_hwl_->GetCameraCharacteristics(characteristics);
96   if (res != OK) {
97     ALOGE("%s: GetCameraCharacteristics() failed: %s (%d).", __FUNCTION__,
98           strerror(-res), res);
99     return res;
100   }
101 
102   return hal_vendor_tag_utils::ModifyCharacteristicsKeys(characteristics->get());
103 }
104 
GetPhysicalCameraCharacteristics(uint32_t physical_camera_id,std::unique_ptr<HalCameraMetadata> * characteristics)105 status_t CameraDevice::GetPhysicalCameraCharacteristics(
106     uint32_t physical_camera_id,
107     std::unique_ptr<HalCameraMetadata>* characteristics) {
108   ATRACE_CALL();
109   status_t res = camera_device_hwl_->GetPhysicalCameraCharacteristics(
110       physical_camera_id, characteristics);
111   if (res != OK) {
112     ALOGE("%s: GetPhysicalCameraCharacteristics() failed: %s (%d).",
113           __FUNCTION__, strerror(-res), res);
114     return res;
115   }
116 
117   return hal_vendor_tag_utils::ModifyCharacteristicsKeys(characteristics->get());
118 }
119 
SetTorchMode(TorchMode mode)120 status_t CameraDevice::SetTorchMode(TorchMode mode) {
121   ATRACE_CALL();
122   return camera_device_hwl_->SetTorchMode(mode);
123 }
124 
DumpState(int fd)125 status_t CameraDevice::DumpState(int fd) {
126   ATRACE_CALL();
127   return camera_device_hwl_->DumpState(fd);
128 }
129 
CreateCameraDeviceSession(std::unique_ptr<CameraDeviceSession> * session)130 status_t CameraDevice::CreateCameraDeviceSession(
131     std::unique_ptr<CameraDeviceSession>* session) {
132   ATRACE_CALL();
133   if (session == nullptr) {
134     ALOGE("%s: session is nullptr.", __FUNCTION__);
135     return BAD_VALUE;
136   }
137 
138   std::unique_ptr<CameraDeviceSessionHwl> session_hwl;
139   status_t res = camera_device_hwl_->CreateCameraDeviceSessionHwl(
140       camera_allocator_hwl_, &session_hwl);
141   if (res != OK) {
142     ALOGE("%s: Creating a CameraDeviceSessionHwl failed: %s(%d)", __FUNCTION__,
143           strerror(-res), res);
144     return res;
145   }
146 
147   *session = CameraDeviceSession::Create(std::move(session_hwl),
148                                          external_session_factory_entries_,
149                                          camera_allocator_hwl_);
150   if (*session == nullptr) {
151     ALOGE("%s: Creating a CameraDeviceSession failed: %s(%d)", __FUNCTION__,
152           strerror(-res), res);
153     return UNKNOWN_ERROR;
154   }
155 
156   return OK;
157 }
158 
IsStreamCombinationSupported(const StreamConfiguration & stream_config)159 bool CameraDevice::IsStreamCombinationSupported(
160     const StreamConfiguration& stream_config) {
161   bool supported =
162       camera_device_hwl_->IsStreamCombinationSupported(stream_config);
163   if (!supported) {
164     ALOGD("%s: stream config is not supported.", __FUNCTION__);
165   }
166 
167   return supported;
168 }
169 
170 // Returns an array of regular files under dir_path.
FindLibraryPaths(const char * dir_path)171 static std::vector<std::string> FindLibraryPaths(const char* dir_path) {
172   std::vector<std::string> libs;
173 
174   errno = 0;
175   DIR* dir = opendir(dir_path);
176   if (!dir) {
177     ALOGD("%s: Unable to open directory %s (%s)", __FUNCTION__, dir_path,
178           strerror(errno));
179     return libs;
180   }
181 
182   struct dirent* entry = nullptr;
183   while ((entry = readdir(dir)) != nullptr) {
184     std::string lib_path(dir_path);
185     lib_path += entry->d_name;
186     struct stat st;
187     if (stat(lib_path.c_str(), &st) == 0) {
188       if (S_ISREG(st.st_mode)) {
189         libs.push_back(lib_path);
190       }
191     }
192   }
193 
194   return libs;
195 }
196 
LoadExternalCaptureSession()197 status_t CameraDevice::LoadExternalCaptureSession() {
198   ATRACE_CALL();
199 
200   if (external_session_factory_entries_.size() > 0) {
201     ALOGI("%s: External capture session libraries already loaded; skip.",
202           __FUNCTION__);
203     return OK;
204   }
205 
206   for (const auto& lib_path : FindLibraryPaths(kExternalCaptureSessionDir)) {
207     ALOGI("%s: Loading %s", __FUNCTION__, lib_path.c_str());
208     void* lib_handle = nullptr;
209     lib_handle = dlopen(lib_path.c_str(), RTLD_NOW);
210     if (lib_handle == nullptr) {
211       ALOGW("Failed loading %s.", lib_path.c_str());
212       continue;
213     }
214 
215     GetCaptureSessionFactoryFunc external_session_factory_t =
216         reinterpret_cast<GetCaptureSessionFactoryFunc>(
217             dlsym(lib_handle, "GetCaptureSessionFactory"));
218     if (external_session_factory_t == nullptr) {
219       ALOGE("%s: dlsym failed (%s) when loading %s.", __FUNCTION__,
220             "GetCaptureSessionFactory", lib_path.c_str());
221       dlclose(lib_handle);
222       lib_handle = nullptr;
223       continue;
224     }
225 
226     external_session_factory_entries_.push_back(external_session_factory_t);
227     external_capture_session_lib_handles_.push_back(lib_handle);
228   }
229 
230   return OK;
231 }
232 
~CameraDevice()233 CameraDevice::~CameraDevice() {
234   for (auto lib_handle : external_capture_session_lib_handles_) {
235     dlclose(lib_handle);
236   }
237 }
238 
239 }  // namespace google_camera_hal
240 }  // namespace android
241