xref: /aosp_15_r20/frameworks/av/camera/ndk/impl/ACameraManager.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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