1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "ACameraManager"
19*ec779b8eSAndroid Build Coastguard Worker
20*ec779b8eSAndroid Build Coastguard Worker #include "ACameraManager.h"
21*ec779b8eSAndroid Build Coastguard Worker #include <android_companion_virtualdevice_flags.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <camera/CameraUtils.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <camera/StringUtils.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <camera/VendorTagDescriptor.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <stdlib.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <utils/Vector.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <memory>
29*ec779b8eSAndroid Build Coastguard Worker #include "ACameraDevice.h"
30*ec779b8eSAndroid Build Coastguard Worker #include "ACameraMetadata.h"
31*ec779b8eSAndroid Build Coastguard Worker #include <com_android_internal_camera_flags.h>
32*ec779b8eSAndroid Build Coastguard Worker
33*ec779b8eSAndroid Build Coastguard Worker using namespace android::acam;
34*ec779b8eSAndroid Build Coastguard Worker namespace vd_flags = android::companion::virtualdevice::flags;
35*ec779b8eSAndroid Build Coastguard Worker namespace flags = com::android::internal::camera::flags;
36*ec779b8eSAndroid Build Coastguard Worker
37*ec779b8eSAndroid Build Coastguard Worker namespace android {
38*ec779b8eSAndroid Build Coastguard Worker namespace acam {
39*ec779b8eSAndroid Build Coastguard Worker namespace {
40*ec779b8eSAndroid Build Coastguard Worker
41*ec779b8eSAndroid Build Coastguard Worker using ::android::binder::Status;
42*ec779b8eSAndroid Build Coastguard Worker using ::android::companion::virtualnative::IVirtualDeviceManagerNative;
43*ec779b8eSAndroid Build Coastguard Worker
44*ec779b8eSAndroid Build Coastguard Worker // Return binder connection to VirtualDeviceManager.
45*ec779b8eSAndroid Build Coastguard Worker //
46*ec779b8eSAndroid Build Coastguard Worker // Subsequent calls return the same cached instance.
getVirtualDeviceManager()47*ec779b8eSAndroid Build Coastguard Worker sp<IVirtualDeviceManagerNative> getVirtualDeviceManager() {
48*ec779b8eSAndroid Build Coastguard Worker auto connectToVirtualDeviceManagerNative = []() {
49*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder =
50*ec779b8eSAndroid Build Coastguard Worker defaultServiceManager()->checkService(String16("virtualdevice_native"));
51*ec779b8eSAndroid Build Coastguard Worker if (binder == nullptr) {
52*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Cannot get virtualdevice_native service", __func__);
53*ec779b8eSAndroid Build Coastguard Worker return interface_cast<IVirtualDeviceManagerNative>(nullptr);
54*ec779b8eSAndroid Build Coastguard Worker }
55*ec779b8eSAndroid Build Coastguard Worker return interface_cast<IVirtualDeviceManagerNative>(binder);
56*ec779b8eSAndroid Build Coastguard Worker };
57*ec779b8eSAndroid Build Coastguard Worker
58*ec779b8eSAndroid Build Coastguard Worker static sp<IVirtualDeviceManagerNative> vdm = connectToVirtualDeviceManagerNative();
59*ec779b8eSAndroid Build Coastguard Worker return vdm;
60*ec779b8eSAndroid Build Coastguard Worker }
61*ec779b8eSAndroid Build Coastguard Worker
62*ec779b8eSAndroid Build Coastguard Worker // Returns device id calling process is running on.
63*ec779b8eSAndroid Build Coastguard Worker // If the process cannot be attributed to single virtual device id, returns default device id.
getCurrentDeviceId()64*ec779b8eSAndroid Build Coastguard Worker int getCurrentDeviceId() {
65*ec779b8eSAndroid Build Coastguard Worker if (!vd_flags::camera_device_awareness()) {
66*ec779b8eSAndroid Build Coastguard Worker return kDefaultDeviceId;
67*ec779b8eSAndroid Build Coastguard Worker }
68*ec779b8eSAndroid Build Coastguard Worker
69*ec779b8eSAndroid Build Coastguard Worker auto vdm = getVirtualDeviceManager();
70*ec779b8eSAndroid Build Coastguard Worker if (vdm == nullptr) {
71*ec779b8eSAndroid Build Coastguard Worker return kDefaultDeviceId;
72*ec779b8eSAndroid Build Coastguard Worker }
73*ec779b8eSAndroid Build Coastguard Worker
74*ec779b8eSAndroid Build Coastguard Worker const uid_t myUid = getuid();
75*ec779b8eSAndroid Build Coastguard Worker std::vector<int> deviceIds;
76*ec779b8eSAndroid Build Coastguard Worker Status status = vdm->getDeviceIdsForUid(myUid, &deviceIds);
77*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk() || deviceIds.empty()) {
78*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to call getDeviceIdsForUid to determine device id for uid %d: %s",
79*ec779b8eSAndroid Build Coastguard Worker __func__, myUid, status.toString8().c_str());
80*ec779b8eSAndroid Build Coastguard Worker return kDefaultDeviceId;
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker
83*ec779b8eSAndroid Build Coastguard Worker // If the UID is associated with multiple virtual devices, use the default device's
84*ec779b8eSAndroid Build Coastguard Worker // camera as we cannot disambiguate here. This effectively means that the app has
85*ec779b8eSAndroid Build Coastguard Worker // activities on different devices at the same time.
86*ec779b8eSAndroid Build Coastguard Worker if (deviceIds.size() != 1) {
87*ec779b8eSAndroid Build Coastguard Worker return kDefaultDeviceId;
88*ec779b8eSAndroid Build Coastguard Worker }
89*ec779b8eSAndroid Build Coastguard Worker return deviceIds[0];
90*ec779b8eSAndroid Build Coastguard Worker }
91*ec779b8eSAndroid Build Coastguard Worker
92*ec779b8eSAndroid Build Coastguard Worker // Returns device policy for POLICY_TYPE_CAMERA corresponding to deviceId.
getDevicePolicyForDeviceId(const int deviceId)93*ec779b8eSAndroid Build Coastguard Worker DevicePolicy getDevicePolicyForDeviceId(const int deviceId) {
94*ec779b8eSAndroid Build Coastguard Worker if (!vd_flags::camera_device_awareness() || deviceId == kDefaultDeviceId) {
95*ec779b8eSAndroid Build Coastguard Worker return DevicePolicy::DEVICE_POLICY_DEFAULT;
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker
98*ec779b8eSAndroid Build Coastguard Worker auto vdm = getVirtualDeviceManager();
99*ec779b8eSAndroid Build Coastguard Worker if (vdm == nullptr) {
100*ec779b8eSAndroid Build Coastguard Worker return DevicePolicy::DEVICE_POLICY_DEFAULT;
101*ec779b8eSAndroid Build Coastguard Worker }
102*ec779b8eSAndroid Build Coastguard Worker
103*ec779b8eSAndroid Build Coastguard Worker int policy = IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT;
104*ec779b8eSAndroid Build Coastguard Worker Status status = vdm->getDevicePolicy(deviceId, IVirtualDeviceManagerNative::POLICY_TYPE_CAMERA,
105*ec779b8eSAndroid Build Coastguard Worker &policy);
106*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
107*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to call getDevicePolicy to determine camera policy for device id %d: %s",
108*ec779b8eSAndroid Build Coastguard Worker __func__, deviceId, status.toString8().c_str());
109*ec779b8eSAndroid Build Coastguard Worker return DevicePolicy::DEVICE_POLICY_DEFAULT;
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker return static_cast<DevicePolicy>(policy);
112*ec779b8eSAndroid Build Coastguard Worker }
113*ec779b8eSAndroid Build Coastguard Worker
114*ec779b8eSAndroid Build Coastguard Worker // Returns true if camera owned by device cameraDeviceId can be accessed within deviceContext.
isCameraAccessible(const DeviceContext deviceContext,const int cameraDeviceId)115*ec779b8eSAndroid Build Coastguard Worker bool isCameraAccessible(const DeviceContext deviceContext, const int cameraDeviceId) {
116*ec779b8eSAndroid Build Coastguard Worker if (!vd_flags::camera_device_awareness() ||
117*ec779b8eSAndroid Build Coastguard Worker deviceContext.policy == DevicePolicy::DEVICE_POLICY_DEFAULT) {
118*ec779b8eSAndroid Build Coastguard Worker return cameraDeviceId == kDefaultDeviceId;
119*ec779b8eSAndroid Build Coastguard Worker }
120*ec779b8eSAndroid Build Coastguard Worker return deviceContext.deviceId == cameraDeviceId;
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker
123*ec779b8eSAndroid Build Coastguard Worker } // namespace
124*ec779b8eSAndroid Build Coastguard Worker
125*ec779b8eSAndroid Build Coastguard Worker // Static member definitions
126*ec779b8eSAndroid Build Coastguard Worker const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
127*ec779b8eSAndroid Build Coastguard Worker const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
128*ec779b8eSAndroid Build Coastguard Worker const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
129*ec779b8eSAndroid Build Coastguard Worker const char* CameraManagerGlobal::kContextKey = "CallbackContext";
130*ec779b8eSAndroid Build Coastguard Worker const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
131*ec779b8eSAndroid Build Coastguard Worker Mutex CameraManagerGlobal::sLock;
132*ec779b8eSAndroid Build Coastguard Worker wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr;
133*ec779b8eSAndroid Build Coastguard Worker
DeviceContext()134*ec779b8eSAndroid Build Coastguard Worker DeviceContext::DeviceContext() {
135*ec779b8eSAndroid Build Coastguard Worker deviceId = getCurrentDeviceId();
136*ec779b8eSAndroid Build Coastguard Worker policy = getDevicePolicyForDeviceId(deviceId);
137*ec779b8eSAndroid Build Coastguard Worker }
138*ec779b8eSAndroid Build Coastguard Worker
getInstance()139*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() {
140*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(sLock);
141*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> instance = sInstance.promote();
142*ec779b8eSAndroid Build Coastguard Worker if (instance == nullptr) {
143*ec779b8eSAndroid Build Coastguard Worker instance = new CameraManagerGlobal();
144*ec779b8eSAndroid Build Coastguard Worker sInstance = instance;
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker return instance;
147*ec779b8eSAndroid Build Coastguard Worker }
148*ec779b8eSAndroid Build Coastguard Worker
~CameraManagerGlobal()149*ec779b8eSAndroid Build Coastguard Worker CameraManagerGlobal::~CameraManagerGlobal() {
150*ec779b8eSAndroid Build Coastguard Worker // clear sInstance so next getInstance call knows to create a new one
151*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _sl(sLock);
152*ec779b8eSAndroid Build Coastguard Worker sInstance = nullptr;
153*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
154*ec779b8eSAndroid Build Coastguard Worker if (mCameraService != nullptr) {
155*ec779b8eSAndroid Build Coastguard Worker IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
156*ec779b8eSAndroid Build Coastguard Worker mCameraService->removeListener(mCameraServiceListener);
157*ec779b8eSAndroid Build Coastguard Worker }
158*ec779b8eSAndroid Build Coastguard Worker mDeathNotifier.clear();
159*ec779b8eSAndroid Build Coastguard Worker if (mCbLooper != nullptr) {
160*ec779b8eSAndroid Build Coastguard Worker mCbLooper->unregisterHandler(mHandler->id());
161*ec779b8eSAndroid Build Coastguard Worker mCbLooper->stop();
162*ec779b8eSAndroid Build Coastguard Worker }
163*ec779b8eSAndroid Build Coastguard Worker mCbLooper.clear();
164*ec779b8eSAndroid Build Coastguard Worker mHandler.clear();
165*ec779b8eSAndroid Build Coastguard Worker mCameraServiceListener.clear();
166*ec779b8eSAndroid Build Coastguard Worker mCameraService.clear();
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker
getCameraService()169*ec779b8eSAndroid Build Coastguard Worker sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
170*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
171*ec779b8eSAndroid Build Coastguard Worker return getCameraServiceLocked();
172*ec779b8eSAndroid Build Coastguard Worker }
173*ec779b8eSAndroid Build Coastguard Worker
getCameraServiceLocked()174*ec779b8eSAndroid Build Coastguard Worker sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
175*ec779b8eSAndroid Build Coastguard Worker if (mCameraService.get() != nullptr) {
176*ec779b8eSAndroid Build Coastguard Worker return mCameraService;
177*ec779b8eSAndroid Build Coastguard Worker }
178*ec779b8eSAndroid Build Coastguard Worker if (CameraUtils::isCameraServiceDisabled()) {
179*ec779b8eSAndroid Build Coastguard Worker return mCameraService;
180*ec779b8eSAndroid Build Coastguard Worker }
181*ec779b8eSAndroid Build Coastguard Worker
182*ec779b8eSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
183*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder;
184*ec779b8eSAndroid Build Coastguard Worker binder = sm->checkService(String16(kCameraServiceName));
185*ec779b8eSAndroid Build Coastguard Worker if (binder == nullptr) {
186*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
187*ec779b8eSAndroid Build Coastguard Worker return nullptr;
188*ec779b8eSAndroid Build Coastguard Worker }
189*ec779b8eSAndroid Build Coastguard Worker sp<hardware::ICameraService> cameraService = interface_cast<hardware::ICameraService>(binder);
190*ec779b8eSAndroid Build Coastguard Worker if (mDeathNotifier == nullptr) {
191*ec779b8eSAndroid Build Coastguard Worker mDeathNotifier = new DeathNotifier(this);
192*ec779b8eSAndroid Build Coastguard Worker binder->linkToDeath(mDeathNotifier);
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker
195*ec779b8eSAndroid Build Coastguard Worker // Setup looper thread to perform availability callbacks
196*ec779b8eSAndroid Build Coastguard Worker if (mCbLooper == nullptr) {
197*ec779b8eSAndroid Build Coastguard Worker mCbLooper = new ALooper;
198*ec779b8eSAndroid Build Coastguard Worker mCbLooper->setName("C2N-mgr-looper");
199*ec779b8eSAndroid Build Coastguard Worker status_t err = mCbLooper->start(
200*ec779b8eSAndroid Build Coastguard Worker /*runOnCallingThread*/false,
201*ec779b8eSAndroid Build Coastguard Worker /*canCallJava*/ true,
202*ec779b8eSAndroid Build Coastguard Worker PRIORITY_DEFAULT);
203*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
204*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
205*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, strerror(-err), err);
206*ec779b8eSAndroid Build Coastguard Worker mCbLooper.clear();
207*ec779b8eSAndroid Build Coastguard Worker return nullptr;
208*ec779b8eSAndroid Build Coastguard Worker }
209*ec779b8eSAndroid Build Coastguard Worker if (mHandler == nullptr) {
210*ec779b8eSAndroid Build Coastguard Worker mHandler = new CallbackHandler(this);
211*ec779b8eSAndroid Build Coastguard Worker }
212*ec779b8eSAndroid Build Coastguard Worker mCbLooper->registerHandler(mHandler);
213*ec779b8eSAndroid Build Coastguard Worker }
214*ec779b8eSAndroid Build Coastguard Worker
215*ec779b8eSAndroid Build Coastguard Worker // register ICameraServiceListener
216*ec779b8eSAndroid Build Coastguard Worker std::vector<hardware::CameraStatus> cameraStatuses{};
217*ec779b8eSAndroid Build Coastguard Worker if (mCameraServiceListener == nullptr) {
218*ec779b8eSAndroid Build Coastguard Worker mCameraServiceListener = new CameraServiceListener(this);
219*ec779b8eSAndroid Build Coastguard Worker cameraService->addListener(mCameraServiceListener, &cameraStatuses);
220*ec779b8eSAndroid Build Coastguard Worker }
221*ec779b8eSAndroid Build Coastguard Worker
222*ec779b8eSAndroid Build Coastguard Worker for (auto& c : cameraStatuses) {
223*ec779b8eSAndroid Build Coastguard Worker onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
224*ec779b8eSAndroid Build Coastguard Worker
225*ec779b8eSAndroid Build Coastguard Worker for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
226*ec779b8eSAndroid Build Coastguard Worker onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
227*ec779b8eSAndroid Build Coastguard Worker c.deviceId, c.cameraId, unavailablePhysicalId);
228*ec779b8eSAndroid Build Coastguard Worker }
229*ec779b8eSAndroid Build Coastguard Worker }
230*ec779b8eSAndroid Build Coastguard Worker // setup vendor tags
231*ec779b8eSAndroid Build Coastguard Worker if (!setupVendorTags(cameraService)) {
232*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Vendor tag descriptor cache couldn't be set up", __FUNCTION__);
233*ec779b8eSAndroid Build Coastguard Worker return nullptr;
234*ec779b8eSAndroid Build Coastguard Worker }
235*ec779b8eSAndroid Build Coastguard Worker
236*ec779b8eSAndroid Build Coastguard Worker mCameraService = cameraService;
237*ec779b8eSAndroid Build Coastguard Worker ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
238*ec779b8eSAndroid Build Coastguard Worker return mCameraService;
239*ec779b8eSAndroid Build Coastguard Worker }
240*ec779b8eSAndroid Build Coastguard Worker
setupVendorTags(sp<hardware::ICameraService> & cameraService)241*ec779b8eSAndroid Build Coastguard Worker bool CameraManagerGlobal::setupVendorTags(sp<hardware::ICameraService> &cameraService) {
242*ec779b8eSAndroid Build Coastguard Worker sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
243*ec779b8eSAndroid Build Coastguard Worker binder::Status ret = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
244*ec779b8eSAndroid Build Coastguard Worker if (!ret.isOk()) {
245*ec779b8eSAndroid Build Coastguard Worker if (ret.serviceSpecificErrorCode() ==
246*ec779b8eSAndroid Build Coastguard Worker hardware::ICameraService::ERROR_DEPRECATED_HAL) {
247*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Camera HAL too old; does not support vendor tags",
248*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
249*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptor::clearGlobalVendorTagDescriptor();
250*ec779b8eSAndroid Build Coastguard Worker } else {
251*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to get vendor tag descriptors: %s",
252*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, ret.toString8().c_str());
253*ec779b8eSAndroid Build Coastguard Worker }
254*ec779b8eSAndroid Build Coastguard Worker return false;
255*ec779b8eSAndroid Build Coastguard Worker }
256*ec779b8eSAndroid Build Coastguard Worker
257*ec779b8eSAndroid Build Coastguard Worker if (0 < desc->getTagCount()) {
258*ec779b8eSAndroid Build Coastguard Worker status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
259*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
260*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
261*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, strerror(-err), err);
262*ec779b8eSAndroid Build Coastguard Worker return false;
263*ec779b8eSAndroid Build Coastguard Worker }
264*ec779b8eSAndroid Build Coastguard Worker } else {
265*ec779b8eSAndroid Build Coastguard Worker sp<VendorTagDescriptorCache> cache =
266*ec779b8eSAndroid Build Coastguard Worker new VendorTagDescriptorCache();
267*ec779b8eSAndroid Build Coastguard Worker binder::Status res =
268*ec779b8eSAndroid Build Coastguard Worker cameraService->getCameraVendorTagCache(
269*ec779b8eSAndroid Build Coastguard Worker /*out*/cache.get());
270*ec779b8eSAndroid Build Coastguard Worker if (res.serviceSpecificErrorCode() ==
271*ec779b8eSAndroid Build Coastguard Worker hardware::ICameraService::ERROR_DISCONNECTED) {
272*ec779b8eSAndroid Build Coastguard Worker // No camera module available, not an error on devices with no cameras
273*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptorCache::clearGlobalVendorTagCache();
274*ec779b8eSAndroid Build Coastguard Worker } else if (res.isOk()) {
275*ec779b8eSAndroid Build Coastguard Worker status_t err =
276*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptorCache::setAsGlobalVendorTagCache(
277*ec779b8eSAndroid Build Coastguard Worker cache);
278*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
279*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to set vendor tag cache,"
280*ec779b8eSAndroid Build Coastguard Worker "received error %s (%d)", __FUNCTION__,
281*ec779b8eSAndroid Build Coastguard Worker strerror(-err), err);
282*ec779b8eSAndroid Build Coastguard Worker return false;
283*ec779b8eSAndroid Build Coastguard Worker }
284*ec779b8eSAndroid Build Coastguard Worker } else {
285*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptorCache::clearGlobalVendorTagCache();
286*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to setup vendor tag cache: %s",
287*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, res.toString8().c_str());
288*ec779b8eSAndroid Build Coastguard Worker return false;
289*ec779b8eSAndroid Build Coastguard Worker }
290*ec779b8eSAndroid Build Coastguard Worker }
291*ec779b8eSAndroid Build Coastguard Worker
292*ec779b8eSAndroid Build Coastguard Worker return true;
293*ec779b8eSAndroid Build Coastguard Worker }
294*ec779b8eSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> &)295*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
296*ec779b8eSAndroid Build Coastguard Worker {
297*ec779b8eSAndroid Build Coastguard Worker ALOGE("Camera service binderDied!");
298*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> cm = mCameraManager.promote();
299*ec779b8eSAndroid Build Coastguard Worker if (cm != nullptr) {
300*ec779b8eSAndroid Build Coastguard Worker AutoMutex lock(cm->mLock);
301*ec779b8eSAndroid Build Coastguard Worker std::vector<DeviceStatusMapKey> keysToRemove;
302*ec779b8eSAndroid Build Coastguard Worker keysToRemove.reserve(cm->mDeviceStatusMap.size());
303*ec779b8eSAndroid Build Coastguard Worker for (auto& pair : cm->mDeviceStatusMap) {
304*ec779b8eSAndroid Build Coastguard Worker keysToRemove.push_back(pair.first);
305*ec779b8eSAndroid Build Coastguard Worker }
306*ec779b8eSAndroid Build Coastguard Worker
307*ec779b8eSAndroid Build Coastguard Worker for (const DeviceStatusMapKey& key : keysToRemove) {
308*ec779b8eSAndroid Build Coastguard Worker cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId,
309*ec779b8eSAndroid Build Coastguard Worker key.cameraId);
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker cm->mCameraService.clear();
312*ec779b8eSAndroid Build Coastguard Worker cm->mCameraServiceListener.clear();
313*ec779b8eSAndroid Build Coastguard Worker cm->mDeathNotifier.clear();
314*ec779b8eSAndroid Build Coastguard Worker // TODO: consider adding re-connect call here?
315*ec779b8eSAndroid Build Coastguard Worker }
316*ec779b8eSAndroid Build Coastguard Worker }
317*ec779b8eSAndroid Build Coastguard Worker
registerExtendedAvailabilityCallback(const DeviceContext & deviceContext,const ACameraManager_ExtendedAvailabilityCallbacks * callback)318*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::registerExtendedAvailabilityCallback(
319*ec779b8eSAndroid Build Coastguard Worker const DeviceContext& deviceContext,
320*ec779b8eSAndroid Build Coastguard Worker const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
321*ec779b8eSAndroid Build Coastguard Worker return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext,
322*ec779b8eSAndroid Build Coastguard Worker callback);
323*ec779b8eSAndroid Build Coastguard Worker }
324*ec779b8eSAndroid Build Coastguard Worker
unregisterExtendedAvailabilityCallback(const DeviceContext & deviceContext,const ACameraManager_ExtendedAvailabilityCallbacks * callback)325*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
326*ec779b8eSAndroid Build Coastguard Worker const DeviceContext& deviceContext,
327*ec779b8eSAndroid Build Coastguard Worker const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
328*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
329*ec779b8eSAndroid Build Coastguard Worker
330*ec779b8eSAndroid Build Coastguard Worker drainPendingCallbacksLocked();
331*ec779b8eSAndroid Build Coastguard Worker
332*ec779b8eSAndroid Build Coastguard Worker Callback cb(deviceContext, callback);
333*ec779b8eSAndroid Build Coastguard Worker mCallbacks.erase(cb);
334*ec779b8eSAndroid Build Coastguard Worker }
335*ec779b8eSAndroid Build Coastguard Worker
registerAvailabilityCallback(const DeviceContext & deviceContext,const ACameraManager_AvailabilityCallbacks * callback)336*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::registerAvailabilityCallback(
337*ec779b8eSAndroid Build Coastguard Worker const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
338*ec779b8eSAndroid Build Coastguard Worker return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback);
339*ec779b8eSAndroid Build Coastguard Worker }
340*ec779b8eSAndroid Build Coastguard Worker
unregisterAvailabilityCallback(const DeviceContext & deviceContext,const ACameraManager_AvailabilityCallbacks * callback)341*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::unregisterAvailabilityCallback(
342*ec779b8eSAndroid Build Coastguard Worker const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
343*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
344*ec779b8eSAndroid Build Coastguard Worker
345*ec779b8eSAndroid Build Coastguard Worker drainPendingCallbacksLocked();
346*ec779b8eSAndroid Build Coastguard Worker
347*ec779b8eSAndroid Build Coastguard Worker Callback cb(deviceContext, callback);
348*ec779b8eSAndroid Build Coastguard Worker mCallbacks.erase(cb);
349*ec779b8eSAndroid Build Coastguard Worker }
350*ec779b8eSAndroid Build Coastguard Worker
onCallbackCalled()351*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::onCallbackCalled() {
352*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
353*ec779b8eSAndroid Build Coastguard Worker if (mPendingCallbackCnt > 0) {
354*ec779b8eSAndroid Build Coastguard Worker mPendingCallbackCnt--;
355*ec779b8eSAndroid Build Coastguard Worker }
356*ec779b8eSAndroid Build Coastguard Worker mCallbacksCond.signal();
357*ec779b8eSAndroid Build Coastguard Worker }
358*ec779b8eSAndroid Build Coastguard Worker
drainPendingCallbacksLocked()359*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::drainPendingCallbacksLocked() {
360*ec779b8eSAndroid Build Coastguard Worker while (mPendingCallbackCnt > 0) {
361*ec779b8eSAndroid Build Coastguard Worker auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
362*ec779b8eSAndroid Build Coastguard Worker if (res != NO_ERROR) {
363*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
364*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, strerror(-res), res);
365*ec779b8eSAndroid Build Coastguard Worker break;
366*ec779b8eSAndroid Build Coastguard Worker }
367*ec779b8eSAndroid Build Coastguard Worker }
368*ec779b8eSAndroid Build Coastguard Worker }
369*ec779b8eSAndroid Build Coastguard Worker
370*ec779b8eSAndroid Build Coastguard Worker template <class T>
registerAvailCallback(const DeviceContext & deviceContext,const T * callback)371*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext,
372*ec779b8eSAndroid Build Coastguard Worker const T* callback) {
373*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
374*ec779b8eSAndroid Build Coastguard Worker getCameraServiceLocked();
375*ec779b8eSAndroid Build Coastguard Worker Callback cb(deviceContext, callback);
376*ec779b8eSAndroid Build Coastguard Worker const auto& [_, newlyRegistered] = mCallbacks.insert(cb);
377*ec779b8eSAndroid Build Coastguard Worker // Send initial callbacks if callback is newly registered
378*ec779b8eSAndroid Build Coastguard Worker if (newlyRegistered) {
379*ec779b8eSAndroid Build Coastguard Worker for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
380*ec779b8eSAndroid Build Coastguard Worker if (!isCameraAccessible(deviceContext, key.deviceId)) {
381*ec779b8eSAndroid Build Coastguard Worker continue;
382*ec779b8eSAndroid Build Coastguard Worker }
383*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId = key.cameraId;
384*ec779b8eSAndroid Build Coastguard Worker int32_t status = statusAndHAL3Support.getStatus();
385*ec779b8eSAndroid Build Coastguard Worker // Don't send initial callbacks for camera ids which don't support
386*ec779b8eSAndroid Build Coastguard Worker // camera2
387*ec779b8eSAndroid Build Coastguard Worker if (!statusAndHAL3Support.supportsHAL3) {
388*ec779b8eSAndroid Build Coastguard Worker continue;
389*ec779b8eSAndroid Build Coastguard Worker }
390*ec779b8eSAndroid Build Coastguard Worker
391*ec779b8eSAndroid Build Coastguard Worker // Camera available/unavailable callback
392*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
393*ec779b8eSAndroid Build Coastguard Worker ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
394*ec779b8eSAndroid Build Coastguard Worker cb.mAvailable : cb.mUnavailable;
395*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kCallbackFpKey, (void *) cbFunc);
396*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kContextKey, cb.mContext);
397*ec779b8eSAndroid Build Coastguard Worker msg->setString(kCameraIdKey, AString(cameraId.c_str()));
398*ec779b8eSAndroid Build Coastguard Worker mPendingCallbackCnt++;
399*ec779b8eSAndroid Build Coastguard Worker msg->post();
400*ec779b8eSAndroid Build Coastguard Worker
401*ec779b8eSAndroid Build Coastguard Worker // Physical camera unavailable callback
402*ec779b8eSAndroid Build Coastguard Worker std::set<std::string> unavailablePhysicalCameras =
403*ec779b8eSAndroid Build Coastguard Worker statusAndHAL3Support.getUnavailablePhysicalIds();
404*ec779b8eSAndroid Build Coastguard Worker for (const auto& physicalCameraId : unavailablePhysicalCameras) {
405*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
406*ec779b8eSAndroid Build Coastguard Worker ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
407*ec779b8eSAndroid Build Coastguard Worker cb.mPhysicalCamUnavailable;
408*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kCallbackFpKey, (void *) cbFunc);
409*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kContextKey, cb.mContext);
410*ec779b8eSAndroid Build Coastguard Worker msg->setString(kCameraIdKey, AString(cameraId.c_str()));
411*ec779b8eSAndroid Build Coastguard Worker msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
412*ec779b8eSAndroid Build Coastguard Worker mPendingCallbackCnt++;
413*ec779b8eSAndroid Build Coastguard Worker msg->post();
414*ec779b8eSAndroid Build Coastguard Worker }
415*ec779b8eSAndroid Build Coastguard Worker }
416*ec779b8eSAndroid Build Coastguard Worker }
417*ec779b8eSAndroid Build Coastguard Worker }
418*ec779b8eSAndroid Build Coastguard Worker
supportsCamera2ApiLocked(const std::string & cameraId)419*ec779b8eSAndroid Build Coastguard Worker bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
420*ec779b8eSAndroid Build Coastguard Worker bool camera2Support = false;
421*ec779b8eSAndroid Build Coastguard Worker auto cs = getCameraServiceLocked();
422*ec779b8eSAndroid Build Coastguard Worker if (cs == nullptr) {
423*ec779b8eSAndroid Build Coastguard Worker return false;
424*ec779b8eSAndroid Build Coastguard Worker }
425*ec779b8eSAndroid Build Coastguard Worker binder::Status serviceRet =
426*ec779b8eSAndroid Build Coastguard Worker cs->supportsCameraApi(cameraId,
427*ec779b8eSAndroid Build Coastguard Worker hardware::ICameraService::API_VERSION_2, &camera2Support);
428*ec779b8eSAndroid Build Coastguard Worker if (!serviceRet.isOk()) {
429*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
430*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
431*ec779b8eSAndroid Build Coastguard Worker return false;
432*ec779b8eSAndroid Build Coastguard Worker }
433*ec779b8eSAndroid Build Coastguard Worker return camera2Support;
434*ec779b8eSAndroid Build Coastguard Worker }
435*ec779b8eSAndroid Build Coastguard Worker
getCameraIdList(const DeviceContext & context,std::vector<std::string> * cameraIds)436*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::getCameraIdList(const DeviceContext& context,
437*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string>* cameraIds) {
438*ec779b8eSAndroid Build Coastguard Worker // Ensure that we have initialized/refreshed the list of available devices
439*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
440*ec779b8eSAndroid Build Coastguard Worker // Needed to make sure we're connected to cameraservice
441*ec779b8eSAndroid Build Coastguard Worker getCameraServiceLocked();
442*ec779b8eSAndroid Build Coastguard Worker for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
443*ec779b8eSAndroid Build Coastguard Worker if (!isCameraAccessible(context, key.deviceId)) {
444*ec779b8eSAndroid Build Coastguard Worker continue;
445*ec779b8eSAndroid Build Coastguard Worker }
446*ec779b8eSAndroid Build Coastguard Worker
447*ec779b8eSAndroid Build Coastguard Worker int32_t status = statusAndHAL3Support.getStatus();
448*ec779b8eSAndroid Build Coastguard Worker if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
449*ec779b8eSAndroid Build Coastguard Worker status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
450*ec779b8eSAndroid Build Coastguard Worker continue;
451*ec779b8eSAndroid Build Coastguard Worker }
452*ec779b8eSAndroid Build Coastguard Worker if (!statusAndHAL3Support.supportsHAL3) {
453*ec779b8eSAndroid Build Coastguard Worker continue;
454*ec779b8eSAndroid Build Coastguard Worker }
455*ec779b8eSAndroid Build Coastguard Worker cameraIds->push_back(key.cameraId);
456*ec779b8eSAndroid Build Coastguard Worker }
457*ec779b8eSAndroid Build Coastguard Worker }
458*ec779b8eSAndroid Build Coastguard Worker
validStatus(int32_t status)459*ec779b8eSAndroid Build Coastguard Worker bool CameraManagerGlobal::validStatus(int32_t status) {
460*ec779b8eSAndroid Build Coastguard Worker switch (status) {
461*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
462*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraServiceListener::STATUS_PRESENT:
463*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraServiceListener::STATUS_ENUMERATING:
464*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
465*ec779b8eSAndroid Build Coastguard Worker return true;
466*ec779b8eSAndroid Build Coastguard Worker default:
467*ec779b8eSAndroid Build Coastguard Worker return false;
468*ec779b8eSAndroid Build Coastguard Worker }
469*ec779b8eSAndroid Build Coastguard Worker }
470*ec779b8eSAndroid Build Coastguard Worker
isStatusAvailable(int32_t status)471*ec779b8eSAndroid Build Coastguard Worker bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
472*ec779b8eSAndroid Build Coastguard Worker switch (status) {
473*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraServiceListener::STATUS_PRESENT:
474*ec779b8eSAndroid Build Coastguard Worker return true;
475*ec779b8eSAndroid Build Coastguard Worker default:
476*ec779b8eSAndroid Build Coastguard Worker return false;
477*ec779b8eSAndroid Build Coastguard Worker }
478*ec779b8eSAndroid Build Coastguard Worker }
479*ec779b8eSAndroid Build Coastguard Worker
onMessageReceived(const sp<AMessage> & msg)480*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::CallbackHandler::onMessageReceived(
481*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &msg) {
482*ec779b8eSAndroid Build Coastguard Worker onMessageReceivedInternal(msg);
483*ec779b8eSAndroid Build Coastguard Worker if (msg->what() == kWhatSendSingleCallback ||
484*ec779b8eSAndroid Build Coastguard Worker msg->what() == kWhatSendSingleAccessCallback ||
485*ec779b8eSAndroid Build Coastguard Worker msg->what() == kWhatSendSinglePhysicalCameraCallback) {
486*ec779b8eSAndroid Build Coastguard Worker notifyParent();
487*ec779b8eSAndroid Build Coastguard Worker }
488*ec779b8eSAndroid Build Coastguard Worker }
489*ec779b8eSAndroid Build Coastguard Worker
onMessageReceivedInternal(const sp<AMessage> & msg)490*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
491*ec779b8eSAndroid Build Coastguard Worker const sp<AMessage> &msg) {
492*ec779b8eSAndroid Build Coastguard Worker switch (msg->what()) {
493*ec779b8eSAndroid Build Coastguard Worker case kWhatSendSingleCallback:
494*ec779b8eSAndroid Build Coastguard Worker {
495*ec779b8eSAndroid Build Coastguard Worker ACameraManager_AvailabilityCallback cb;
496*ec779b8eSAndroid Build Coastguard Worker void* context;
497*ec779b8eSAndroid Build Coastguard Worker AString cameraId;
498*ec779b8eSAndroid Build Coastguard Worker bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
499*ec779b8eSAndroid Build Coastguard Worker if (!found) {
500*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
501*ec779b8eSAndroid Build Coastguard Worker return;
502*ec779b8eSAndroid Build Coastguard Worker }
503*ec779b8eSAndroid Build Coastguard Worker found = msg->findPointer(kContextKey, &context);
504*ec779b8eSAndroid Build Coastguard Worker if (!found) {
505*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find callback context!", __FUNCTION__);
506*ec779b8eSAndroid Build Coastguard Worker return;
507*ec779b8eSAndroid Build Coastguard Worker }
508*ec779b8eSAndroid Build Coastguard Worker found = msg->findString(kCameraIdKey, &cameraId);
509*ec779b8eSAndroid Build Coastguard Worker if (!found) {
510*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
511*ec779b8eSAndroid Build Coastguard Worker return;
512*ec779b8eSAndroid Build Coastguard Worker }
513*ec779b8eSAndroid Build Coastguard Worker (*cb)(context, cameraId.c_str());
514*ec779b8eSAndroid Build Coastguard Worker break;
515*ec779b8eSAndroid Build Coastguard Worker }
516*ec779b8eSAndroid Build Coastguard Worker case kWhatSendSingleAccessCallback:
517*ec779b8eSAndroid Build Coastguard Worker {
518*ec779b8eSAndroid Build Coastguard Worker ACameraManager_AccessPrioritiesChangedCallback cb;
519*ec779b8eSAndroid Build Coastguard Worker void* context;
520*ec779b8eSAndroid Build Coastguard Worker AString cameraId;
521*ec779b8eSAndroid Build Coastguard Worker bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
522*ec779b8eSAndroid Build Coastguard Worker if (!found) {
523*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
524*ec779b8eSAndroid Build Coastguard Worker return;
525*ec779b8eSAndroid Build Coastguard Worker }
526*ec779b8eSAndroid Build Coastguard Worker found = msg->findPointer(kContextKey, &context);
527*ec779b8eSAndroid Build Coastguard Worker if (!found) {
528*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find callback context!", __FUNCTION__);
529*ec779b8eSAndroid Build Coastguard Worker return;
530*ec779b8eSAndroid Build Coastguard Worker }
531*ec779b8eSAndroid Build Coastguard Worker (*cb)(context);
532*ec779b8eSAndroid Build Coastguard Worker break;
533*ec779b8eSAndroid Build Coastguard Worker }
534*ec779b8eSAndroid Build Coastguard Worker case kWhatSendSinglePhysicalCameraCallback:
535*ec779b8eSAndroid Build Coastguard Worker {
536*ec779b8eSAndroid Build Coastguard Worker ACameraManager_PhysicalCameraAvailabilityCallback cb;
537*ec779b8eSAndroid Build Coastguard Worker void* context;
538*ec779b8eSAndroid Build Coastguard Worker AString cameraId;
539*ec779b8eSAndroid Build Coastguard Worker AString physicalCameraId;
540*ec779b8eSAndroid Build Coastguard Worker bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
541*ec779b8eSAndroid Build Coastguard Worker if (!found) {
542*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
543*ec779b8eSAndroid Build Coastguard Worker return;
544*ec779b8eSAndroid Build Coastguard Worker }
545*ec779b8eSAndroid Build Coastguard Worker if (cb == nullptr) {
546*ec779b8eSAndroid Build Coastguard Worker // Physical camera callback is null
547*ec779b8eSAndroid Build Coastguard Worker return;
548*ec779b8eSAndroid Build Coastguard Worker }
549*ec779b8eSAndroid Build Coastguard Worker found = msg->findPointer(kContextKey, &context);
550*ec779b8eSAndroid Build Coastguard Worker if (!found) {
551*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find callback context!", __FUNCTION__);
552*ec779b8eSAndroid Build Coastguard Worker return;
553*ec779b8eSAndroid Build Coastguard Worker }
554*ec779b8eSAndroid Build Coastguard Worker found = msg->findString(kCameraIdKey, &cameraId);
555*ec779b8eSAndroid Build Coastguard Worker if (!found) {
556*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
557*ec779b8eSAndroid Build Coastguard Worker return;
558*ec779b8eSAndroid Build Coastguard Worker }
559*ec779b8eSAndroid Build Coastguard Worker found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
560*ec779b8eSAndroid Build Coastguard Worker if (!found) {
561*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
562*ec779b8eSAndroid Build Coastguard Worker return;
563*ec779b8eSAndroid Build Coastguard Worker }
564*ec779b8eSAndroid Build Coastguard Worker (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
565*ec779b8eSAndroid Build Coastguard Worker break;
566*ec779b8eSAndroid Build Coastguard Worker }
567*ec779b8eSAndroid Build Coastguard Worker default:
568*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
569*ec779b8eSAndroid Build Coastguard Worker break;
570*ec779b8eSAndroid Build Coastguard Worker }
571*ec779b8eSAndroid Build Coastguard Worker }
572*ec779b8eSAndroid Build Coastguard Worker
notifyParent()573*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::CallbackHandler::notifyParent() {
574*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> parent = mParent.promote();
575*ec779b8eSAndroid Build Coastguard Worker if (parent != nullptr) {
576*ec779b8eSAndroid Build Coastguard Worker parent->onCallbackCalled();
577*ec779b8eSAndroid Build Coastguard Worker }
578*ec779b8eSAndroid Build Coastguard Worker }
579*ec779b8eSAndroid Build Coastguard Worker
onCameraAccessPrioritiesChanged()580*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
581*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> cm = mCameraManager.promote();
582*ec779b8eSAndroid Build Coastguard Worker if (cm != nullptr) {
583*ec779b8eSAndroid Build Coastguard Worker cm->onCameraAccessPrioritiesChanged();
584*ec779b8eSAndroid Build Coastguard Worker } else {
585*ec779b8eSAndroid Build Coastguard Worker ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
586*ec779b8eSAndroid Build Coastguard Worker }
587*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
588*ec779b8eSAndroid Build Coastguard Worker }
589*ec779b8eSAndroid Build Coastguard Worker
onStatusChanged(int32_t status,const std::string & cameraId,int deviceId)590*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
591*ec779b8eSAndroid Build Coastguard Worker int32_t status, const std::string& cameraId, int deviceId) {
592*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> cm = mCameraManager.promote();
593*ec779b8eSAndroid Build Coastguard Worker if (cm != nullptr) {
594*ec779b8eSAndroid Build Coastguard Worker cm->onStatusChanged(status, deviceId, cameraId);
595*ec779b8eSAndroid Build Coastguard Worker }
596*ec779b8eSAndroid Build Coastguard Worker ALOGE_IF(cm == nullptr,
597*ec779b8eSAndroid Build Coastguard Worker "Cannot deliver physical camera status change. Global camera manager died");
598*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
599*ec779b8eSAndroid Build Coastguard Worker }
600*ec779b8eSAndroid Build Coastguard Worker
onPhysicalCameraStatusChanged(int32_t status,const std::string & cameraId,const std::string & physicalCameraId,int deviceId)601*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
602*ec779b8eSAndroid Build Coastguard Worker int32_t status, const std::string& cameraId, const std::string& physicalCameraId,
603*ec779b8eSAndroid Build Coastguard Worker int deviceId) {
604*ec779b8eSAndroid Build Coastguard Worker sp<CameraManagerGlobal> cm = mCameraManager.promote();
605*ec779b8eSAndroid Build Coastguard Worker if (cm != nullptr) {
606*ec779b8eSAndroid Build Coastguard Worker cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId);
607*ec779b8eSAndroid Build Coastguard Worker }
608*ec779b8eSAndroid Build Coastguard Worker ALOGE_IF(cm == nullptr,
609*ec779b8eSAndroid Build Coastguard Worker "Cannot deliver physical camera status change. Global camera manager died");
610*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
611*ec779b8eSAndroid Build Coastguard Worker }
612*ec779b8eSAndroid Build Coastguard Worker
onCameraAccessPrioritiesChanged()613*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
614*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
615*ec779b8eSAndroid Build Coastguard Worker for (auto cb : mCallbacks) {
616*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
617*ec779b8eSAndroid Build Coastguard Worker ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
618*ec779b8eSAndroid Build Coastguard Worker if (cbFp != nullptr) {
619*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kCallbackFpKey, (void *) cbFp);
620*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kContextKey, cb.mContext);
621*ec779b8eSAndroid Build Coastguard Worker mPendingCallbackCnt++;
622*ec779b8eSAndroid Build Coastguard Worker msg->post();
623*ec779b8eSAndroid Build Coastguard Worker }
624*ec779b8eSAndroid Build Coastguard Worker }
625*ec779b8eSAndroid Build Coastguard Worker }
626*ec779b8eSAndroid Build Coastguard Worker
onStatusChanged(int32_t status,const int deviceId,const std::string & cameraId)627*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
628*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId) {
629*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
630*ec779b8eSAndroid Build Coastguard Worker onStatusChangedLocked(status, deviceId, cameraId);
631*ec779b8eSAndroid Build Coastguard Worker }
632*ec779b8eSAndroid Build Coastguard Worker
onStatusChangedLocked(int32_t status,const int deviceId,const std::string & cameraId)633*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
634*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId) {
635*ec779b8eSAndroid Build Coastguard Worker if (!validStatus(status)) {
636*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid status %d", __FUNCTION__, status);
637*ec779b8eSAndroid Build Coastguard Worker return;
638*ec779b8eSAndroid Build Coastguard Worker }
639*ec779b8eSAndroid Build Coastguard Worker
640*ec779b8eSAndroid Build Coastguard Worker DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
641*ec779b8eSAndroid Build Coastguard Worker
642*ec779b8eSAndroid Build Coastguard Worker bool firstStatus = (mDeviceStatusMap.count(key) == 0);
643*ec779b8eSAndroid Build Coastguard Worker int32_t oldStatus = firstStatus ? status : // first status
644*ec779b8eSAndroid Build Coastguard Worker mDeviceStatusMap[key].getStatus();
645*ec779b8eSAndroid Build Coastguard Worker
646*ec779b8eSAndroid Build Coastguard Worker if (!firstStatus &&
647*ec779b8eSAndroid Build Coastguard Worker isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
648*ec779b8eSAndroid Build Coastguard Worker // No status update. No need to send callback
649*ec779b8eSAndroid Build Coastguard Worker return;
650*ec779b8eSAndroid Build Coastguard Worker }
651*ec779b8eSAndroid Build Coastguard Worker
652*ec779b8eSAndroid Build Coastguard Worker bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
653*ec779b8eSAndroid Build Coastguard Worker if (firstStatus) {
654*ec779b8eSAndroid Build Coastguard Worker mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key),
655*ec779b8eSAndroid Build Coastguard Worker std::forward_as_tuple(status, supportsHAL3));
656*ec779b8eSAndroid Build Coastguard Worker } else {
657*ec779b8eSAndroid Build Coastguard Worker mDeviceStatusMap[key].updateStatus(status);
658*ec779b8eSAndroid Build Coastguard Worker }
659*ec779b8eSAndroid Build Coastguard Worker // Iterate through all registered callbacks
660*ec779b8eSAndroid Build Coastguard Worker if (supportsHAL3) {
661*ec779b8eSAndroid Build Coastguard Worker for (auto cb : mCallbacks) {
662*ec779b8eSAndroid Build Coastguard Worker if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
663*ec779b8eSAndroid Build Coastguard Worker continue;
664*ec779b8eSAndroid Build Coastguard Worker }
665*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
666*ec779b8eSAndroid Build Coastguard Worker ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
667*ec779b8eSAndroid Build Coastguard Worker cb.mAvailable : cb.mUnavailable;
668*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kCallbackFpKey, (void *) cbFp);
669*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kContextKey, cb.mContext);
670*ec779b8eSAndroid Build Coastguard Worker msg->setString(kCameraIdKey, AString(cameraId.c_str()));
671*ec779b8eSAndroid Build Coastguard Worker mPendingCallbackCnt++;
672*ec779b8eSAndroid Build Coastguard Worker msg->post();
673*ec779b8eSAndroid Build Coastguard Worker }
674*ec779b8eSAndroid Build Coastguard Worker }
675*ec779b8eSAndroid Build Coastguard Worker if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
676*ec779b8eSAndroid Build Coastguard Worker mDeviceStatusMap.erase(key);
677*ec779b8eSAndroid Build Coastguard Worker }
678*ec779b8eSAndroid Build Coastguard Worker }
679*ec779b8eSAndroid Build Coastguard Worker
onStatusChanged(int32_t status,const int deviceId,const std::string & cameraId,const std::string & physicalCameraId)680*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
681*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId, const std::string& physicalCameraId) {
682*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
683*ec779b8eSAndroid Build Coastguard Worker onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId);
684*ec779b8eSAndroid Build Coastguard Worker }
685*ec779b8eSAndroid Build Coastguard Worker
onStatusChangedLocked(int32_t status,const int deviceId,const std::string & cameraId,const std::string & physicalCameraId)686*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
687*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId, const std::string& physicalCameraId) {
688*ec779b8eSAndroid Build Coastguard Worker if (!validStatus(status)) {
689*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid status %d", __FUNCTION__, status);
690*ec779b8eSAndroid Build Coastguard Worker return;
691*ec779b8eSAndroid Build Coastguard Worker }
692*ec779b8eSAndroid Build Coastguard Worker
693*ec779b8eSAndroid Build Coastguard Worker DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
694*ec779b8eSAndroid Build Coastguard Worker auto logicalStatus = mDeviceStatusMap.find(key);
695*ec779b8eSAndroid Build Coastguard Worker if (logicalStatus == mDeviceStatusMap.end()) {
696*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Physical camera id %s status change on a non-present id %s",
697*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
698*ec779b8eSAndroid Build Coastguard Worker return;
699*ec779b8eSAndroid Build Coastguard Worker }
700*ec779b8eSAndroid Build Coastguard Worker int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus();
701*ec779b8eSAndroid Build Coastguard Worker if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
702*ec779b8eSAndroid Build Coastguard Worker logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
703*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
704*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
705*ec779b8eSAndroid Build Coastguard Worker return;
706*ec779b8eSAndroid Build Coastguard Worker }
707*ec779b8eSAndroid Build Coastguard Worker
708*ec779b8eSAndroid Build Coastguard Worker bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
709*ec779b8eSAndroid Build Coastguard Worker
710*ec779b8eSAndroid Build Coastguard Worker bool updated = false;
711*ec779b8eSAndroid Build Coastguard Worker if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
712*ec779b8eSAndroid Build Coastguard Worker updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId);
713*ec779b8eSAndroid Build Coastguard Worker } else {
714*ec779b8eSAndroid Build Coastguard Worker updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId);
715*ec779b8eSAndroid Build Coastguard Worker }
716*ec779b8eSAndroid Build Coastguard Worker
717*ec779b8eSAndroid Build Coastguard Worker // Iterate through all registered callbacks
718*ec779b8eSAndroid Build Coastguard Worker if (supportsHAL3 && updated) {
719*ec779b8eSAndroid Build Coastguard Worker for (auto cb : mCallbacks) {
720*ec779b8eSAndroid Build Coastguard Worker if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
721*ec779b8eSAndroid Build Coastguard Worker continue;
722*ec779b8eSAndroid Build Coastguard Worker }
723*ec779b8eSAndroid Build Coastguard Worker sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
724*ec779b8eSAndroid Build Coastguard Worker ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
725*ec779b8eSAndroid Build Coastguard Worker cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
726*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kCallbackFpKey, (void *) cbFp);
727*ec779b8eSAndroid Build Coastguard Worker msg->setPointer(kContextKey, cb.mContext);
728*ec779b8eSAndroid Build Coastguard Worker msg->setString(kCameraIdKey, AString(cameraId.c_str()));
729*ec779b8eSAndroid Build Coastguard Worker msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
730*ec779b8eSAndroid Build Coastguard Worker mPendingCallbackCnt++;
731*ec779b8eSAndroid Build Coastguard Worker msg->post();
732*ec779b8eSAndroid Build Coastguard Worker }
733*ec779b8eSAndroid Build Coastguard Worker }
734*ec779b8eSAndroid Build Coastguard Worker }
735*ec779b8eSAndroid Build Coastguard Worker
getStatus()736*ec779b8eSAndroid Build Coastguard Worker int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
737*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
738*ec779b8eSAndroid Build Coastguard Worker return status;
739*ec779b8eSAndroid Build Coastguard Worker }
740*ec779b8eSAndroid Build Coastguard Worker
updateStatus(int32_t newStatus)741*ec779b8eSAndroid Build Coastguard Worker void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
742*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
743*ec779b8eSAndroid Build Coastguard Worker status = newStatus;
744*ec779b8eSAndroid Build Coastguard Worker }
745*ec779b8eSAndroid Build Coastguard Worker
addUnavailablePhysicalId(const std::string & physicalCameraId)746*ec779b8eSAndroid Build Coastguard Worker bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
747*ec779b8eSAndroid Build Coastguard Worker const std::string& physicalCameraId) {
748*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
749*ec779b8eSAndroid Build Coastguard Worker auto result = unavailablePhysicalIds.insert(physicalCameraId);
750*ec779b8eSAndroid Build Coastguard Worker return result.second;
751*ec779b8eSAndroid Build Coastguard Worker }
752*ec779b8eSAndroid Build Coastguard Worker
removeUnavailablePhysicalId(const std::string & physicalCameraId)753*ec779b8eSAndroid Build Coastguard Worker bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
754*ec779b8eSAndroid Build Coastguard Worker const std::string& physicalCameraId) {
755*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
756*ec779b8eSAndroid Build Coastguard Worker auto count = unavailablePhysicalIds.erase(physicalCameraId);
757*ec779b8eSAndroid Build Coastguard Worker return count > 0;
758*ec779b8eSAndroid Build Coastguard Worker }
759*ec779b8eSAndroid Build Coastguard Worker
getUnavailablePhysicalIds()760*ec779b8eSAndroid Build Coastguard Worker std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
761*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mLock);
762*ec779b8eSAndroid Build Coastguard Worker return unavailablePhysicalIds;
763*ec779b8eSAndroid Build Coastguard Worker }
764*ec779b8eSAndroid Build Coastguard Worker
765*ec779b8eSAndroid Build Coastguard Worker } // namespace acam
766*ec779b8eSAndroid Build Coastguard Worker } // namespace android
767*ec779b8eSAndroid Build Coastguard Worker
768*ec779b8eSAndroid Build Coastguard Worker /**
769*ec779b8eSAndroid Build Coastguard Worker * ACameraManger Implementation
770*ec779b8eSAndroid Build Coastguard Worker */
771*ec779b8eSAndroid Build Coastguard Worker camera_status_t
getCameraIdList(ACameraIdList ** cameraIdList)772*ec779b8eSAndroid Build Coastguard Worker ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
773*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
774*ec779b8eSAndroid Build Coastguard Worker
775*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> idList;
776*ec779b8eSAndroid Build Coastguard Worker mGlobalManager->getCameraIdList(mDeviceContext, &idList);
777*ec779b8eSAndroid Build Coastguard Worker
778*ec779b8eSAndroid Build Coastguard Worker int numCameras = idList.size();
779*ec779b8eSAndroid Build Coastguard Worker ACameraIdList *out = new ACameraIdList;
780*ec779b8eSAndroid Build Coastguard Worker if (!out) {
781*ec779b8eSAndroid Build Coastguard Worker ALOGE("Allocate memory for ACameraIdList failed!");
782*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
783*ec779b8eSAndroid Build Coastguard Worker }
784*ec779b8eSAndroid Build Coastguard Worker out->numCameras = numCameras;
785*ec779b8eSAndroid Build Coastguard Worker out->cameraIds = new const char*[numCameras];
786*ec779b8eSAndroid Build Coastguard Worker if (!out->cameraIds) {
787*ec779b8eSAndroid Build Coastguard Worker ALOGE("Allocate memory for ACameraIdList failed!");
788*ec779b8eSAndroid Build Coastguard Worker deleteCameraIdList(out);
789*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
790*ec779b8eSAndroid Build Coastguard Worker }
791*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < numCameras; i++) {
792*ec779b8eSAndroid Build Coastguard Worker const char* src = idList[i].c_str();
793*ec779b8eSAndroid Build Coastguard Worker size_t dstSize = strlen(src) + 1;
794*ec779b8eSAndroid Build Coastguard Worker char* dst = new char[dstSize];
795*ec779b8eSAndroid Build Coastguard Worker if (!dst) {
796*ec779b8eSAndroid Build Coastguard Worker ALOGE("Allocate memory for ACameraIdList failed!");
797*ec779b8eSAndroid Build Coastguard Worker deleteCameraIdList(out);
798*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
799*ec779b8eSAndroid Build Coastguard Worker }
800*ec779b8eSAndroid Build Coastguard Worker strlcpy(dst, src, dstSize);
801*ec779b8eSAndroid Build Coastguard Worker out->cameraIds[i] = dst;
802*ec779b8eSAndroid Build Coastguard Worker }
803*ec779b8eSAndroid Build Coastguard Worker *cameraIdList = out;
804*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_OK;
805*ec779b8eSAndroid Build Coastguard Worker }
806*ec779b8eSAndroid Build Coastguard Worker
807*ec779b8eSAndroid Build Coastguard Worker void
deleteCameraIdList(ACameraIdList * cameraIdList)808*ec779b8eSAndroid Build Coastguard Worker ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
809*ec779b8eSAndroid Build Coastguard Worker if (cameraIdList != nullptr) {
810*ec779b8eSAndroid Build Coastguard Worker if (cameraIdList->cameraIds != nullptr) {
811*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < cameraIdList->numCameras; i ++) {
812*ec779b8eSAndroid Build Coastguard Worker if (cameraIdList->cameraIds[i] != nullptr) {
813*ec779b8eSAndroid Build Coastguard Worker delete[] cameraIdList->cameraIds[i];
814*ec779b8eSAndroid Build Coastguard Worker }
815*ec779b8eSAndroid Build Coastguard Worker }
816*ec779b8eSAndroid Build Coastguard Worker delete[] cameraIdList->cameraIds;
817*ec779b8eSAndroid Build Coastguard Worker }
818*ec779b8eSAndroid Build Coastguard Worker delete cameraIdList;
819*ec779b8eSAndroid Build Coastguard Worker }
820*ec779b8eSAndroid Build Coastguard Worker }
821*ec779b8eSAndroid Build Coastguard Worker
getCameraCharacteristics(const char * cameraIdStr,sp<ACameraMetadata> * characteristics)822*ec779b8eSAndroid Build Coastguard Worker camera_status_t ACameraManager::getCameraCharacteristics(
823*ec779b8eSAndroid Build Coastguard Worker const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
824*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
825*ec779b8eSAndroid Build Coastguard Worker
826*ec779b8eSAndroid Build Coastguard Worker sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
827*ec779b8eSAndroid Build Coastguard Worker if (cs == nullptr) {
828*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
829*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_CAMERA_DISCONNECTED;
830*ec779b8eSAndroid Build Coastguard Worker }
831*ec779b8eSAndroid Build Coastguard Worker
832*ec779b8eSAndroid Build Coastguard Worker CameraMetadata rawMetadata;
833*ec779b8eSAndroid Build Coastguard Worker int targetSdkVersion = android_get_application_target_sdk_version();
834*ec779b8eSAndroid Build Coastguard Worker
835*ec779b8eSAndroid Build Coastguard Worker AttributionSourceState clientAttribution;
836*ec779b8eSAndroid Build Coastguard Worker clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
837*ec779b8eSAndroid Build Coastguard Worker clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
838*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId = mDeviceContext.deviceId;
839*ec779b8eSAndroid Build Coastguard Worker
840*ec779b8eSAndroid Build Coastguard Worker binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
841*ec779b8eSAndroid Build Coastguard Worker targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
842*ec779b8eSAndroid Build Coastguard Worker clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
843*ec779b8eSAndroid Build Coastguard Worker &rawMetadata);
844*ec779b8eSAndroid Build Coastguard Worker if (!serviceRet.isOk()) {
845*ec779b8eSAndroid Build Coastguard Worker switch(serviceRet.serviceSpecificErrorCode()) {
846*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_DISCONNECTED:
847*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
848*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_CAMERA_DISCONNECTED;
849*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
850*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
851*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_INVALID_PARAMETER;
852*ec779b8eSAndroid Build Coastguard Worker default:
853*ec779b8eSAndroid Build Coastguard Worker ALOGE("Get camera characteristics from camera service failed: %s",
854*ec779b8eSAndroid Build Coastguard Worker serviceRet.toString8().c_str());
855*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_UNKNOWN; // should not reach here
856*ec779b8eSAndroid Build Coastguard Worker }
857*ec779b8eSAndroid Build Coastguard Worker }
858*ec779b8eSAndroid Build Coastguard Worker
859*ec779b8eSAndroid Build Coastguard Worker *characteristics = new ACameraMetadata(
860*ec779b8eSAndroid Build Coastguard Worker rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
861*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_OK;
862*ec779b8eSAndroid Build Coastguard Worker }
863*ec779b8eSAndroid Build Coastguard Worker
864*ec779b8eSAndroid Build Coastguard Worker camera_status_t
isCameraDeviceSharingSupported(const char * cameraId,bool * isSharingSupported)865*ec779b8eSAndroid Build Coastguard Worker ACameraManager::isCameraDeviceSharingSupported(
866*ec779b8eSAndroid Build Coastguard Worker const char* cameraId,
867*ec779b8eSAndroid Build Coastguard Worker /*out*/bool* isSharingSupported) {
868*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client()) {
869*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
870*ec779b8eSAndroid Build Coastguard Worker }
871*ec779b8eSAndroid Build Coastguard Worker sp<ACameraMetadata> spChars;
872*ec779b8eSAndroid Build Coastguard Worker camera_status_t ret = getCameraCharacteristics(cameraId, &spChars);
873*ec779b8eSAndroid Build Coastguard Worker if (ret != ACAMERA_OK) {
874*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
875*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId, ret);
876*ec779b8eSAndroid Build Coastguard Worker return ret;
877*ec779b8eSAndroid Build Coastguard Worker }
878*ec779b8eSAndroid Build Coastguard Worker
879*ec779b8eSAndroid Build Coastguard Worker ACameraMetadata* chars = spChars.get();
880*ec779b8eSAndroid Build Coastguard Worker ACameraMetadata_const_entry entry;
881*ec779b8eSAndroid Build Coastguard Worker ret = ACameraMetadata_getConstEntry(chars, ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS,
882*ec779b8eSAndroid Build Coastguard Worker &entry);
883*ec779b8eSAndroid Build Coastguard Worker if (ret != ACAMERA_OK) {
884*ec779b8eSAndroid Build Coastguard Worker return ret;
885*ec779b8eSAndroid Build Coastguard Worker }
886*ec779b8eSAndroid Build Coastguard Worker *isSharingSupported = (entry.count > 0) ? true : false;
887*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_OK;
888*ec779b8eSAndroid Build Coastguard Worker }
889*ec779b8eSAndroid Build Coastguard Worker
890*ec779b8eSAndroid Build Coastguard Worker camera_status_t
openCamera(const char * cameraId,bool sharedMode,ACameraDevice_StateCallbacks * callback,ACameraDevice ** outDevice,bool * primaryClient)891*ec779b8eSAndroid Build Coastguard Worker ACameraManager::openCamera(
892*ec779b8eSAndroid Build Coastguard Worker const char* cameraId, bool sharedMode,
893*ec779b8eSAndroid Build Coastguard Worker ACameraDevice_StateCallbacks* callback,
894*ec779b8eSAndroid Build Coastguard Worker /*out*/ACameraDevice** outDevice, /*out*/bool* primaryClient) {
895*ec779b8eSAndroid Build Coastguard Worker sp<ACameraMetadata> chars;
896*ec779b8eSAndroid Build Coastguard Worker camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
897*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mLock);
898*ec779b8eSAndroid Build Coastguard Worker if (ret != ACAMERA_OK) {
899*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
900*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId, ret);
901*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_INVALID_PARAMETER;
902*ec779b8eSAndroid Build Coastguard Worker }
903*ec779b8eSAndroid Build Coastguard Worker
904*ec779b8eSAndroid Build Coastguard Worker ACameraDevice* device = new ACameraDevice(cameraId, callback, chars, sharedMode);
905*ec779b8eSAndroid Build Coastguard Worker
906*ec779b8eSAndroid Build Coastguard Worker sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
907*ec779b8eSAndroid Build Coastguard Worker if (cs == nullptr) {
908*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
909*ec779b8eSAndroid Build Coastguard Worker delete device;
910*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_CAMERA_DISCONNECTED;
911*ec779b8eSAndroid Build Coastguard Worker }
912*ec779b8eSAndroid Build Coastguard Worker
913*ec779b8eSAndroid Build Coastguard Worker sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
914*ec779b8eSAndroid Build Coastguard Worker sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
915*ec779b8eSAndroid Build Coastguard Worker int targetSdkVersion = android_get_application_target_sdk_version();
916*ec779b8eSAndroid Build Coastguard Worker
917*ec779b8eSAndroid Build Coastguard Worker AttributionSourceState clientAttribution;
918*ec779b8eSAndroid Build Coastguard Worker clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
919*ec779b8eSAndroid Build Coastguard Worker clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
920*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId = mDeviceContext.deviceId;
921*ec779b8eSAndroid Build Coastguard Worker clientAttribution.packageName = "";
922*ec779b8eSAndroid Build Coastguard Worker clientAttribution.attributionTag = std::nullopt;
923*ec779b8eSAndroid Build Coastguard Worker clientAttribution.token = sp<BBinder>::make();
924*ec779b8eSAndroid Build Coastguard Worker
925*ec779b8eSAndroid Build Coastguard Worker // No way to get package name from native.
926*ec779b8eSAndroid Build Coastguard Worker // Send a zero length package name and let camera service figure it out from UID
927*ec779b8eSAndroid Build Coastguard Worker binder::Status serviceRet = cs->connectDevice(
928*ec779b8eSAndroid Build Coastguard Worker callbacks, cameraId, /*oomScoreOffset*/0,
929*ec779b8eSAndroid Build Coastguard Worker targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
930*ec779b8eSAndroid Build Coastguard Worker clientAttribution, static_cast<int32_t>(mDeviceContext.policy), sharedMode,
931*ec779b8eSAndroid Build Coastguard Worker /*out*/&deviceRemote);
932*ec779b8eSAndroid Build Coastguard Worker
933*ec779b8eSAndroid Build Coastguard Worker if (!serviceRet.isOk()) {
934*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
935*ec779b8eSAndroid Build Coastguard Worker // Convert serviceRet to camera_status_t
936*ec779b8eSAndroid Build Coastguard Worker switch(serviceRet.serviceSpecificErrorCode()) {
937*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_DISCONNECTED:
938*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
939*ec779b8eSAndroid Build Coastguard Worker break;
940*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_CAMERA_IN_USE:
941*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_CAMERA_IN_USE;
942*ec779b8eSAndroid Build Coastguard Worker break;
943*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
944*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
945*ec779b8eSAndroid Build Coastguard Worker break;
946*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
947*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_INVALID_PARAMETER;
948*ec779b8eSAndroid Build Coastguard Worker break;
949*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_DEPRECATED_HAL:
950*ec779b8eSAndroid Build Coastguard Worker // Should not reach here since we filtered legacy HALs earlier
951*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_INVALID_PARAMETER;
952*ec779b8eSAndroid Build Coastguard Worker break;
953*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_DISABLED:
954*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_CAMERA_DISABLED;
955*ec779b8eSAndroid Build Coastguard Worker break;
956*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_PERMISSION_DENIED:
957*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_PERMISSION_DENIED;
958*ec779b8eSAndroid Build Coastguard Worker break;
959*ec779b8eSAndroid Build Coastguard Worker case hardware::ICameraService::ERROR_INVALID_OPERATION:
960*ec779b8eSAndroid Build Coastguard Worker default:
961*ec779b8eSAndroid Build Coastguard Worker ret = ACAMERA_ERROR_UNKNOWN;
962*ec779b8eSAndroid Build Coastguard Worker break;
963*ec779b8eSAndroid Build Coastguard Worker }
964*ec779b8eSAndroid Build Coastguard Worker
965*ec779b8eSAndroid Build Coastguard Worker delete device;
966*ec779b8eSAndroid Build Coastguard Worker return ret;
967*ec779b8eSAndroid Build Coastguard Worker }
968*ec779b8eSAndroid Build Coastguard Worker if (deviceRemote == nullptr) {
969*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
970*ec779b8eSAndroid Build Coastguard Worker delete device;
971*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_CAMERA_DISCONNECTED;
972*ec779b8eSAndroid Build Coastguard Worker }
973*ec779b8eSAndroid Build Coastguard Worker device->setRemoteDevice(deviceRemote);
974*ec779b8eSAndroid Build Coastguard Worker device->setDeviceMetadataQueues();
975*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_multi_client() && sharedMode) {
976*ec779b8eSAndroid Build Coastguard Worker binder::Status remoteRet = deviceRemote->isPrimaryClient(primaryClient);
977*ec779b8eSAndroid Build Coastguard Worker if (!remoteRet.isOk()) {
978*ec779b8eSAndroid Build Coastguard Worker delete device;
979*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_ERROR_UNKNOWN;
980*ec779b8eSAndroid Build Coastguard Worker }
981*ec779b8eSAndroid Build Coastguard Worker device->setPrimaryClient(*primaryClient);
982*ec779b8eSAndroid Build Coastguard Worker }
983*ec779b8eSAndroid Build Coastguard Worker *outDevice = device;
984*ec779b8eSAndroid Build Coastguard Worker return ACAMERA_OK;
985*ec779b8eSAndroid Build Coastguard Worker }
986*ec779b8eSAndroid Build Coastguard Worker
registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks * callback)987*ec779b8eSAndroid Build Coastguard Worker void ACameraManager::registerAvailabilityCallback(
988*ec779b8eSAndroid Build Coastguard Worker const ACameraManager_AvailabilityCallbacks* callback) {
989*ec779b8eSAndroid Build Coastguard Worker mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback);
990*ec779b8eSAndroid Build Coastguard Worker }
991*ec779b8eSAndroid Build Coastguard Worker
unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks * callback)992*ec779b8eSAndroid Build Coastguard Worker void ACameraManager::unregisterAvailabilityCallback(
993*ec779b8eSAndroid Build Coastguard Worker const ACameraManager_AvailabilityCallbacks* callback) {
994*ec779b8eSAndroid Build Coastguard Worker mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback);
995*ec779b8eSAndroid Build Coastguard Worker }
996*ec779b8eSAndroid Build Coastguard Worker
registerExtendedAvailabilityCallback(const ACameraManager_ExtendedAvailabilityCallbacks * callback)997*ec779b8eSAndroid Build Coastguard Worker void ACameraManager::registerExtendedAvailabilityCallback(
998*ec779b8eSAndroid Build Coastguard Worker const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
999*ec779b8eSAndroid Build Coastguard Worker mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback);
1000*ec779b8eSAndroid Build Coastguard Worker }
1001*ec779b8eSAndroid Build Coastguard Worker
unregisterExtendedAvailabilityCallback(const ACameraManager_ExtendedAvailabilityCallbacks * callback)1002*ec779b8eSAndroid Build Coastguard Worker void ACameraManager::unregisterExtendedAvailabilityCallback(
1003*ec779b8eSAndroid Build Coastguard Worker const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
1004*ec779b8eSAndroid Build Coastguard Worker mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback);
1005*ec779b8eSAndroid Build Coastguard Worker }
1006