1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2008 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_TAG "CameraService"
18*ec779b8eSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_CAMERA
19*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include <algorithm>
22*ec779b8eSAndroid Build Coastguard Worker #include <climits>
23*ec779b8eSAndroid Build Coastguard Worker #include <stdio.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <cstdlib>
25*ec779b8eSAndroid Build Coastguard Worker #include <cstring>
26*ec779b8eSAndroid Build Coastguard Worker #include <ctime>
27*ec779b8eSAndroid Build Coastguard Worker #include <iostream>
28*ec779b8eSAndroid Build Coastguard Worker #include <sstream>
29*ec779b8eSAndroid Build Coastguard Worker #include <string>
30*ec779b8eSAndroid Build Coastguard Worker #include <sys/types.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <inttypes.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <pthread.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <poll.h>
34*ec779b8eSAndroid Build Coastguard Worker
35*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/ICamera.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/ICameraClient.h>
37*ec779b8eSAndroid Build Coastguard Worker
38*ec779b8eSAndroid Build Coastguard Worker #include <aidl/AidlCameraService.h>
39*ec779b8eSAndroid Build Coastguard Worker #include <android-base/macros.h>
40*ec779b8eSAndroid Build Coastguard Worker #include <android-base/parseint.h>
41*ec779b8eSAndroid Build Coastguard Worker #include <android_companion_virtualdevice_flags.h>
42*ec779b8eSAndroid Build Coastguard Worker #include <android/companion/virtualnative/IVirtualDeviceManagerNative.h>
43*ec779b8eSAndroid Build Coastguard Worker #include <binder/ActivityManager.h>
44*ec779b8eSAndroid Build Coastguard Worker #include <binder/AppOpsManager.h>
45*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
46*ec779b8eSAndroid Build Coastguard Worker #include <binder/MemoryBase.h>
47*ec779b8eSAndroid Build Coastguard Worker #include <binder/MemoryHeapBase.h>
48*ec779b8eSAndroid Build Coastguard Worker #include <binder/PermissionController.h>
49*ec779b8eSAndroid Build Coastguard Worker #include <binder/IResultReceiver.h>
50*ec779b8eSAndroid Build Coastguard Worker #include <binderthreadstate/CallerUtils.h>
51*ec779b8eSAndroid Build Coastguard Worker #include <com_android_internal_camera_flags.h>
52*ec779b8eSAndroid Build Coastguard Worker #include <cutils/atomic.h>
53*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
54*ec779b8eSAndroid Build Coastguard Worker #include <cutils/misc.h>
55*ec779b8eSAndroid Build Coastguard Worker #include <gui/Surface.h>
56*ec779b8eSAndroid Build Coastguard Worker #include <hardware/hardware.h>
57*ec779b8eSAndroid Build Coastguard Worker #include "hidl/HidlCameraService.h"
58*ec779b8eSAndroid Build Coastguard Worker #include <hidl/HidlTransportSupport.h>
59*ec779b8eSAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
60*ec779b8eSAndroid Build Coastguard Worker #include <memunreachable/memunreachable.h>
61*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioSystem.h>
62*ec779b8eSAndroid Build Coastguard Worker #include <media/IMediaHTTPService.h>
63*ec779b8eSAndroid Build Coastguard Worker #include <media/mediaplayer.h>
64*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/BatteryNotifier.h>
65*ec779b8eSAndroid Build Coastguard Worker #include <processinfo/ProcessInfoService.h>
66*ec779b8eSAndroid Build Coastguard Worker #include <utils/Errors.h>
67*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
68*ec779b8eSAndroid Build Coastguard Worker #include <utils/String16.h>
69*ec779b8eSAndroid Build Coastguard Worker #include <utils/SystemClock.h>
70*ec779b8eSAndroid Build Coastguard Worker #include <utils/Trace.h>
71*ec779b8eSAndroid Build Coastguard Worker #include <utils/CallStack.h>
72*ec779b8eSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
73*ec779b8eSAndroid Build Coastguard Worker #include <system/camera_vendor_tags.h>
74*ec779b8eSAndroid Build Coastguard Worker #include <system/camera_metadata.h>
75*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
76*ec779b8eSAndroid Build Coastguard Worker #include <binder/IActivityManager.h>
77*ec779b8eSAndroid Build Coastguard Worker #include <camera/CameraUtils.h>
78*ec779b8eSAndroid Build Coastguard Worker #include <camera/StringUtils.h>
79*ec779b8eSAndroid Build Coastguard Worker
80*ec779b8eSAndroid Build Coastguard Worker #include <system/camera.h>
81*ec779b8eSAndroid Build Coastguard Worker
82*ec779b8eSAndroid Build Coastguard Worker #include "CameraService.h"
83*ec779b8eSAndroid Build Coastguard Worker #include "api1/Camera2Client.h"
84*ec779b8eSAndroid Build Coastguard Worker #include "api2/CameraDeviceClient.h"
85*ec779b8eSAndroid Build Coastguard Worker #include "utils/CameraServiceProxyWrapper.h"
86*ec779b8eSAndroid Build Coastguard Worker #include "utils/CameraTraces.h"
87*ec779b8eSAndroid Build Coastguard Worker #include "utils/SessionConfigurationUtils.h"
88*ec779b8eSAndroid Build Coastguard Worker #include "utils/TagMonitor.h"
89*ec779b8eSAndroid Build Coastguard Worker #include "utils/Utils.h"
90*ec779b8eSAndroid Build Coastguard Worker
91*ec779b8eSAndroid Build Coastguard Worker namespace {
92*ec779b8eSAndroid Build Coastguard Worker const char* kActivityServiceName = "activity";
93*ec779b8eSAndroid Build Coastguard Worker const char* kSensorPrivacyServiceName = "sensor_privacy";
94*ec779b8eSAndroid Build Coastguard Worker const char* kAppopsServiceName = "appops";
95*ec779b8eSAndroid Build Coastguard Worker const char* kProcessInfoServiceName = "processinfo";
96*ec779b8eSAndroid Build Coastguard Worker const char* kVirtualDeviceBackCameraId = "0";
97*ec779b8eSAndroid Build Coastguard Worker const char* kVirtualDeviceFrontCameraId = "1";
98*ec779b8eSAndroid Build Coastguard Worker const char* kUnknownPackageName = "<unknown>";
99*ec779b8eSAndroid Build Coastguard Worker
getDeviceId(const android::CameraMetadata & cameraInfo)100*ec779b8eSAndroid Build Coastguard Worker int32_t getDeviceId(const android::CameraMetadata& cameraInfo) {
101*ec779b8eSAndroid Build Coastguard Worker if (!cameraInfo.exists(ANDROID_INFO_DEVICE_ID)) {
102*ec779b8eSAndroid Build Coastguard Worker return android::kDefaultDeviceId;
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker
105*ec779b8eSAndroid Build Coastguard Worker const auto &deviceIdEntry = cameraInfo.find(ANDROID_INFO_DEVICE_ID);
106*ec779b8eSAndroid Build Coastguard Worker return deviceIdEntry.data.i32[0];
107*ec779b8eSAndroid Build Coastguard Worker }
108*ec779b8eSAndroid Build Coastguard Worker
appOpModeToPermissionResult(int32_t res)109*ec779b8eSAndroid Build Coastguard Worker static android::PermissionChecker::PermissionResult appOpModeToPermissionResult(int32_t res) {
110*ec779b8eSAndroid Build Coastguard Worker switch (res) {
111*ec779b8eSAndroid Build Coastguard Worker case android::AppOpsManager::MODE_ERRORED:
112*ec779b8eSAndroid Build Coastguard Worker return android::PermissionChecker::PERMISSION_HARD_DENIED;
113*ec779b8eSAndroid Build Coastguard Worker case android::AppOpsManager::MODE_IGNORED:
114*ec779b8eSAndroid Build Coastguard Worker return android::PermissionChecker::PERMISSION_SOFT_DENIED;
115*ec779b8eSAndroid Build Coastguard Worker case android::AppOpsManager::MODE_ALLOWED:
116*ec779b8eSAndroid Build Coastguard Worker return android::PermissionChecker::PERMISSION_GRANTED;
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker
119*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unexpected appOpMode %d", __FUNCTION__, res);
120*ec779b8eSAndroid Build Coastguard Worker return android::PermissionChecker::PERMISSION_HARD_DENIED;
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker } // namespace anonymous
123*ec779b8eSAndroid Build Coastguard Worker
124*ec779b8eSAndroid Build Coastguard Worker namespace android {
125*ec779b8eSAndroid Build Coastguard Worker
126*ec779b8eSAndroid Build Coastguard Worker using namespace camera3;
127*ec779b8eSAndroid Build Coastguard Worker using namespace camera3::SessionConfigurationUtils;
128*ec779b8eSAndroid Build Coastguard Worker
129*ec779b8eSAndroid Build Coastguard Worker using binder::Status;
130*ec779b8eSAndroid Build Coastguard Worker using companion::virtualnative::IVirtualDeviceManagerNative;
131*ec779b8eSAndroid Build Coastguard Worker using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
132*ec779b8eSAndroid Build Coastguard Worker using frameworks::cameraservice::service::implementation::AidlCameraService;
133*ec779b8eSAndroid Build Coastguard Worker using hardware::ICamera;
134*ec779b8eSAndroid Build Coastguard Worker using hardware::ICameraClient;
135*ec779b8eSAndroid Build Coastguard Worker using hardware::ICameraServiceListener;
136*ec779b8eSAndroid Build Coastguard Worker using hardware::camera2::ICameraInjectionCallback;
137*ec779b8eSAndroid Build Coastguard Worker using hardware::camera2::ICameraInjectionSession;
138*ec779b8eSAndroid Build Coastguard Worker using hardware::camera2::utils::CameraIdAndSessionConfiguration;
139*ec779b8eSAndroid Build Coastguard Worker using hardware::camera2::utils::ConcurrentCameraIdCombination;
140*ec779b8eSAndroid Build Coastguard Worker
141*ec779b8eSAndroid Build Coastguard Worker namespace flags = com::android::internal::camera::flags;
142*ec779b8eSAndroid Build Coastguard Worker namespace vd_flags = android::companion::virtualdevice::flags;
143*ec779b8eSAndroid Build Coastguard Worker
144*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
145*ec779b8eSAndroid Build Coastguard Worker // Logging support -- this is for debugging only
146*ec779b8eSAndroid Build Coastguard Worker // Use "adb shell dumpsys media.camera -v 1" to change it.
147*ec779b8eSAndroid Build Coastguard Worker volatile int32_t gLogLevel = 0;
148*ec779b8eSAndroid Build Coastguard Worker
149*ec779b8eSAndroid Build Coastguard Worker #define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
150*ec779b8eSAndroid Build Coastguard Worker #define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
151*ec779b8eSAndroid Build Coastguard Worker
setLogLevel(int level)152*ec779b8eSAndroid Build Coastguard Worker static void setLogLevel(int level) {
153*ec779b8eSAndroid Build Coastguard Worker android_atomic_write(level, &gLogLevel);
154*ec779b8eSAndroid Build Coastguard Worker }
155*ec779b8eSAndroid Build Coastguard Worker
format_as(CameraService::StatusInternal s)156*ec779b8eSAndroid Build Coastguard Worker int32_t format_as(CameraService::StatusInternal s) {
157*ec779b8eSAndroid Build Coastguard Worker return fmt::underlying(s);
158*ec779b8eSAndroid Build Coastguard Worker }
159*ec779b8eSAndroid Build Coastguard Worker
160*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
161*ec779b8eSAndroid Build Coastguard Worker
162*ec779b8eSAndroid Build Coastguard Worker // Permission strings (references to AttributionAndPermissionUtils for brevity)
163*ec779b8eSAndroid Build Coastguard Worker static const std::string &sDumpPermission =
164*ec779b8eSAndroid Build Coastguard Worker AttributionAndPermissionUtils::sDumpPermission;
165*ec779b8eSAndroid Build Coastguard Worker static const std::string &sManageCameraPermission =
166*ec779b8eSAndroid Build Coastguard Worker AttributionAndPermissionUtils::sManageCameraPermission;
167*ec779b8eSAndroid Build Coastguard Worker static const std::string &sCameraSendSystemEventsPermission =
168*ec779b8eSAndroid Build Coastguard Worker AttributionAndPermissionUtils::sCameraSendSystemEventsPermission;
169*ec779b8eSAndroid Build Coastguard Worker static const std::string &sCameraInjectExternalCameraPermission =
170*ec779b8eSAndroid Build Coastguard Worker AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission;
171*ec779b8eSAndroid Build Coastguard Worker
172*ec779b8eSAndroid Build Coastguard Worker // Constant integer for FGS Logging, used to denote the API type for logger
173*ec779b8eSAndroid Build Coastguard Worker static const int LOG_FGS_CAMERA_API = 1;
174*ec779b8eSAndroid Build Coastguard Worker const char *sFileName = "lastOpenSessionDumpFile";
175*ec779b8eSAndroid Build Coastguard Worker static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ;
176*ec779b8eSAndroid Build Coastguard Worker static constexpr int32_t kSystemNativeClientState =
177*ec779b8eSAndroid Build Coastguard Worker ActivityManager::PROCESS_STATE_PERSISTENT_UI;
178*ec779b8eSAndroid Build Coastguard Worker static const std::string kServiceName("cameraserver");
179*ec779b8eSAndroid Build Coastguard Worker
180*ec779b8eSAndroid Build Coastguard Worker const std::string CameraService::kOfflineDevice("offline-");
181*ec779b8eSAndroid Build Coastguard Worker const std::string CameraService::kWatchAllClientsFlag("all");
182*ec779b8eSAndroid Build Coastguard Worker
183*ec779b8eSAndroid Build Coastguard Worker constexpr int32_t kInvalidDeviceId = -1;
184*ec779b8eSAndroid Build Coastguard Worker
185*ec779b8eSAndroid Build Coastguard Worker // Set to keep track of logged service error events.
186*ec779b8eSAndroid Build Coastguard Worker static std::set<std::string> sServiceErrorEventSet;
187*ec779b8eSAndroid Build Coastguard Worker
CameraService(std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)188*ec779b8eSAndroid Build Coastguard Worker CameraService::CameraService(
189*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
190*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils) :
191*ec779b8eSAndroid Build Coastguard Worker AttributionAndPermissionUtilsEncapsulator(attributionAndPermissionUtils == nullptr ?
192*ec779b8eSAndroid Build Coastguard Worker std::make_shared<AttributionAndPermissionUtils>()\
193*ec779b8eSAndroid Build Coastguard Worker : attributionAndPermissionUtils),
194*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper(cameraServiceProxyWrapper == nullptr ?
195*ec779b8eSAndroid Build Coastguard Worker std::make_shared<CameraServiceProxyWrapper>() : cameraServiceProxyWrapper),
196*ec779b8eSAndroid Build Coastguard Worker mEventLog(DEFAULT_EVENT_LOG_LENGTH),
197*ec779b8eSAndroid Build Coastguard Worker mNumberOfCameras(0),
198*ec779b8eSAndroid Build Coastguard Worker mNumberOfCamerasWithoutSystemCamera(0),
199*ec779b8eSAndroid Build Coastguard Worker mSoundRef(0), mInitialized(false),
200*ec779b8eSAndroid Build Coastguard Worker mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
201*ec779b8eSAndroid Build Coastguard Worker ALOGI("CameraService started (pid=%d)", getpid());
202*ec779b8eSAndroid Build Coastguard Worker mAttributionAndPermissionUtils->setCameraService(this);
203*ec779b8eSAndroid Build Coastguard Worker mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
204*ec779b8eSAndroid Build Coastguard Worker mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
205*ec779b8eSAndroid Build Coastguard Worker if (mMemFd == -1) {
206*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName);
207*ec779b8eSAndroid Build Coastguard Worker }
208*ec779b8eSAndroid Build Coastguard Worker }
209*ec779b8eSAndroid Build Coastguard Worker
210*ec779b8eSAndroid Build Coastguard Worker // Enable processes with isolated AID to request the binder
instantiate()211*ec779b8eSAndroid Build Coastguard Worker void CameraService::instantiate() {
212*ec779b8eSAndroid Build Coastguard Worker CameraService::publish(true);
213*ec779b8eSAndroid Build Coastguard Worker }
214*ec779b8eSAndroid Build Coastguard Worker
onServiceRegistration(const String16 & name,const sp<IBinder> &)215*ec779b8eSAndroid Build Coastguard Worker void CameraService::onServiceRegistration(const String16& name, const sp<IBinder>&) {
216*ec779b8eSAndroid Build Coastguard Worker if (name != toString16(kAppopsServiceName)) {
217*ec779b8eSAndroid Build Coastguard Worker return;
218*ec779b8eSAndroid Build Coastguard Worker }
219*ec779b8eSAndroid Build Coastguard Worker
220*ec779b8eSAndroid Build Coastguard Worker ALOGV("appops service registered. setting camera audio restriction");
221*ec779b8eSAndroid Build Coastguard Worker mAppOps.setCameraAudioRestriction(mAudioRestriction);
222*ec779b8eSAndroid Build Coastguard Worker }
223*ec779b8eSAndroid Build Coastguard Worker
onFirstRef()224*ec779b8eSAndroid Build Coastguard Worker void CameraService::onFirstRef()
225*ec779b8eSAndroid Build Coastguard Worker {
226*ec779b8eSAndroid Build Coastguard Worker ALOGI("CameraService process starting");
227*ec779b8eSAndroid Build Coastguard Worker
228*ec779b8eSAndroid Build Coastguard Worker BnCameraService::onFirstRef();
229*ec779b8eSAndroid Build Coastguard Worker
230*ec779b8eSAndroid Build Coastguard Worker // Update battery life tracking if service is restarting
231*ec779b8eSAndroid Build Coastguard Worker BatteryNotifier& notifier(BatteryNotifier::getInstance());
232*ec779b8eSAndroid Build Coastguard Worker notifier.noteResetCamera();
233*ec779b8eSAndroid Build Coastguard Worker notifier.noteResetFlashlight();
234*ec779b8eSAndroid Build Coastguard Worker
235*ec779b8eSAndroid Build Coastguard Worker status_t res = INVALID_OPERATION;
236*ec779b8eSAndroid Build Coastguard Worker
237*ec779b8eSAndroid Build Coastguard Worker res = enumerateProviders();
238*ec779b8eSAndroid Build Coastguard Worker if (res == OK) {
239*ec779b8eSAndroid Build Coastguard Worker mInitialized = true;
240*ec779b8eSAndroid Build Coastguard Worker }
241*ec779b8eSAndroid Build Coastguard Worker
242*ec779b8eSAndroid Build Coastguard Worker mUidPolicy = new UidPolicy(this);
243*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->registerSelf();
244*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy = new SensorPrivacyPolicy(this, mAttributionAndPermissionUtils);
245*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy->registerSelf();
246*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener = new InjectionStatusListener(this);
247*ec779b8eSAndroid Build Coastguard Worker
248*ec779b8eSAndroid Build Coastguard Worker // appops function setCamerAudioRestriction uses getService which
249*ec779b8eSAndroid Build Coastguard Worker // is blocking till the appops service is ready. To enable early
250*ec779b8eSAndroid Build Coastguard Worker // boot availability for cameraservice, use checkService which is
251*ec779b8eSAndroid Build Coastguard Worker // non blocking and register for notifications
252*ec779b8eSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
253*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = sm->checkService(toString16(kAppopsServiceName));
254*ec779b8eSAndroid Build Coastguard Worker if (!binder) {
255*ec779b8eSAndroid Build Coastguard Worker sm->registerForNotifications(toString16(kAppopsServiceName), this);
256*ec779b8eSAndroid Build Coastguard Worker } else {
257*ec779b8eSAndroid Build Coastguard Worker mAppOps.setCameraAudioRestriction(mAudioRestriction);
258*ec779b8eSAndroid Build Coastguard Worker }
259*ec779b8eSAndroid Build Coastguard Worker
260*ec779b8eSAndroid Build Coastguard Worker sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
261*ec779b8eSAndroid Build Coastguard Worker if (hcs->registerAsService() != android::OK) {
262*ec779b8eSAndroid Build Coastguard Worker // Deprecated, so it will fail to register on newer devices
263*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Did not register default [email protected]",
264*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
265*ec779b8eSAndroid Build Coastguard Worker }
266*ec779b8eSAndroid Build Coastguard Worker
267*ec779b8eSAndroid Build Coastguard Worker if (!AidlCameraService::registerService(this)) {
268*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to register default AIDL VNDK CameraService", __FUNCTION__);
269*ec779b8eSAndroid Build Coastguard Worker }
270*ec779b8eSAndroid Build Coastguard Worker
271*ec779b8eSAndroid Build Coastguard Worker // This needs to be last call in this function, so that it's as close to
272*ec779b8eSAndroid Build Coastguard Worker // ServiceManager::addService() as possible.
273*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->pingCameraServiceProxy();
274*ec779b8eSAndroid Build Coastguard Worker ALOGI("CameraService pinged cameraservice proxy");
275*ec779b8eSAndroid Build Coastguard Worker }
276*ec779b8eSAndroid Build Coastguard Worker
enumerateProviders()277*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::enumerateProviders() {
278*ec779b8eSAndroid Build Coastguard Worker status_t res;
279*ec779b8eSAndroid Build Coastguard Worker
280*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> deviceIds;
281*ec779b8eSAndroid Build Coastguard Worker std::unordered_map<std::string, std::set<std::string>> unavailPhysicalIds;
282*ec779b8eSAndroid Build Coastguard Worker {
283*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mServiceLock);
284*ec779b8eSAndroid Build Coastguard Worker
285*ec779b8eSAndroid Build Coastguard Worker if (nullptr == mCameraProviderManager.get()) {
286*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager = new CameraProviderManager();
287*ec779b8eSAndroid Build Coastguard Worker res = mCameraProviderManager->initialize(this);
288*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
289*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
290*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, strerror(-res), res);
291*ec779b8eSAndroid Build Coastguard Worker logServiceError("Unable to initialize camera provider manager",
292*ec779b8eSAndroid Build Coastguard Worker ERROR_DISCONNECTED);
293*ec779b8eSAndroid Build Coastguard Worker return res;
294*ec779b8eSAndroid Build Coastguard Worker }
295*ec779b8eSAndroid Build Coastguard Worker }
296*ec779b8eSAndroid Build Coastguard Worker
297*ec779b8eSAndroid Build Coastguard Worker // Setup vendor tags before we call get_camera_info the first time
298*ec779b8eSAndroid Build Coastguard Worker // because HAL might need to setup static vendor keys in get_camera_info
299*ec779b8eSAndroid Build Coastguard Worker // TODO: maybe put this into CameraProviderManager::initialize()?
300*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->setUpVendorTags();
301*ec779b8eSAndroid Build Coastguard Worker
302*ec779b8eSAndroid Build Coastguard Worker if (nullptr == mFlashlight.get()) {
303*ec779b8eSAndroid Build Coastguard Worker mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
304*ec779b8eSAndroid Build Coastguard Worker }
305*ec779b8eSAndroid Build Coastguard Worker
306*ec779b8eSAndroid Build Coastguard Worker res = mFlashlight->findFlashUnits();
307*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
308*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
309*ec779b8eSAndroid Build Coastguard Worker }
310*ec779b8eSAndroid Build Coastguard Worker
311*ec779b8eSAndroid Build Coastguard Worker deviceIds = mCameraProviderManager->getCameraDeviceIds(&unavailPhysicalIds);
312*ec779b8eSAndroid Build Coastguard Worker }
313*ec779b8eSAndroid Build Coastguard Worker
314*ec779b8eSAndroid Build Coastguard Worker for (auto& cameraId : deviceIds) {
315*ec779b8eSAndroid Build Coastguard Worker if (getCameraState(cameraId) == nullptr) {
316*ec779b8eSAndroid Build Coastguard Worker onDeviceStatusChanged(cameraId, CameraDeviceStatus::PRESENT);
317*ec779b8eSAndroid Build Coastguard Worker }
318*ec779b8eSAndroid Build Coastguard Worker if (unavailPhysicalIds.count(cameraId) > 0) {
319*ec779b8eSAndroid Build Coastguard Worker for (const auto& physicalId : unavailPhysicalIds[cameraId]) {
320*ec779b8eSAndroid Build Coastguard Worker onDeviceStatusChanged(cameraId, physicalId, CameraDeviceStatus::NOT_PRESENT);
321*ec779b8eSAndroid Build Coastguard Worker }
322*ec779b8eSAndroid Build Coastguard Worker }
323*ec779b8eSAndroid Build Coastguard Worker }
324*ec779b8eSAndroid Build Coastguard Worker
325*ec779b8eSAndroid Build Coastguard Worker // Derive primary rear/front cameras, and filter their charactierstics.
326*ec779b8eSAndroid Build Coastguard Worker // This needs to be done after all cameras are enumerated and camera ids are sorted.
327*ec779b8eSAndroid Build Coastguard Worker if (SessionConfigurationUtils::IS_PERF_CLASS) {
328*ec779b8eSAndroid Build Coastguard Worker // Assume internal cameras are advertised from the same
329*ec779b8eSAndroid Build Coastguard Worker // provider. If multiple providers are registered at different time,
330*ec779b8eSAndroid Build Coastguard Worker // and each provider contains multiple internal color cameras, the current
331*ec779b8eSAndroid Build Coastguard Worker // logic may filter the characteristics of more than one front/rear color
332*ec779b8eSAndroid Build Coastguard Worker // cameras.
333*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mServiceLock);
334*ec779b8eSAndroid Build Coastguard Worker filterSPerfClassCharacteristicsLocked();
335*ec779b8eSAndroid Build Coastguard Worker }
336*ec779b8eSAndroid Build Coastguard Worker
337*ec779b8eSAndroid Build Coastguard Worker return OK;
338*ec779b8eSAndroid Build Coastguard Worker }
339*ec779b8eSAndroid Build Coastguard Worker
broadcastTorchModeStatus(const std::string & cameraId,TorchModeStatus status,SystemCameraKind systemCameraKind)340*ec779b8eSAndroid Build Coastguard Worker void CameraService::broadcastTorchModeStatus(const std::string& cameraId, TorchModeStatus status,
341*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind systemCameraKind) {
342*ec779b8eSAndroid Build Coastguard Worker // Get the device id and app-visible camera id for the given HAL-visible camera id.
343*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, mappedCameraId] =
344*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
345*ec779b8eSAndroid Build Coastguard Worker
346*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
347*ec779b8eSAndroid Build Coastguard Worker for (auto& i : mListenerList) {
348*ec779b8eSAndroid Build Coastguard Worker if (shouldSkipStatusUpdates(systemCameraKind, i->isVendorListener(), i->getListenerPid(),
349*ec779b8eSAndroid Build Coastguard Worker i->getListenerUid())) {
350*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Skipping torch callback for system-only camera device %s",
351*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
352*ec779b8eSAndroid Build Coastguard Worker continue;
353*ec779b8eSAndroid Build Coastguard Worker }
354*ec779b8eSAndroid Build Coastguard Worker
355*ec779b8eSAndroid Build Coastguard Worker auto ret = i->getListener()->onTorchStatusChanged(mapToInterface(status),
356*ec779b8eSAndroid Build Coastguard Worker mappedCameraId, deviceId);
357*ec779b8eSAndroid Build Coastguard Worker i->handleBinderStatus(ret, "%s: Failed to trigger onTorchStatusChanged for %d:%d: %d",
358*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
359*ec779b8eSAndroid Build Coastguard Worker }
360*ec779b8eSAndroid Build Coastguard Worker }
361*ec779b8eSAndroid Build Coastguard Worker
~CameraService()362*ec779b8eSAndroid Build Coastguard Worker CameraService::~CameraService() {
363*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptor::clearGlobalVendorTagDescriptor();
364*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->unregisterSelf();
365*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy->unregisterSelf();
366*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->removeListener();
367*ec779b8eSAndroid Build Coastguard Worker }
368*ec779b8eSAndroid Build Coastguard Worker
onNewProviderRegistered()369*ec779b8eSAndroid Build Coastguard Worker void CameraService::onNewProviderRegistered() {
370*ec779b8eSAndroid Build Coastguard Worker enumerateProviders();
371*ec779b8eSAndroid Build Coastguard Worker }
372*ec779b8eSAndroid Build Coastguard Worker
filterAPI1SystemCameraLocked(const std::vector<std::string> & normalDeviceIds)373*ec779b8eSAndroid Build Coastguard Worker void CameraService::filterAPI1SystemCameraLocked(
374*ec779b8eSAndroid Build Coastguard Worker const std::vector<std::string> &normalDeviceIds) {
375*ec779b8eSAndroid Build Coastguard Worker mNormalDeviceIdsWithoutSystemCamera.clear();
376*ec779b8eSAndroid Build Coastguard Worker for (auto &cameraId : normalDeviceIds) {
377*ec779b8eSAndroid Build Coastguard Worker if (vd_flags::camera_device_awareness()) {
378*ec779b8eSAndroid Build Coastguard Worker CameraMetadata cameraInfo;
379*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->getCameraCharacteristics(
380*ec779b8eSAndroid Build Coastguard Worker cameraId, false, &cameraInfo,
381*ec779b8eSAndroid Build Coastguard Worker hardware::ICameraService::ROTATION_OVERRIDE_NONE);
382*ec779b8eSAndroid Build Coastguard Worker int32_t deviceId = kDefaultDeviceId;
383*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
384*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Not able to get camera characteristics for camera id %s",
385*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
386*ec779b8eSAndroid Build Coastguard Worker } else {
387*ec779b8eSAndroid Build Coastguard Worker deviceId = getDeviceId(cameraInfo);
388*ec779b8eSAndroid Build Coastguard Worker }
389*ec779b8eSAndroid Build Coastguard Worker // Cameras associated with non-default device id's (i.e., virtual cameras) can never be
390*ec779b8eSAndroid Build Coastguard Worker // system cameras, so skip for non-default device id's.
391*ec779b8eSAndroid Build Coastguard Worker if (deviceId != kDefaultDeviceId) {
392*ec779b8eSAndroid Build Coastguard Worker continue;
393*ec779b8eSAndroid Build Coastguard Worker }
394*ec779b8eSAndroid Build Coastguard Worker }
395*ec779b8eSAndroid Build Coastguard Worker
396*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
397*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
398*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
399*ec779b8eSAndroid Build Coastguard Worker continue;
400*ec779b8eSAndroid Build Coastguard Worker }
401*ec779b8eSAndroid Build Coastguard Worker if (deviceKind == SystemCameraKind::SYSTEM_ONLY_CAMERA) {
402*ec779b8eSAndroid Build Coastguard Worker // All system camera ids will necessarily come after public camera
403*ec779b8eSAndroid Build Coastguard Worker // device ids as per the HAL interface contract.
404*ec779b8eSAndroid Build Coastguard Worker break;
405*ec779b8eSAndroid Build Coastguard Worker }
406*ec779b8eSAndroid Build Coastguard Worker mNormalDeviceIdsWithoutSystemCamera.push_back(cameraId);
407*ec779b8eSAndroid Build Coastguard Worker }
408*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: number of API1 compatible public cameras is %zu", __FUNCTION__,
409*ec779b8eSAndroid Build Coastguard Worker mNormalDeviceIdsWithoutSystemCamera.size());
410*ec779b8eSAndroid Build Coastguard Worker }
411*ec779b8eSAndroid Build Coastguard Worker
getSystemCameraKind(const std::string & cameraId,SystemCameraKind * kind) const412*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::getSystemCameraKind(const std::string& cameraId,
413*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind *kind) const {
414*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
415*ec779b8eSAndroid Build Coastguard Worker if (state != nullptr) {
416*ec779b8eSAndroid Build Coastguard Worker *kind = state->getSystemCameraKind();
417*ec779b8eSAndroid Build Coastguard Worker return OK;
418*ec779b8eSAndroid Build Coastguard Worker }
419*ec779b8eSAndroid Build Coastguard Worker // Hidden physical camera ids won't have CameraState
420*ec779b8eSAndroid Build Coastguard Worker return mCameraProviderManager->getSystemCameraKind(cameraId, kind);
421*ec779b8eSAndroid Build Coastguard Worker }
422*ec779b8eSAndroid Build Coastguard Worker
updateCameraNumAndIds()423*ec779b8eSAndroid Build Coastguard Worker void CameraService::updateCameraNumAndIds() {
424*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mServiceLock);
425*ec779b8eSAndroid Build Coastguard Worker std::pair<int, int> systemAndNonSystemCameras = mCameraProviderManager->getCameraCount();
426*ec779b8eSAndroid Build Coastguard Worker // Excludes hidden secure cameras
427*ec779b8eSAndroid Build Coastguard Worker mNumberOfCameras =
428*ec779b8eSAndroid Build Coastguard Worker systemAndNonSystemCameras.first + systemAndNonSystemCameras.second;
429*ec779b8eSAndroid Build Coastguard Worker mNumberOfCamerasWithoutSystemCamera = systemAndNonSystemCameras.second;
430*ec779b8eSAndroid Build Coastguard Worker mNormalDeviceIds =
431*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
432*ec779b8eSAndroid Build Coastguard Worker filterAPI1SystemCameraLocked(mNormalDeviceIds);
433*ec779b8eSAndroid Build Coastguard Worker }
434*ec779b8eSAndroid Build Coastguard Worker
filterSPerfClassCharacteristicsLocked()435*ec779b8eSAndroid Build Coastguard Worker void CameraService::filterSPerfClassCharacteristicsLocked() {
436*ec779b8eSAndroid Build Coastguard Worker // To claim to be S Performance primary cameras, the cameras must be
437*ec779b8eSAndroid Build Coastguard Worker // backward compatible. So performance class primary camera Ids must be API1
438*ec779b8eSAndroid Build Coastguard Worker // compatible.
439*ec779b8eSAndroid Build Coastguard Worker bool firstRearCameraSeen = false, firstFrontCameraSeen = false;
440*ec779b8eSAndroid Build Coastguard Worker for (const auto& cameraId : mNormalDeviceIdsWithoutSystemCamera) {
441*ec779b8eSAndroid Build Coastguard Worker int facing = -1;
442*ec779b8eSAndroid Build Coastguard Worker int orientation = 0;
443*ec779b8eSAndroid Build Coastguard Worker int portraitRotation;
444*ec779b8eSAndroid Build Coastguard Worker getDeviceVersion(cameraId,
445*ec779b8eSAndroid Build Coastguard Worker /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
446*ec779b8eSAndroid Build Coastguard Worker /*out*/&portraitRotation, /*out*/&facing, /*out*/&orientation);
447*ec779b8eSAndroid Build Coastguard Worker if (facing == -1) {
448*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
449*ec779b8eSAndroid Build Coastguard Worker return;
450*ec779b8eSAndroid Build Coastguard Worker }
451*ec779b8eSAndroid Build Coastguard Worker
452*ec779b8eSAndroid Build Coastguard Worker if ((facing == hardware::CAMERA_FACING_BACK && !firstRearCameraSeen) ||
453*ec779b8eSAndroid Build Coastguard Worker (facing == hardware::CAMERA_FACING_FRONT && !firstFrontCameraSeen)) {
454*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->filterSmallJpegSizes(cameraId);
455*ec779b8eSAndroid Build Coastguard Worker if (res == OK) {
456*ec779b8eSAndroid Build Coastguard Worker mPerfClassPrimaryCameraIds.insert(cameraId);
457*ec779b8eSAndroid Build Coastguard Worker } else {
458*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to filter small JPEG sizes for performance class primary "
459*ec779b8eSAndroid Build Coastguard Worker "camera %s: %s(%d)", __FUNCTION__, cameraId.c_str(), strerror(-res), res);
460*ec779b8eSAndroid Build Coastguard Worker break;
461*ec779b8eSAndroid Build Coastguard Worker }
462*ec779b8eSAndroid Build Coastguard Worker
463*ec779b8eSAndroid Build Coastguard Worker if (facing == hardware::CAMERA_FACING_BACK) {
464*ec779b8eSAndroid Build Coastguard Worker firstRearCameraSeen = true;
465*ec779b8eSAndroid Build Coastguard Worker }
466*ec779b8eSAndroid Build Coastguard Worker if (facing == hardware::CAMERA_FACING_FRONT) {
467*ec779b8eSAndroid Build Coastguard Worker firstFrontCameraSeen = true;
468*ec779b8eSAndroid Build Coastguard Worker }
469*ec779b8eSAndroid Build Coastguard Worker }
470*ec779b8eSAndroid Build Coastguard Worker
471*ec779b8eSAndroid Build Coastguard Worker if (firstRearCameraSeen && firstFrontCameraSeen) {
472*ec779b8eSAndroid Build Coastguard Worker break;
473*ec779b8eSAndroid Build Coastguard Worker }
474*ec779b8eSAndroid Build Coastguard Worker }
475*ec779b8eSAndroid Build Coastguard Worker }
476*ec779b8eSAndroid Build Coastguard Worker
addStates(const std::string & cameraId)477*ec779b8eSAndroid Build Coastguard Worker void CameraService::addStates(const std::string& cameraId) {
478*ec779b8eSAndroid Build Coastguard Worker CameraResourceCost cost;
479*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
480*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
481*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
482*ec779b8eSAndroid Build Coastguard Worker return;
483*ec779b8eSAndroid Build Coastguard Worker }
484*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
485*ec779b8eSAndroid Build Coastguard Worker res = mCameraProviderManager->getSystemCameraKind(cameraId, &deviceKind);
486*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
487*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to query device kind: %s (%d)", strerror(-res), res);
488*ec779b8eSAndroid Build Coastguard Worker return;
489*ec779b8eSAndroid Build Coastguard Worker }
490*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> physicalCameraIds;
491*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds);
492*ec779b8eSAndroid Build Coastguard Worker std::set<std::string> conflicting;
493*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
494*ec779b8eSAndroid Build Coastguard Worker conflicting.emplace(cost.conflictingDevices[i]);
495*ec779b8eSAndroid Build Coastguard Worker }
496*ec779b8eSAndroid Build Coastguard Worker
497*ec779b8eSAndroid Build Coastguard Worker {
498*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mCameraStatesLock);
499*ec779b8eSAndroid Build Coastguard Worker mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost.resourceCost,
500*ec779b8eSAndroid Build Coastguard Worker conflicting, deviceKind, physicalCameraIds));
501*ec779b8eSAndroid Build Coastguard Worker }
502*ec779b8eSAndroid Build Coastguard Worker
503*ec779b8eSAndroid Build Coastguard Worker if (mFlashlight->hasFlashUnit(cameraId)) {
504*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
505*ec779b8eSAndroid Build Coastguard Worker mTorchStatusMap.add(cameraId, TorchModeStatus::AVAILABLE_OFF);
506*ec779b8eSAndroid Build Coastguard Worker
507*ec779b8eSAndroid Build Coastguard Worker broadcastTorchModeStatus(cameraId, TorchModeStatus::AVAILABLE_OFF, deviceKind);
508*ec779b8eSAndroid Build Coastguard Worker }
509*ec779b8eSAndroid Build Coastguard Worker
510*ec779b8eSAndroid Build Coastguard Worker updateCameraNumAndIds();
511*ec779b8eSAndroid Build Coastguard Worker logDeviceAdded(cameraId, "Device added");
512*ec779b8eSAndroid Build Coastguard Worker }
513*ec779b8eSAndroid Build Coastguard Worker
removeStates(const std::string & cameraId)514*ec779b8eSAndroid Build Coastguard Worker void CameraService::removeStates(const std::string& cameraId) {
515*ec779b8eSAndroid Build Coastguard Worker updateCameraNumAndIds();
516*ec779b8eSAndroid Build Coastguard Worker if (mFlashlight->hasFlashUnit(cameraId)) {
517*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
518*ec779b8eSAndroid Build Coastguard Worker mTorchStatusMap.removeItem(cameraId);
519*ec779b8eSAndroid Build Coastguard Worker }
520*ec779b8eSAndroid Build Coastguard Worker
521*ec779b8eSAndroid Build Coastguard Worker {
522*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mCameraStatesLock);
523*ec779b8eSAndroid Build Coastguard Worker mCameraStates.erase(cameraId);
524*ec779b8eSAndroid Build Coastguard Worker }
525*ec779b8eSAndroid Build Coastguard Worker }
526*ec779b8eSAndroid Build Coastguard Worker
onDeviceStatusChanged(const std::string & cameraId,CameraDeviceStatus newHalStatus)527*ec779b8eSAndroid Build Coastguard Worker void CameraService::onDeviceStatusChanged(const std::string& cameraId,
528*ec779b8eSAndroid Build Coastguard Worker CameraDeviceStatus newHalStatus) {
529*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
530*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), eToI(newHalStatus));
531*ec779b8eSAndroid Build Coastguard Worker
532*ec779b8eSAndroid Build Coastguard Worker StatusInternal newStatus = mapToInternal(newHalStatus);
533*ec779b8eSAndroid Build Coastguard Worker
534*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<CameraState> state = getCameraState(cameraId);
535*ec779b8eSAndroid Build Coastguard Worker
536*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
537*ec779b8eSAndroid Build Coastguard Worker if (newStatus == StatusInternal::PRESENT) {
538*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Unknown camera ID %s, a new camera is added",
539*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
540*ec779b8eSAndroid Build Coastguard Worker
541*ec779b8eSAndroid Build Coastguard Worker // First add as absent to make sure clients are notified below
542*ec779b8eSAndroid Build Coastguard Worker addStates(cameraId);
543*ec779b8eSAndroid Build Coastguard Worker
544*ec779b8eSAndroid Build Coastguard Worker updateStatus(newStatus, cameraId);
545*ec779b8eSAndroid Build Coastguard Worker } else {
546*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Bad camera ID %s", __FUNCTION__, cameraId.c_str());
547*ec779b8eSAndroid Build Coastguard Worker }
548*ec779b8eSAndroid Build Coastguard Worker return;
549*ec779b8eSAndroid Build Coastguard Worker }
550*ec779b8eSAndroid Build Coastguard Worker
551*ec779b8eSAndroid Build Coastguard Worker StatusInternal oldStatus = state->getStatus();
552*ec779b8eSAndroid Build Coastguard Worker
553*ec779b8eSAndroid Build Coastguard Worker if (oldStatus == newStatus) {
554*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__,
555*ec779b8eSAndroid Build Coastguard Worker eToI(newStatus));
556*ec779b8eSAndroid Build Coastguard Worker return;
557*ec779b8eSAndroid Build Coastguard Worker }
558*ec779b8eSAndroid Build Coastguard Worker
559*ec779b8eSAndroid Build Coastguard Worker if (newStatus == StatusInternal::NOT_PRESENT) {
560*ec779b8eSAndroid Build Coastguard Worker logDeviceRemoved(cameraId, fmt::format("Device status changed from {} to {}",
561*ec779b8eSAndroid Build Coastguard Worker oldStatus, newStatus));
562*ec779b8eSAndroid Build Coastguard Worker // Set the device status to NOT_PRESENT, clients will no longer be able to connect
563*ec779b8eSAndroid Build Coastguard Worker // to this device until the status changes
564*ec779b8eSAndroid Build Coastguard Worker updateStatus(StatusInternal::NOT_PRESENT, cameraId);
565*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.removeCamera(cameraId);
566*ec779b8eSAndroid Build Coastguard Worker
567*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<BasicClient>> clientsToDisconnectOnline, clientsToDisconnectOffline;
568*ec779b8eSAndroid Build Coastguard Worker {
569*ec779b8eSAndroid Build Coastguard Worker // Don't do this in updateStatus to avoid deadlock over mServiceLock
570*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
571*ec779b8eSAndroid Build Coastguard Worker
572*ec779b8eSAndroid Build Coastguard Worker // Remove cached shim parameters
573*ec779b8eSAndroid Build Coastguard Worker state->setShimParams(CameraParameters());
574*ec779b8eSAndroid Build Coastguard Worker
575*ec779b8eSAndroid Build Coastguard Worker // Remove online as well as offline client from the list of active clients,
576*ec779b8eSAndroid Build Coastguard Worker // if they are present
577*ec779b8eSAndroid Build Coastguard Worker clientsToDisconnectOnline = removeClientsLocked(cameraId);
578*ec779b8eSAndroid Build Coastguard Worker clientsToDisconnectOffline = removeClientsLocked(kOfflineDevice + cameraId);
579*ec779b8eSAndroid Build Coastguard Worker }
580*ec779b8eSAndroid Build Coastguard Worker
581*ec779b8eSAndroid Build Coastguard Worker disconnectClients(cameraId, clientsToDisconnectOnline);
582*ec779b8eSAndroid Build Coastguard Worker disconnectClients(kOfflineDevice + cameraId, clientsToDisconnectOffline);
583*ec779b8eSAndroid Build Coastguard Worker
584*ec779b8eSAndroid Build Coastguard Worker removeStates(cameraId);
585*ec779b8eSAndroid Build Coastguard Worker } else {
586*ec779b8eSAndroid Build Coastguard Worker if (oldStatus == StatusInternal::NOT_PRESENT) {
587*ec779b8eSAndroid Build Coastguard Worker logDeviceAdded(cameraId, fmt::format("Device status changed from {} to {}",
588*ec779b8eSAndroid Build Coastguard Worker oldStatus, newStatus));
589*ec779b8eSAndroid Build Coastguard Worker }
590*ec779b8eSAndroid Build Coastguard Worker updateStatus(newStatus, cameraId);
591*ec779b8eSAndroid Build Coastguard Worker }
592*ec779b8eSAndroid Build Coastguard Worker }
593*ec779b8eSAndroid Build Coastguard Worker
onDeviceStatusChanged(const std::string & id,const std::string & physicalId,CameraDeviceStatus newHalStatus)594*ec779b8eSAndroid Build Coastguard Worker void CameraService::onDeviceStatusChanged(const std::string& id,
595*ec779b8eSAndroid Build Coastguard Worker const std::string& physicalId,
596*ec779b8eSAndroid Build Coastguard Worker CameraDeviceStatus newHalStatus) {
597*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d",
598*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, id.c_str(), physicalId.c_str(), eToI(newHalStatus));
599*ec779b8eSAndroid Build Coastguard Worker
600*ec779b8eSAndroid Build Coastguard Worker StatusInternal newStatus = mapToInternal(newHalStatus);
601*ec779b8eSAndroid Build Coastguard Worker
602*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<CameraState> state = getCameraState(id);
603*ec779b8eSAndroid Build Coastguard Worker
604*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
605*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Physical camera id %s status change on a non-present ID %s",
606*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, physicalId.c_str(), id.c_str());
607*ec779b8eSAndroid Build Coastguard Worker return;
608*ec779b8eSAndroid Build Coastguard Worker }
609*ec779b8eSAndroid Build Coastguard Worker
610*ec779b8eSAndroid Build Coastguard Worker StatusInternal logicalCameraStatus = state->getStatus();
611*ec779b8eSAndroid Build Coastguard Worker if (logicalCameraStatus != StatusInternal::PRESENT &&
612*ec779b8eSAndroid Build Coastguard Worker logicalCameraStatus != StatusInternal::NOT_AVAILABLE) {
613*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
614*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, physicalId.c_str(), eToI(newHalStatus), eToI(logicalCameraStatus));
615*ec779b8eSAndroid Build Coastguard Worker return;
616*ec779b8eSAndroid Build Coastguard Worker }
617*ec779b8eSAndroid Build Coastguard Worker
618*ec779b8eSAndroid Build Coastguard Worker bool updated = false;
619*ec779b8eSAndroid Build Coastguard Worker if (newStatus == StatusInternal::PRESENT) {
620*ec779b8eSAndroid Build Coastguard Worker updated = state->removeUnavailablePhysicalId(physicalId);
621*ec779b8eSAndroid Build Coastguard Worker } else {
622*ec779b8eSAndroid Build Coastguard Worker updated = state->addUnavailablePhysicalId(physicalId);
623*ec779b8eSAndroid Build Coastguard Worker }
624*ec779b8eSAndroid Build Coastguard Worker
625*ec779b8eSAndroid Build Coastguard Worker if (updated) {
626*ec779b8eSAndroid Build Coastguard Worker std::string idCombo = id + " : " + physicalId;
627*ec779b8eSAndroid Build Coastguard Worker if (newStatus == StatusInternal::PRESENT) {
628*ec779b8eSAndroid Build Coastguard Worker logDeviceAdded(idCombo, fmt::format("Device status changed to {}", newStatus));
629*ec779b8eSAndroid Build Coastguard Worker } else {
630*ec779b8eSAndroid Build Coastguard Worker logDeviceRemoved(idCombo, fmt::format("Device status changed to {}", newStatus));
631*ec779b8eSAndroid Build Coastguard Worker }
632*ec779b8eSAndroid Build Coastguard Worker // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
633*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
634*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(id, &deviceKind) != OK) {
635*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.c_str());
636*ec779b8eSAndroid Build Coastguard Worker return;
637*ec779b8eSAndroid Build Coastguard Worker }
638*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
639*ec779b8eSAndroid Build Coastguard Worker for (auto& listener : mListenerList) {
640*ec779b8eSAndroid Build Coastguard Worker if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
641*ec779b8eSAndroid Build Coastguard Worker listener->getListenerPid(), listener->getListenerUid())) {
642*ec779b8eSAndroid Build Coastguard Worker ALOGV("Skipping discovery callback for system-only camera device %s",
643*ec779b8eSAndroid Build Coastguard Worker id.c_str());
644*ec779b8eSAndroid Build Coastguard Worker continue;
645*ec779b8eSAndroid Build Coastguard Worker }
646*ec779b8eSAndroid Build Coastguard Worker auto ret = listener->getListener()->onPhysicalCameraStatusChanged(
647*ec779b8eSAndroid Build Coastguard Worker mapToInterface(newStatus), id, physicalId, kDefaultDeviceId);
648*ec779b8eSAndroid Build Coastguard Worker listener->handleBinderStatus(ret,
649*ec779b8eSAndroid Build Coastguard Worker "%s: Failed to trigger onPhysicalCameraStatusChanged for %d:%d: %d",
650*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
651*ec779b8eSAndroid Build Coastguard Worker ret.exceptionCode());
652*ec779b8eSAndroid Build Coastguard Worker }
653*ec779b8eSAndroid Build Coastguard Worker }
654*ec779b8eSAndroid Build Coastguard Worker }
655*ec779b8eSAndroid Build Coastguard Worker
disconnectClients(const std::string & id,std::vector<sp<BasicClient>> clientsToDisconnect)656*ec779b8eSAndroid Build Coastguard Worker void CameraService::disconnectClients(const std::string& id,
657*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<BasicClient>> clientsToDisconnect) {
658*ec779b8eSAndroid Build Coastguard Worker for (auto& client : clientsToDisconnect) {
659*ec779b8eSAndroid Build Coastguard Worker disconnectClient(id, client);
660*ec779b8eSAndroid Build Coastguard Worker }
661*ec779b8eSAndroid Build Coastguard Worker }
662*ec779b8eSAndroid Build Coastguard Worker
disconnectClient(const std::string & id,sp<BasicClient> clientToDisconnect)663*ec779b8eSAndroid Build Coastguard Worker void CameraService::disconnectClient(const std::string& id, sp<BasicClient> clientToDisconnect) {
664*ec779b8eSAndroid Build Coastguard Worker if (clientToDisconnect.get() != nullptr) {
665*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
666*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, id.c_str());
667*ec779b8eSAndroid Build Coastguard Worker // Notify the client of disconnection
668*ec779b8eSAndroid Build Coastguard Worker clientToDisconnect->notifyError(
669*ec779b8eSAndroid Build Coastguard Worker hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
670*ec779b8eSAndroid Build Coastguard Worker CaptureResultExtras{});
671*ec779b8eSAndroid Build Coastguard Worker clientToDisconnect->disconnect();
672*ec779b8eSAndroid Build Coastguard Worker }
673*ec779b8eSAndroid Build Coastguard Worker }
674*ec779b8eSAndroid Build Coastguard Worker
onTorchStatusChanged(const std::string & cameraId,TorchModeStatus newStatus)675*ec779b8eSAndroid Build Coastguard Worker void CameraService::onTorchStatusChanged(const std::string& cameraId,
676*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus newStatus) {
677*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
678*ec779b8eSAndroid Build Coastguard Worker status_t res = getSystemCameraKind(cameraId, &systemCameraKind);
679*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
680*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__,
681*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
682*ec779b8eSAndroid Build Coastguard Worker return;
683*ec779b8eSAndroid Build Coastguard Worker }
684*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
685*ec779b8eSAndroid Build Coastguard Worker onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
686*ec779b8eSAndroid Build Coastguard Worker }
687*ec779b8eSAndroid Build Coastguard Worker
onTorchStatusChanged(const std::string & cameraId,TorchModeStatus newStatus,SystemCameraKind systemCameraKind)688*ec779b8eSAndroid Build Coastguard Worker void CameraService::onTorchStatusChanged(const std::string& cameraId,
689*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
690*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
691*ec779b8eSAndroid Build Coastguard Worker onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind);
692*ec779b8eSAndroid Build Coastguard Worker }
693*ec779b8eSAndroid Build Coastguard Worker
broadcastTorchStrengthLevel(const std::string & cameraId,int32_t newStrengthLevel)694*ec779b8eSAndroid Build Coastguard Worker void CameraService::broadcastTorchStrengthLevel(const std::string& cameraId,
695*ec779b8eSAndroid Build Coastguard Worker int32_t newStrengthLevel) {
696*ec779b8eSAndroid Build Coastguard Worker // Get the device id and app-visible camera id for the given HAL-visible camera id.
697*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, mappedCameraId] =
698*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
699*ec779b8eSAndroid Build Coastguard Worker
700*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
701*ec779b8eSAndroid Build Coastguard Worker for (auto& i : mListenerList) {
702*ec779b8eSAndroid Build Coastguard Worker auto ret = i->getListener()->onTorchStrengthLevelChanged(mappedCameraId,
703*ec779b8eSAndroid Build Coastguard Worker newStrengthLevel, deviceId);
704*ec779b8eSAndroid Build Coastguard Worker i->handleBinderStatus(ret,
705*ec779b8eSAndroid Build Coastguard Worker "%s: Failed to trigger onTorchStrengthLevelChanged for %d:%d: %d", __FUNCTION__,
706*ec779b8eSAndroid Build Coastguard Worker i->getListenerUid(), i->getListenerPid(), ret.exceptionCode());
707*ec779b8eSAndroid Build Coastguard Worker }
708*ec779b8eSAndroid Build Coastguard Worker }
709*ec779b8eSAndroid Build Coastguard Worker
onTorchStatusChangedLocked(const std::string & cameraId,TorchModeStatus newStatus,SystemCameraKind systemCameraKind)710*ec779b8eSAndroid Build Coastguard Worker void CameraService::onTorchStatusChangedLocked(const std::string& cameraId,
711*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
712*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
713*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str(), eToI(newStatus));
714*ec779b8eSAndroid Build Coastguard Worker
715*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus status;
716*ec779b8eSAndroid Build Coastguard Worker status_t res = getTorchStatusLocked(cameraId, &status);
717*ec779b8eSAndroid Build Coastguard Worker if (res) {
718*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
719*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str(), strerror(-res), res);
720*ec779b8eSAndroid Build Coastguard Worker return;
721*ec779b8eSAndroid Build Coastguard Worker }
722*ec779b8eSAndroid Build Coastguard Worker if (status == newStatus) {
723*ec779b8eSAndroid Build Coastguard Worker return;
724*ec779b8eSAndroid Build Coastguard Worker }
725*ec779b8eSAndroid Build Coastguard Worker
726*ec779b8eSAndroid Build Coastguard Worker res = setTorchStatusLocked(cameraId, newStatus);
727*ec779b8eSAndroid Build Coastguard Worker if (res) {
728*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__,
729*ec779b8eSAndroid Build Coastguard Worker (uint32_t)newStatus, strerror(-res), res);
730*ec779b8eSAndroid Build Coastguard Worker return;
731*ec779b8eSAndroid Build Coastguard Worker }
732*ec779b8eSAndroid Build Coastguard Worker
733*ec779b8eSAndroid Build Coastguard Worker {
734*ec779b8eSAndroid Build Coastguard Worker // Update battery life logging for flashlight
735*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchUidMapMutex);
736*ec779b8eSAndroid Build Coastguard Worker auto iter = mTorchUidMap.find(cameraId);
737*ec779b8eSAndroid Build Coastguard Worker if (iter != mTorchUidMap.end()) {
738*ec779b8eSAndroid Build Coastguard Worker int oldUid = iter->second.second;
739*ec779b8eSAndroid Build Coastguard Worker int newUid = iter->second.first;
740*ec779b8eSAndroid Build Coastguard Worker BatteryNotifier& notifier(BatteryNotifier::getInstance());
741*ec779b8eSAndroid Build Coastguard Worker if (oldUid != newUid) {
742*ec779b8eSAndroid Build Coastguard Worker // If the UID has changed, log the status and update current UID in mTorchUidMap
743*ec779b8eSAndroid Build Coastguard Worker if (status == TorchModeStatus::AVAILABLE_ON) {
744*ec779b8eSAndroid Build Coastguard Worker notifier.noteFlashlightOff(toString8(cameraId), oldUid);
745*ec779b8eSAndroid Build Coastguard Worker }
746*ec779b8eSAndroid Build Coastguard Worker if (newStatus == TorchModeStatus::AVAILABLE_ON) {
747*ec779b8eSAndroid Build Coastguard Worker notifier.noteFlashlightOn(toString8(cameraId), newUid);
748*ec779b8eSAndroid Build Coastguard Worker }
749*ec779b8eSAndroid Build Coastguard Worker iter->second.second = newUid;
750*ec779b8eSAndroid Build Coastguard Worker } else {
751*ec779b8eSAndroid Build Coastguard Worker // If the UID has not changed, log the status
752*ec779b8eSAndroid Build Coastguard Worker if (newStatus == TorchModeStatus::AVAILABLE_ON) {
753*ec779b8eSAndroid Build Coastguard Worker notifier.noteFlashlightOn(toString8(cameraId), oldUid);
754*ec779b8eSAndroid Build Coastguard Worker } else {
755*ec779b8eSAndroid Build Coastguard Worker notifier.noteFlashlightOff(toString8(cameraId), oldUid);
756*ec779b8eSAndroid Build Coastguard Worker }
757*ec779b8eSAndroid Build Coastguard Worker }
758*ec779b8eSAndroid Build Coastguard Worker }
759*ec779b8eSAndroid Build Coastguard Worker }
760*ec779b8eSAndroid Build Coastguard Worker broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
761*ec779b8eSAndroid Build Coastguard Worker }
762*ec779b8eSAndroid Build Coastguard Worker
isAutomotiveExteriorSystemCamera(const std::string & cam_id) const763*ec779b8eSAndroid Build Coastguard Worker bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const {
764*ec779b8eSAndroid Build Coastguard Worker // Returns false if this is not an automotive device type.
765*ec779b8eSAndroid Build Coastguard Worker if (!isAutomotiveDevice())
766*ec779b8eSAndroid Build Coastguard Worker return false;
767*ec779b8eSAndroid Build Coastguard Worker
768*ec779b8eSAndroid Build Coastguard Worker // Returns false if no camera id is provided.
769*ec779b8eSAndroid Build Coastguard Worker if (cam_id.empty())
770*ec779b8eSAndroid Build Coastguard Worker return false;
771*ec779b8eSAndroid Build Coastguard Worker
772*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
773*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cam_id, &systemCameraKind) != OK) {
774*ec779b8eSAndroid Build Coastguard Worker // This isn't a known camera ID, so it's not a system camera.
775*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unknown camera id %s, ", __FUNCTION__, cam_id.c_str());
776*ec779b8eSAndroid Build Coastguard Worker return false;
777*ec779b8eSAndroid Build Coastguard Worker }
778*ec779b8eSAndroid Build Coastguard Worker
779*ec779b8eSAndroid Build Coastguard Worker if (systemCameraKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) {
780*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: camera id %s is not a system camera", __FUNCTION__, cam_id.c_str());
781*ec779b8eSAndroid Build Coastguard Worker return false;
782*ec779b8eSAndroid Build Coastguard Worker }
783*ec779b8eSAndroid Build Coastguard Worker
784*ec779b8eSAndroid Build Coastguard Worker CameraMetadata cameraInfo;
785*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->getCameraCharacteristics(
786*ec779b8eSAndroid Build Coastguard Worker cam_id, false, &cameraInfo, hardware::ICameraService::ROTATION_OVERRIDE_NONE);
787*ec779b8eSAndroid Build Coastguard Worker if (res != OK){
788*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Not able to get camera characteristics for camera id %s",__FUNCTION__,
789*ec779b8eSAndroid Build Coastguard Worker cam_id.c_str());
790*ec779b8eSAndroid Build Coastguard Worker return false;
791*ec779b8eSAndroid Build Coastguard Worker }
792*ec779b8eSAndroid Build Coastguard Worker
793*ec779b8eSAndroid Build Coastguard Worker camera_metadata_entry auto_location = cameraInfo.find(ANDROID_AUTOMOTIVE_LOCATION);
794*ec779b8eSAndroid Build Coastguard Worker if (auto_location.count != 1)
795*ec779b8eSAndroid Build Coastguard Worker return false;
796*ec779b8eSAndroid Build Coastguard Worker
797*ec779b8eSAndroid Build Coastguard Worker uint8_t location = auto_location.data.u8[0];
798*ec779b8eSAndroid Build Coastguard Worker if ((location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT) &&
799*ec779b8eSAndroid Build Coastguard Worker (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR) &&
800*ec779b8eSAndroid Build Coastguard Worker (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT) &&
801*ec779b8eSAndroid Build Coastguard Worker (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT)) {
802*ec779b8eSAndroid Build Coastguard Worker return false;
803*ec779b8eSAndroid Build Coastguard Worker }
804*ec779b8eSAndroid Build Coastguard Worker
805*ec779b8eSAndroid Build Coastguard Worker return true;
806*ec779b8eSAndroid Build Coastguard Worker }
807*ec779b8eSAndroid Build Coastguard Worker
getNumberOfCameras(int32_t type,const AttributionSourceState & clientAttribution,int32_t devicePolicy,int32_t * numCameras)808*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getNumberOfCameras(int32_t type,
809*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int32_t devicePolicy,
810*ec779b8eSAndroid Build Coastguard Worker int32_t* numCameras) {
811*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
812*ec779b8eSAndroid Build Coastguard Worker if (vd_flags::camera_device_awareness() && (clientAttribution.deviceId != kDefaultDeviceId)
813*ec779b8eSAndroid Build Coastguard Worker && (devicePolicy != IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) {
814*ec779b8eSAndroid Build Coastguard Worker *numCameras = mVirtualDeviceCameraIdMapper.getNumberOfCameras(clientAttribution.deviceId);
815*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
816*ec779b8eSAndroid Build Coastguard Worker }
817*ec779b8eSAndroid Build Coastguard Worker
818*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mServiceLock);
819*ec779b8eSAndroid Build Coastguard Worker bool hasSystemCameraPermissions =
820*ec779b8eSAndroid Build Coastguard Worker hasPermissionsForSystemCamera(std::string(), getCallingPid(),
821*ec779b8eSAndroid Build Coastguard Worker getCallingUid());
822*ec779b8eSAndroid Build Coastguard Worker switch (type) {
823*ec779b8eSAndroid Build Coastguard Worker case CAMERA_TYPE_BACKWARD_COMPATIBLE:
824*ec779b8eSAndroid Build Coastguard Worker if (hasSystemCameraPermissions) {
825*ec779b8eSAndroid Build Coastguard Worker *numCameras = static_cast<int>(mNormalDeviceIds.size());
826*ec779b8eSAndroid Build Coastguard Worker } else {
827*ec779b8eSAndroid Build Coastguard Worker *numCameras = static_cast<int>(mNormalDeviceIdsWithoutSystemCamera.size());
828*ec779b8eSAndroid Build Coastguard Worker }
829*ec779b8eSAndroid Build Coastguard Worker break;
830*ec779b8eSAndroid Build Coastguard Worker case CAMERA_TYPE_ALL:
831*ec779b8eSAndroid Build Coastguard Worker if (hasSystemCameraPermissions) {
832*ec779b8eSAndroid Build Coastguard Worker *numCameras = mNumberOfCameras;
833*ec779b8eSAndroid Build Coastguard Worker } else {
834*ec779b8eSAndroid Build Coastguard Worker *numCameras = mNumberOfCamerasWithoutSystemCamera;
835*ec779b8eSAndroid Build Coastguard Worker }
836*ec779b8eSAndroid Build Coastguard Worker break;
837*ec779b8eSAndroid Build Coastguard Worker default:
838*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Unknown camera type %d",
839*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, type);
840*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
841*ec779b8eSAndroid Build Coastguard Worker "Unknown camera type %d", type);
842*ec779b8eSAndroid Build Coastguard Worker }
843*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
844*ec779b8eSAndroid Build Coastguard Worker }
845*ec779b8eSAndroid Build Coastguard Worker
createDefaultRequest(const std::string & unresolvedCameraId,int templateId,const AttributionSourceState & clientAttribution,int32_t devicePolicy,hardware::camera2::impl::CameraMetadataNative * request)846*ec779b8eSAndroid Build Coastguard Worker Status CameraService::createDefaultRequest(const std::string& unresolvedCameraId, int templateId,
847*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int32_t devicePolicy,
848*ec779b8eSAndroid Build Coastguard Worker /* out */
849*ec779b8eSAndroid Build Coastguard Worker hardware::camera2::impl::CameraMetadataNative* request) {
850*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
851*ec779b8eSAndroid Build Coastguard Worker
852*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
853*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera subsystem is not available", __FUNCTION__);
854*ec779b8eSAndroid Build Coastguard Worker logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
855*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
856*ec779b8eSAndroid Build Coastguard Worker }
857*ec779b8eSAndroid Build Coastguard Worker
858*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional =
859*ec779b8eSAndroid Build Coastguard Worker resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
860*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
861*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
862*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
863*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
864*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
865*ec779b8eSAndroid Build Coastguard Worker }
866*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
867*ec779b8eSAndroid Build Coastguard Worker
868*ec779b8eSAndroid Build Coastguard Worker binder::Status res;
869*ec779b8eSAndroid Build Coastguard Worker if (request == nullptr) {
870*ec779b8eSAndroid Build Coastguard Worker res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
871*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Error creating default request", cameraId.c_str());
872*ec779b8eSAndroid Build Coastguard Worker return res;
873*ec779b8eSAndroid Build Coastguard Worker }
874*ec779b8eSAndroid Build Coastguard Worker camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
875*ec779b8eSAndroid Build Coastguard Worker res = SessionConfigurationUtils::mapRequestTemplateFromClient(
876*ec779b8eSAndroid Build Coastguard Worker cameraId, templateId, &tempId);
877*ec779b8eSAndroid Build Coastguard Worker if (!res.isOk()) {
878*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera %s: failed to map request Template %d",
879*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str(), templateId);
880*ec779b8eSAndroid Build Coastguard Worker return res;
881*ec779b8eSAndroid Build Coastguard Worker }
882*ec779b8eSAndroid Build Coastguard Worker
883*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
884*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to create default"
885*ec779b8eSAndroid Build Coastguard Worker "request for system only device %s: ", cameraId.c_str());
886*ec779b8eSAndroid Build Coastguard Worker }
887*ec779b8eSAndroid Build Coastguard Worker
888*ec779b8eSAndroid Build Coastguard Worker CameraMetadata metadata;
889*ec779b8eSAndroid Build Coastguard Worker status_t err = mCameraProviderManager->createDefaultRequest(cameraId, tempId, &metadata);
890*ec779b8eSAndroid Build Coastguard Worker if (err == OK) {
891*ec779b8eSAndroid Build Coastguard Worker request->swap(metadata);
892*ec779b8eSAndroid Build Coastguard Worker } else if (err == BAD_VALUE) {
893*ec779b8eSAndroid Build Coastguard Worker res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
894*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Template ID %d is invalid or not supported: %s (%d)",
895*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), templateId, strerror(-err), err);
896*ec779b8eSAndroid Build Coastguard Worker } else {
897*ec779b8eSAndroid Build Coastguard Worker res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
898*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Error creating default request for template %d: %s (%d)",
899*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), templateId, strerror(-err), err);
900*ec779b8eSAndroid Build Coastguard Worker }
901*ec779b8eSAndroid Build Coastguard Worker return res;
902*ec779b8eSAndroid Build Coastguard Worker }
903*ec779b8eSAndroid Build Coastguard Worker
isSessionConfigurationWithParametersSupported(const std::string & unresolvedCameraId,int targetSdkVersion,const SessionConfiguration & sessionConfiguration,const AttributionSourceState & clientAttribution,int32_t devicePolicy,bool * supported)904*ec779b8eSAndroid Build Coastguard Worker Status CameraService::isSessionConfigurationWithParametersSupported(
905*ec779b8eSAndroid Build Coastguard Worker const std::string& unresolvedCameraId, int targetSdkVersion,
906*ec779b8eSAndroid Build Coastguard Worker const SessionConfiguration& sessionConfiguration,
907*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int32_t devicePolicy,
908*ec779b8eSAndroid Build Coastguard Worker /*out*/ bool* supported) {
909*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
910*ec779b8eSAndroid Build Coastguard Worker
911*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
912*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
913*ec779b8eSAndroid Build Coastguard Worker logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
914*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
915*ec779b8eSAndroid Build Coastguard Worker }
916*ec779b8eSAndroid Build Coastguard Worker
917*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional =
918*ec779b8eSAndroid Build Coastguard Worker resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
919*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
920*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
921*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
922*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
923*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
924*ec779b8eSAndroid Build Coastguard Worker }
925*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
926*ec779b8eSAndroid Build Coastguard Worker
927*ec779b8eSAndroid Build Coastguard Worker if (supported == nullptr) {
928*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid 'support' input!",
929*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str());
930*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
931*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
932*ec779b8eSAndroid Build Coastguard Worker }
933*ec779b8eSAndroid Build Coastguard Worker
934*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
935*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query "
936*ec779b8eSAndroid Build Coastguard Worker "session configuration with parameters support for system only device %s: ",
937*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
938*ec779b8eSAndroid Build Coastguard Worker }
939*ec779b8eSAndroid Build Coastguard Worker
940*ec779b8eSAndroid Build Coastguard Worker bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
941*ec779b8eSAndroid Build Coastguard Worker mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion);
942*ec779b8eSAndroid Build Coastguard Worker
943*ec779b8eSAndroid Build Coastguard Worker auto ret = isSessionConfigurationWithParametersSupportedUnsafe(cameraId,
944*ec779b8eSAndroid Build Coastguard Worker sessionConfiguration, overrideForPerfClass, supported);
945*ec779b8eSAndroid Build Coastguard Worker if (flags::analytics_24q3()) {
946*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->logFeatureCombinationQuery(cameraId,
947*ec779b8eSAndroid Build Coastguard Worker getCallingUid(), sessionConfiguration, ret);
948*ec779b8eSAndroid Build Coastguard Worker }
949*ec779b8eSAndroid Build Coastguard Worker return ret;
950*ec779b8eSAndroid Build Coastguard Worker }
951*ec779b8eSAndroid Build Coastguard Worker
isSessionConfigurationWithParametersSupportedUnsafe(const std::string & cameraId,const SessionConfiguration & sessionConfiguration,bool overrideForPerfClass,bool * supported)952*ec779b8eSAndroid Build Coastguard Worker Status CameraService::isSessionConfigurationWithParametersSupportedUnsafe(
953*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId, const SessionConfiguration& sessionConfiguration,
954*ec779b8eSAndroid Build Coastguard Worker bool overrideForPerfClass, /*out*/ bool* supported) {
955*ec779b8eSAndroid Build Coastguard Worker *supported = false;
956*ec779b8eSAndroid Build Coastguard Worker status_t ret = mCameraProviderManager->isSessionConfigurationSupported(
957*ec779b8eSAndroid Build Coastguard Worker cameraId, sessionConfiguration, overrideForPerfClass,
958*ec779b8eSAndroid Build Coastguard Worker /*checkSessionParams=*/true, supported);
959*ec779b8eSAndroid Build Coastguard Worker binder::Status res;
960*ec779b8eSAndroid Build Coastguard Worker switch (ret) {
961*ec779b8eSAndroid Build Coastguard Worker case OK:
962*ec779b8eSAndroid Build Coastguard Worker // Expected. Do Nothing.
963*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
964*ec779b8eSAndroid Build Coastguard Worker case INVALID_OPERATION: {
965*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
966*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Session configuration with parameters supported query not "
967*ec779b8eSAndroid Build Coastguard Worker "supported!",
968*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
969*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: %s", __FUNCTION__, msg.c_str());
970*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, CameraService::ERROR_INVALID_OPERATION);
971*ec779b8eSAndroid Build Coastguard Worker *supported = false;
972*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
973*ec779b8eSAndroid Build Coastguard Worker }
974*ec779b8eSAndroid Build Coastguard Worker break;
975*ec779b8eSAndroid Build Coastguard Worker case NAME_NOT_FOUND: {
976*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Unknown camera ID.", cameraId.c_str());
977*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: %s", __FUNCTION__, msg.c_str());
978*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, CameraService::ERROR_ILLEGAL_ARGUMENT);
979*ec779b8eSAndroid Build Coastguard Worker *supported = false;
980*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
981*ec779b8eSAndroid Build Coastguard Worker }
982*ec779b8eSAndroid Build Coastguard Worker break;
983*ec779b8eSAndroid Build Coastguard Worker default: {
984*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
985*ec779b8eSAndroid Build Coastguard Worker "Unable to retrieve session configuration support for camera "
986*ec779b8eSAndroid Build Coastguard Worker "device %s: Error: %s (%d)",
987*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-ret), ret);
988*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
989*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, CameraService::ERROR_ILLEGAL_ARGUMENT);
990*ec779b8eSAndroid Build Coastguard Worker *supported = false;
991*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
992*ec779b8eSAndroid Build Coastguard Worker }
993*ec779b8eSAndroid Build Coastguard Worker break;
994*ec779b8eSAndroid Build Coastguard Worker }
995*ec779b8eSAndroid Build Coastguard Worker }
996*ec779b8eSAndroid Build Coastguard Worker
getSessionCharacteristics(const std::string & unresolvedCameraId,int targetSdkVersion,int rotationOverride,const SessionConfiguration & sessionConfiguration,const AttributionSourceState & clientAttribution,int32_t devicePolicy,CameraMetadata * outMetadata)997*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getSessionCharacteristics(const std::string& unresolvedCameraId,
998*ec779b8eSAndroid Build Coastguard Worker int targetSdkVersion, int rotationOverride,
999*ec779b8eSAndroid Build Coastguard Worker const SessionConfiguration& sessionConfiguration,
1000*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int32_t devicePolicy,
1001*ec779b8eSAndroid Build Coastguard Worker /*out*/ CameraMetadata* outMetadata) {
1002*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1003*ec779b8eSAndroid Build Coastguard Worker
1004*ec779b8eSAndroid Build Coastguard Worker if (outMetadata == nullptr) {
1005*ec779b8eSAndroid Build Coastguard Worker std::string msg =
1006*ec779b8eSAndroid Build Coastguard Worker fmt::sprintf("Camera %s: Invalid 'outMetadata' input!", unresolvedCameraId.c_str());
1007*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1008*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1009*ec779b8eSAndroid Build Coastguard Worker }
1010*ec779b8eSAndroid Build Coastguard Worker
1011*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1012*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
1013*ec779b8eSAndroid Build Coastguard Worker logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
1014*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
1015*ec779b8eSAndroid Build Coastguard Worker }
1016*ec779b8eSAndroid Build Coastguard Worker
1017*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional =
1018*ec779b8eSAndroid Build Coastguard Worker resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
1019*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
1020*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
1021*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
1022*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1023*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1024*ec779b8eSAndroid Build Coastguard Worker }
1025*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
1026*ec779b8eSAndroid Build Coastguard Worker
1027*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
1028*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1029*ec779b8eSAndroid Build Coastguard Worker "Unable to retrieve camera"
1030*ec779b8eSAndroid Build Coastguard Worker "characteristics for system only device %s: ",
1031*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1032*ec779b8eSAndroid Build Coastguard Worker }
1033*ec779b8eSAndroid Build Coastguard Worker
1034*ec779b8eSAndroid Build Coastguard Worker bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
1035*ec779b8eSAndroid Build Coastguard Worker mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion);
1036*ec779b8eSAndroid Build Coastguard Worker
1037*ec779b8eSAndroid Build Coastguard Worker bool sessionConfigSupported;
1038*ec779b8eSAndroid Build Coastguard Worker Status res = isSessionConfigurationWithParametersSupportedUnsafe(
1039*ec779b8eSAndroid Build Coastguard Worker cameraId, sessionConfiguration, overrideForPerfClass, &sessionConfigSupported);
1040*ec779b8eSAndroid Build Coastguard Worker if (!res.isOk()) {
1041*ec779b8eSAndroid Build Coastguard Worker // isSessionConfigurationWithParametersSupportedUnsafe should log what went wrong and
1042*ec779b8eSAndroid Build Coastguard Worker // report the correct Status to send to the client. Simply forward the error to
1043*ec779b8eSAndroid Build Coastguard Worker // the client.
1044*ec779b8eSAndroid Build Coastguard Worker outMetadata->clear();
1045*ec779b8eSAndroid Build Coastguard Worker return res;
1046*ec779b8eSAndroid Build Coastguard Worker }
1047*ec779b8eSAndroid Build Coastguard Worker
1048*ec779b8eSAndroid Build Coastguard Worker if (!sessionConfigSupported) {
1049*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Session configuration not supported for camera device %s.",
1050*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1051*ec779b8eSAndroid Build Coastguard Worker outMetadata->clear();
1052*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1053*ec779b8eSAndroid Build Coastguard Worker }
1054*ec779b8eSAndroid Build Coastguard Worker
1055*ec779b8eSAndroid Build Coastguard Worker status_t ret = mCameraProviderManager->getSessionCharacteristics(
1056*ec779b8eSAndroid Build Coastguard Worker cameraId, sessionConfiguration, overrideForPerfClass, rotationOverride, outMetadata);
1057*ec779b8eSAndroid Build Coastguard Worker
1058*ec779b8eSAndroid Build Coastguard Worker switch (ret) {
1059*ec779b8eSAndroid Build Coastguard Worker case OK:
1060*ec779b8eSAndroid Build Coastguard Worker // Expected, no handling needed.
1061*ec779b8eSAndroid Build Coastguard Worker break;
1062*ec779b8eSAndroid Build Coastguard Worker case INVALID_OPERATION: {
1063*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
1064*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Session characteristics query not supported!",
1065*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1066*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: %s", __FUNCTION__, msg.c_str());
1067*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, CameraService::ERROR_INVALID_OPERATION);
1068*ec779b8eSAndroid Build Coastguard Worker outMetadata->clear();
1069*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
1070*ec779b8eSAndroid Build Coastguard Worker }
1071*ec779b8eSAndroid Build Coastguard Worker break;
1072*ec779b8eSAndroid Build Coastguard Worker case NAME_NOT_FOUND: {
1073*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
1074*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Unknown camera ID.",
1075*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1076*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: %s", __FUNCTION__, msg.c_str());
1077*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, CameraService::ERROR_ILLEGAL_ARGUMENT);
1078*ec779b8eSAndroid Build Coastguard Worker outMetadata->clear();
1079*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1080*ec779b8eSAndroid Build Coastguard Worker }
1081*ec779b8eSAndroid Build Coastguard Worker break;
1082*ec779b8eSAndroid Build Coastguard Worker default: {
1083*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
1084*ec779b8eSAndroid Build Coastguard Worker "Unable to retrieve session characteristics for camera device %s: "
1085*ec779b8eSAndroid Build Coastguard Worker "Error: %s (%d)",
1086*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-ret), ret);
1087*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1088*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, CameraService::ERROR_INVALID_OPERATION);
1089*ec779b8eSAndroid Build Coastguard Worker outMetadata->clear();
1090*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
1091*ec779b8eSAndroid Build Coastguard Worker }
1092*ec779b8eSAndroid Build Coastguard Worker }
1093*ec779b8eSAndroid Build Coastguard Worker
1094*ec779b8eSAndroid Build Coastguard Worker res = filterSensitiveMetadataIfNeeded(cameraId, outMetadata);
1095*ec779b8eSAndroid Build Coastguard Worker if (flags::analytics_24q3()) {
1096*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->logSessionCharacteristicsQuery(cameraId,
1097*ec779b8eSAndroid Build Coastguard Worker getCallingUid(), sessionConfiguration, res);
1098*ec779b8eSAndroid Build Coastguard Worker }
1099*ec779b8eSAndroid Build Coastguard Worker return res;
1100*ec779b8eSAndroid Build Coastguard Worker }
1101*ec779b8eSAndroid Build Coastguard Worker
filterSensitiveMetadataIfNeeded(const std::string & cameraId,CameraMetadata * metadata)1102*ec779b8eSAndroid Build Coastguard Worker Status CameraService::filterSensitiveMetadataIfNeeded(
1103*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId, CameraMetadata* metadata) {
1104*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
1105*ec779b8eSAndroid Build Coastguard Worker int callingUid = getCallingUid();
1106*ec779b8eSAndroid Build Coastguard Worker
1107*ec779b8eSAndroid Build Coastguard Worker if (callingPid == getpid()) {
1108*ec779b8eSAndroid Build Coastguard Worker // Caller is cameraserver; no need to remove keys
1109*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1110*ec779b8eSAndroid Build Coastguard Worker }
1111*ec779b8eSAndroid Build Coastguard Worker
1112*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
1113*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
1114*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Couldn't get camera kind for camera id %s", __FUNCTION__, cameraId.c_str());
1115*ec779b8eSAndroid Build Coastguard Worker metadata->clear();
1116*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1117*ec779b8eSAndroid Build Coastguard Worker "Unable to retrieve camera kind for device %s", cameraId.c_str());
1118*ec779b8eSAndroid Build Coastguard Worker }
1119*ec779b8eSAndroid Build Coastguard Worker if (deviceKind == SystemCameraKind::SYSTEM_ONLY_CAMERA) {
1120*ec779b8eSAndroid Build Coastguard Worker // Attempting to query system only camera without system camera permission would have
1121*ec779b8eSAndroid Build Coastguard Worker // failed the shouldRejectSystemCameraConnection in the caller. So if we get here
1122*ec779b8eSAndroid Build Coastguard Worker // for a system only camera, then the caller has the required permission.
1123*ec779b8eSAndroid Build Coastguard Worker // No need to remove keys
1124*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1125*ec779b8eSAndroid Build Coastguard Worker }
1126*ec779b8eSAndroid Build Coastguard Worker
1127*ec779b8eSAndroid Build Coastguard Worker std::vector<int32_t> tagsRemoved;
1128*ec779b8eSAndroid Build Coastguard Worker // Get the device id that owns this camera.
1129*ec779b8eSAndroid Build Coastguard Worker auto [cameraOwnerDeviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(
1130*ec779b8eSAndroid Build Coastguard Worker cameraId);
1131*ec779b8eSAndroid Build Coastguard Worker bool hasCameraPermission = hasPermissionsForCamera(cameraId, callingPid, callingUid,
1132*ec779b8eSAndroid Build Coastguard Worker cameraOwnerDeviceId);
1133*ec779b8eSAndroid Build Coastguard Worker if (hasCameraPermission) {
1134*ec779b8eSAndroid Build Coastguard Worker // Caller has camera permission; no need to remove keys
1135*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1136*ec779b8eSAndroid Build Coastguard Worker }
1137*ec779b8eSAndroid Build Coastguard Worker
1138*ec779b8eSAndroid Build Coastguard Worker status_t ret = metadata->removePermissionEntries(
1139*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->getProviderTagIdLocked(cameraId), &tagsRemoved);
1140*ec779b8eSAndroid Build Coastguard Worker if (ret != OK) {
1141*ec779b8eSAndroid Build Coastguard Worker metadata->clear();
1142*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1143*ec779b8eSAndroid Build Coastguard Worker "Failed to remove camera characteristics needing camera permission "
1144*ec779b8eSAndroid Build Coastguard Worker "for device %s:%s (%d)",
1145*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-ret), ret);
1146*ec779b8eSAndroid Build Coastguard Worker }
1147*ec779b8eSAndroid Build Coastguard Worker
1148*ec779b8eSAndroid Build Coastguard Worker if (!tagsRemoved.empty()) {
1149*ec779b8eSAndroid Build Coastguard Worker ret = metadata->update(ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION,
1150*ec779b8eSAndroid Build Coastguard Worker tagsRemoved.data(), tagsRemoved.size());
1151*ec779b8eSAndroid Build Coastguard Worker if (ret != OK) {
1152*ec779b8eSAndroid Build Coastguard Worker metadata->clear();
1153*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(
1154*ec779b8eSAndroid Build Coastguard Worker ERROR_INVALID_OPERATION,
1155*ec779b8eSAndroid Build Coastguard Worker "Failed to insert camera keys needing permission for device %s: %s (%d)",
1156*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-ret), ret);
1157*ec779b8eSAndroid Build Coastguard Worker }
1158*ec779b8eSAndroid Build Coastguard Worker }
1159*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1160*ec779b8eSAndroid Build Coastguard Worker }
1161*ec779b8eSAndroid Build Coastguard Worker
injectSessionParams(const std::string & cameraId,const CameraMetadata & sessionParams)1162*ec779b8eSAndroid Build Coastguard Worker Status CameraService::injectSessionParams(
1163*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId,
1164*ec779b8eSAndroid Build Coastguard Worker const CameraMetadata& sessionParams) {
1165*ec779b8eSAndroid Build Coastguard Worker if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) {
1166*ec779b8eSAndroid Build Coastguard Worker const int pid = getCallingPid();
1167*ec779b8eSAndroid Build Coastguard Worker const int uid = getCallingUid();
1168*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Permission Denial: can't inject session params pid=%d, uid=%d",
1169*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, pid, uid);
1170*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_PERMISSION_DENIED,
1171*ec779b8eSAndroid Build Coastguard Worker "Permission Denial: no permission to inject session params");
1172*ec779b8eSAndroid Build Coastguard Worker }
1173*ec779b8eSAndroid Build Coastguard Worker
1174*ec779b8eSAndroid Build Coastguard Worker // Do not allow session params injection for a virtual camera.
1175*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
1176*ec779b8eSAndroid Build Coastguard Worker if (deviceId != kDefaultDeviceId) {
1177*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1178*ec779b8eSAndroid Build Coastguard Worker "Cannot inject session params for a virtual camera");
1179*ec779b8eSAndroid Build Coastguard Worker }
1180*ec779b8eSAndroid Build Coastguard Worker
1181*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<AutoConditionLock> serviceLockWrapper =
1182*ec779b8eSAndroid Build Coastguard Worker AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
1183*ec779b8eSAndroid Build Coastguard Worker
1184*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = mActiveClientManager.get(cameraId);
1185*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor == nullptr) {
1186*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: No active client for camera id %s", __FUNCTION__, cameraId.c_str());
1187*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1188*ec779b8eSAndroid Build Coastguard Worker "No active client for camera id %s", cameraId.c_str());
1189*ec779b8eSAndroid Build Coastguard Worker }
1190*ec779b8eSAndroid Build Coastguard Worker
1191*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp = clientDescriptor->getValue();
1192*ec779b8eSAndroid Build Coastguard Worker status_t res = clientSp->injectSessionParams(sessionParams);
1193*ec779b8eSAndroid Build Coastguard Worker
1194*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
1195*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1196*ec779b8eSAndroid Build Coastguard Worker "Error injecting session params into camera \"%s\": %s (%d)",
1197*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-res), res);
1198*ec779b8eSAndroid Build Coastguard Worker }
1199*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1200*ec779b8eSAndroid Build Coastguard Worker }
1201*ec779b8eSAndroid Build Coastguard Worker
resolveCameraId(const std::string & inputCameraId,int32_t deviceId,int32_t devicePolicy)1202*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> CameraService::resolveCameraId(
1203*ec779b8eSAndroid Build Coastguard Worker const std::string& inputCameraId,
1204*ec779b8eSAndroid Build Coastguard Worker int32_t deviceId,
1205*ec779b8eSAndroid Build Coastguard Worker int32_t devicePolicy) {
1206*ec779b8eSAndroid Build Coastguard Worker if ((deviceId == kDefaultDeviceId)
1207*ec779b8eSAndroid Build Coastguard Worker || (devicePolicy == IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) {
1208*ec779b8eSAndroid Build Coastguard Worker auto [storedDeviceId, _] =
1209*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(inputCameraId);
1210*ec779b8eSAndroid Build Coastguard Worker if (storedDeviceId != kDefaultDeviceId) {
1211*ec779b8eSAndroid Build Coastguard Worker // Trying to access a virtual camera from default-policy device context, we should fail.
1212*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
1213*ec779b8eSAndroid Build Coastguard Worker inputCameraId.c_str(), deviceId);
1214*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1215*ec779b8eSAndroid Build Coastguard Worker return std::nullopt;
1216*ec779b8eSAndroid Build Coastguard Worker }
1217*ec779b8eSAndroid Build Coastguard Worker return inputCameraId;
1218*ec779b8eSAndroid Build Coastguard Worker }
1219*ec779b8eSAndroid Build Coastguard Worker
1220*ec779b8eSAndroid Build Coastguard Worker return mVirtualDeviceCameraIdMapper.getActualCameraId(deviceId, inputCameraId);
1221*ec779b8eSAndroid Build Coastguard Worker }
1222*ec779b8eSAndroid Build Coastguard Worker
getCameraInfo(int cameraId,int rotationOverride,const AttributionSourceState & clientAttribution,int32_t devicePolicy,CameraInfo * cameraInfo)1223*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getCameraInfo(int cameraId, int rotationOverride,
1224*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int32_t devicePolicy,
1225*ec779b8eSAndroid Build Coastguard Worker CameraInfo* cameraInfo) {
1226*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1227*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mServiceLock);
1228*ec779b8eSAndroid Build Coastguard Worker std::string cameraIdStr =
1229*ec779b8eSAndroid Build Coastguard Worker cameraIdIntToStrLocked(cameraId, clientAttribution.deviceId, devicePolicy);
1230*ec779b8eSAndroid Build Coastguard Worker if (cameraIdStr.empty()) {
1231*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %d: Invalid camera id for device id %d",
1232*ec779b8eSAndroid Build Coastguard Worker cameraId, clientAttribution.deviceId);
1233*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1234*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1235*ec779b8eSAndroid Build Coastguard Worker }
1236*ec779b8eSAndroid Build Coastguard Worker
1237*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraIdStr)) {
1238*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
1239*ec779b8eSAndroid Build Coastguard Worker "characteristics for system only device %s: ", cameraIdStr.c_str());
1240*ec779b8eSAndroid Build Coastguard Worker }
1241*ec779b8eSAndroid Build Coastguard Worker
1242*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1243*ec779b8eSAndroid Build Coastguard Worker logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
1244*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED,
1245*ec779b8eSAndroid Build Coastguard Worker "Camera subsystem is not available");
1246*ec779b8eSAndroid Build Coastguard Worker }
1247*ec779b8eSAndroid Build Coastguard Worker bool hasSystemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraId),
1248*ec779b8eSAndroid Build Coastguard Worker getCallingPid(), getCallingUid());
1249*ec779b8eSAndroid Build Coastguard Worker int cameraIdBound = mNumberOfCamerasWithoutSystemCamera;
1250*ec779b8eSAndroid Build Coastguard Worker if (hasSystemCameraPermissions) {
1251*ec779b8eSAndroid Build Coastguard Worker cameraIdBound = mNumberOfCameras;
1252*ec779b8eSAndroid Build Coastguard Worker }
1253*ec779b8eSAndroid Build Coastguard Worker if (cameraId < 0 || cameraId >= cameraIdBound) {
1254*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1255*ec779b8eSAndroid Build Coastguard Worker "CameraId is not valid");
1256*ec779b8eSAndroid Build Coastguard Worker }
1257*ec779b8eSAndroid Build Coastguard Worker
1258*ec779b8eSAndroid Build Coastguard Worker Status ret = Status::ok();
1259*ec779b8eSAndroid Build Coastguard Worker int portraitRotation;
1260*ec779b8eSAndroid Build Coastguard Worker status_t err = mCameraProviderManager->getCameraInfo(
1261*ec779b8eSAndroid Build Coastguard Worker cameraIdStr, rotationOverride, &portraitRotation, cameraInfo);
1262*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
1263*ec779b8eSAndroid Build Coastguard Worker ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1264*ec779b8eSAndroid Build Coastguard Worker "Error retrieving camera info from device %d: %s (%d)", cameraId,
1265*ec779b8eSAndroid Build Coastguard Worker strerror(-err), err);
1266*ec779b8eSAndroid Build Coastguard Worker logServiceError(std::string("Error retrieving camera info from device ")
1267*ec779b8eSAndroid Build Coastguard Worker + std::to_string(cameraId), ERROR_INVALID_OPERATION);
1268*ec779b8eSAndroid Build Coastguard Worker }
1269*ec779b8eSAndroid Build Coastguard Worker
1270*ec779b8eSAndroid Build Coastguard Worker return ret;
1271*ec779b8eSAndroid Build Coastguard Worker }
1272*ec779b8eSAndroid Build Coastguard Worker
cameraIdIntToStrLocked(int cameraIdInt,int32_t deviceId,int32_t devicePolicy)1273*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt,
1274*ec779b8eSAndroid Build Coastguard Worker int32_t deviceId, int32_t devicePolicy) {
1275*ec779b8eSAndroid Build Coastguard Worker if (vd_flags::camera_device_awareness() && (deviceId != kDefaultDeviceId)
1276*ec779b8eSAndroid Build Coastguard Worker && (devicePolicy != IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) {
1277*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional =
1278*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getActualCameraId(cameraIdInt, deviceId);
1279*ec779b8eSAndroid Build Coastguard Worker return cameraIdOptional.has_value() ? cameraIdOptional.value() : std::string{};
1280*ec779b8eSAndroid Build Coastguard Worker }
1281*ec779b8eSAndroid Build Coastguard Worker
1282*ec779b8eSAndroid Build Coastguard Worker const std::vector<std::string> *cameraIds = &mNormalDeviceIdsWithoutSystemCamera;
1283*ec779b8eSAndroid Build Coastguard Worker auto callingPid = getCallingPid();
1284*ec779b8eSAndroid Build Coastguard Worker auto callingUid = getCallingUid();
1285*ec779b8eSAndroid Build Coastguard Worker bool systemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraIdInt),
1286*ec779b8eSAndroid Build Coastguard Worker callingPid, callingUid, /* checkCameraPermissions= */ false);
1287*ec779b8eSAndroid Build Coastguard Worker if (systemCameraPermissions || getpid() == callingPid) {
1288*ec779b8eSAndroid Build Coastguard Worker cameraIds = &mNormalDeviceIds;
1289*ec779b8eSAndroid Build Coastguard Worker }
1290*ec779b8eSAndroid Build Coastguard Worker if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(cameraIds->size())) {
1291*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: input id %d invalid: valid range (0, %zu)",
1292*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraIdInt, cameraIds->size());
1293*ec779b8eSAndroid Build Coastguard Worker return std::string{};
1294*ec779b8eSAndroid Build Coastguard Worker }
1295*ec779b8eSAndroid Build Coastguard Worker
1296*ec779b8eSAndroid Build Coastguard Worker return (*cameraIds)[cameraIdInt];
1297*ec779b8eSAndroid Build Coastguard Worker }
1298*ec779b8eSAndroid Build Coastguard Worker
cameraIdIntToStr(int cameraIdInt,int32_t deviceId,int32_t devicePolicy)1299*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::cameraIdIntToStr(int cameraIdInt, int32_t deviceId,
1300*ec779b8eSAndroid Build Coastguard Worker int32_t devicePolicy) {
1301*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
1302*ec779b8eSAndroid Build Coastguard Worker return cameraIdIntToStrLocked(cameraIdInt, deviceId, devicePolicy);
1303*ec779b8eSAndroid Build Coastguard Worker }
1304*ec779b8eSAndroid Build Coastguard Worker
getCameraCharacteristics(const std::string & unresolvedCameraId,int targetSdkVersion,int rotationOverride,const AttributionSourceState & clientAttribution,int32_t devicePolicy,CameraMetadata * cameraInfo)1305*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getCameraCharacteristics(const std::string& unresolvedCameraId,
1306*ec779b8eSAndroid Build Coastguard Worker int targetSdkVersion, int rotationOverride, const AttributionSourceState& clientAttribution,
1307*ec779b8eSAndroid Build Coastguard Worker int32_t devicePolicy, CameraMetadata* cameraInfo) {
1308*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1309*ec779b8eSAndroid Build Coastguard Worker
1310*ec779b8eSAndroid Build Coastguard Worker if (!cameraInfo) {
1311*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
1312*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL");
1313*ec779b8eSAndroid Build Coastguard Worker }
1314*ec779b8eSAndroid Build Coastguard Worker
1315*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1316*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
1317*ec779b8eSAndroid Build Coastguard Worker logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
1318*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED,
1319*ec779b8eSAndroid Build Coastguard Worker "Camera subsystem is not available");;
1320*ec779b8eSAndroid Build Coastguard Worker }
1321*ec779b8eSAndroid Build Coastguard Worker
1322*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional =
1323*ec779b8eSAndroid Build Coastguard Worker resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
1324*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
1325*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
1326*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
1327*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1328*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1329*ec779b8eSAndroid Build Coastguard Worker }
1330*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
1331*ec779b8eSAndroid Build Coastguard Worker
1332*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
1333*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
1334*ec779b8eSAndroid Build Coastguard Worker "characteristics for system only device %s: ", cameraId.c_str());
1335*ec779b8eSAndroid Build Coastguard Worker }
1336*ec779b8eSAndroid Build Coastguard Worker
1337*ec779b8eSAndroid Build Coastguard Worker bool overrideForPerfClass =
1338*ec779b8eSAndroid Build Coastguard Worker SessionConfigurationUtils::targetPerfClassPrimaryCamera(mPerfClassPrimaryCameraIds,
1339*ec779b8eSAndroid Build Coastguard Worker cameraId, targetSdkVersion);
1340*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->getCameraCharacteristics(
1341*ec779b8eSAndroid Build Coastguard Worker cameraId, overrideForPerfClass, cameraInfo, rotationOverride);
1342*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
1343*ec779b8eSAndroid Build Coastguard Worker if (res == NAME_NOT_FOUND) {
1344*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to retrieve camera "
1345*ec779b8eSAndroid Build Coastguard Worker "characteristics for unknown device %s: %s (%d)", cameraId.c_str(),
1346*ec779b8eSAndroid Build Coastguard Worker strerror(-res), res);
1347*ec779b8eSAndroid Build Coastguard Worker } else {
1348*ec779b8eSAndroid Build Coastguard Worker logServiceError(fmt::sprintf("Unable to retrieve camera characteristics for device %s.",
1349*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str()), ERROR_INVALID_OPERATION);
1350*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
1351*ec779b8eSAndroid Build Coastguard Worker "characteristics for device %s: %s (%d)", cameraId.c_str(),
1352*ec779b8eSAndroid Build Coastguard Worker strerror(-res), res);
1353*ec779b8eSAndroid Build Coastguard Worker }
1354*ec779b8eSAndroid Build Coastguard Worker }
1355*ec779b8eSAndroid Build Coastguard Worker
1356*ec779b8eSAndroid Build Coastguard Worker return filterSensitiveMetadataIfNeeded(cameraId, cameraInfo);
1357*ec779b8eSAndroid Build Coastguard Worker }
1358*ec779b8eSAndroid Build Coastguard Worker
getTorchStrengthLevel(const std::string & unresolvedCameraId,const AttributionSourceState & clientAttribution,int32_t devicePolicy,int32_t * torchStrength)1359*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getTorchStrengthLevel(const std::string& unresolvedCameraId,
1360*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution,
1361*ec779b8eSAndroid Build Coastguard Worker int32_t devicePolicy, int32_t* torchStrength) {
1362*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1363*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mServiceLock);
1364*ec779b8eSAndroid Build Coastguard Worker
1365*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
1366*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId, devicePolicy);
1367*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
1368*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
1369*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
1370*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
1371*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
1372*ec779b8eSAndroid Build Coastguard Worker }
1373*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
1374*ec779b8eSAndroid Build Coastguard Worker
1375*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1376*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized.", __FUNCTION__);
1377*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED, "Camera HAL couldn't be initialized.");
1378*ec779b8eSAndroid Build Coastguard Worker }
1379*ec779b8eSAndroid Build Coastguard Worker
1380*ec779b8eSAndroid Build Coastguard Worker if (torchStrength == NULL) {
1381*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: strength level must not be null.", __FUNCTION__);
1382*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Strength level should not be null.");
1383*ec779b8eSAndroid Build Coastguard Worker }
1384*ec779b8eSAndroid Build Coastguard Worker
1385*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
1386*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
1387*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve torch "
1388*ec779b8eSAndroid Build Coastguard Worker "strength level for device %s: %s (%d)", cameraId.c_str(),
1389*ec779b8eSAndroid Build Coastguard Worker strerror(-res), res);
1390*ec779b8eSAndroid Build Coastguard Worker }
1391*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Torch strength level is: %d", __FUNCTION__, *torchStrength);
1392*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1393*ec779b8eSAndroid Build Coastguard Worker }
1394*ec779b8eSAndroid Build Coastguard Worker
getFormattedCurrentTime()1395*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::getFormattedCurrentTime() {
1396*ec779b8eSAndroid Build Coastguard Worker time_t now = time(nullptr);
1397*ec779b8eSAndroid Build Coastguard Worker char formattedTime[64];
1398*ec779b8eSAndroid Build Coastguard Worker strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now));
1399*ec779b8eSAndroid Build Coastguard Worker return std::string(formattedTime);
1400*ec779b8eSAndroid Build Coastguard Worker }
1401*ec779b8eSAndroid Build Coastguard Worker
getCameraVendorTagDescriptor(hardware::camera2::params::VendorTagDescriptor * desc)1402*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getCameraVendorTagDescriptor(
1403*ec779b8eSAndroid Build Coastguard Worker /*out*/
1404*ec779b8eSAndroid Build Coastguard Worker hardware::camera2::params::VendorTagDescriptor* desc) {
1405*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1406*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1407*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
1408*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available");
1409*ec779b8eSAndroid Build Coastguard Worker }
1410*ec779b8eSAndroid Build Coastguard Worker sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor();
1411*ec779b8eSAndroid Build Coastguard Worker if (globalDescriptor != nullptr) {
1412*ec779b8eSAndroid Build Coastguard Worker *desc = *(globalDescriptor.get());
1413*ec779b8eSAndroid Build Coastguard Worker }
1414*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1415*ec779b8eSAndroid Build Coastguard Worker }
1416*ec779b8eSAndroid Build Coastguard Worker
getCameraVendorTagCache(hardware::camera2::params::VendorTagDescriptorCache * cache)1417*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getCameraVendorTagCache(
1418*ec779b8eSAndroid Build Coastguard Worker /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) {
1419*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1420*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1421*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
1422*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED,
1423*ec779b8eSAndroid Build Coastguard Worker "Camera subsystem not available");
1424*ec779b8eSAndroid Build Coastguard Worker }
1425*ec779b8eSAndroid Build Coastguard Worker sp<VendorTagDescriptorCache> globalCache =
1426*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptorCache::getGlobalVendorTagCache();
1427*ec779b8eSAndroid Build Coastguard Worker if (globalCache != nullptr) {
1428*ec779b8eSAndroid Build Coastguard Worker *cache = *(globalCache.get());
1429*ec779b8eSAndroid Build Coastguard Worker }
1430*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1431*ec779b8eSAndroid Build Coastguard Worker }
1432*ec779b8eSAndroid Build Coastguard Worker
clearCachedVariables()1433*ec779b8eSAndroid Build Coastguard Worker void CameraService::clearCachedVariables() {
1434*ec779b8eSAndroid Build Coastguard Worker BasicClient::BasicClient::sCameraService = nullptr;
1435*ec779b8eSAndroid Build Coastguard Worker }
1436*ec779b8eSAndroid Build Coastguard Worker
getDeviceVersion(const std::string & cameraId,int rotationOverride,int * portraitRotation,int * facing,int * orientation)1437*ec779b8eSAndroid Build Coastguard Worker std::pair<int, IPCTransport> CameraService::getDeviceVersion(const std::string& cameraId,
1438*ec779b8eSAndroid Build Coastguard Worker int rotationOverride, int* portraitRotation, int* facing,
1439*ec779b8eSAndroid Build Coastguard Worker int* orientation) {
1440*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1441*ec779b8eSAndroid Build Coastguard Worker
1442*ec779b8eSAndroid Build Coastguard Worker int deviceVersion = 0;
1443*ec779b8eSAndroid Build Coastguard Worker
1444*ec779b8eSAndroid Build Coastguard Worker status_t res;
1445*ec779b8eSAndroid Build Coastguard Worker hardware::hidl_version maxVersion{0,0};
1446*ec779b8eSAndroid Build Coastguard Worker IPCTransport transport = IPCTransport::INVALID;
1447*ec779b8eSAndroid Build Coastguard Worker res = mCameraProviderManager->getHighestSupportedVersion(cameraId, &maxVersion, &transport);
1448*ec779b8eSAndroid Build Coastguard Worker if (res != OK || transport == IPCTransport::INVALID) {
1449*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unable to get highest supported version for camera id %s", __FUNCTION__,
1450*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1451*ec779b8eSAndroid Build Coastguard Worker return std::make_pair(-1, IPCTransport::INVALID) ;
1452*ec779b8eSAndroid Build Coastguard Worker }
1453*ec779b8eSAndroid Build Coastguard Worker deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
1454*ec779b8eSAndroid Build Coastguard Worker
1455*ec779b8eSAndroid Build Coastguard Worker hardware::CameraInfo info;
1456*ec779b8eSAndroid Build Coastguard Worker if (facing) {
1457*ec779b8eSAndroid Build Coastguard Worker res = mCameraProviderManager->getCameraInfo(cameraId, rotationOverride,
1458*ec779b8eSAndroid Build Coastguard Worker portraitRotation, &info);
1459*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
1460*ec779b8eSAndroid Build Coastguard Worker return std::make_pair(-1, IPCTransport::INVALID);
1461*ec779b8eSAndroid Build Coastguard Worker }
1462*ec779b8eSAndroid Build Coastguard Worker *facing = info.facing;
1463*ec779b8eSAndroid Build Coastguard Worker if (orientation) {
1464*ec779b8eSAndroid Build Coastguard Worker *orientation = info.orientation;
1465*ec779b8eSAndroid Build Coastguard Worker }
1466*ec779b8eSAndroid Build Coastguard Worker }
1467*ec779b8eSAndroid Build Coastguard Worker
1468*ec779b8eSAndroid Build Coastguard Worker return std::make_pair(deviceVersion, transport);
1469*ec779b8eSAndroid Build Coastguard Worker }
1470*ec779b8eSAndroid Build Coastguard Worker
filterGetInfoErrorCode(status_t err)1471*ec779b8eSAndroid Build Coastguard Worker Status CameraService::filterGetInfoErrorCode(status_t err) {
1472*ec779b8eSAndroid Build Coastguard Worker switch(err) {
1473*ec779b8eSAndroid Build Coastguard Worker case NO_ERROR:
1474*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1475*ec779b8eSAndroid Build Coastguard Worker case BAD_VALUE:
1476*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
1477*ec779b8eSAndroid Build Coastguard Worker "CameraId is not valid for HAL module");
1478*ec779b8eSAndroid Build Coastguard Worker case NO_INIT:
1479*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED,
1480*ec779b8eSAndroid Build Coastguard Worker "Camera device not available");
1481*ec779b8eSAndroid Build Coastguard Worker default:
1482*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1483*ec779b8eSAndroid Build Coastguard Worker "Camera HAL encountered error %d: %s",
1484*ec779b8eSAndroid Build Coastguard Worker err, strerror(-err));
1485*ec779b8eSAndroid Build Coastguard Worker }
1486*ec779b8eSAndroid Build Coastguard Worker }
1487*ec779b8eSAndroid Build Coastguard Worker
makeClient(const sp<CameraService> & cameraService,const sp<IInterface> & cameraCb,const AttributionSourceState & clientAttribution,int callingPid,bool systemNativeClient,const std::string & cameraId,int api1CameraId,int facing,int sensorOrientation,int servicePid,std::pair<int,IPCTransport> deviceVersionAndTransport,apiLevel effectiveApiLevel,bool overrideForPerfClass,int rotationOverride,bool forceSlowJpegMode,const std::string & originalCameraId,bool sharedMode,bool isVendorClient,sp<BasicClient> * client)1488*ec779b8eSAndroid Build Coastguard Worker Status CameraService::makeClient(
1489*ec779b8eSAndroid Build Coastguard Worker const sp<CameraService>& cameraService, const sp<IInterface>& cameraCb,
1490*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int callingPid, bool systemNativeClient,
1491*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId, int api1CameraId, int facing, int sensorOrientation,
1492*ec779b8eSAndroid Build Coastguard Worker int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport,
1493*ec779b8eSAndroid Build Coastguard Worker apiLevel effectiveApiLevel, bool overrideForPerfClass, int rotationOverride,
1494*ec779b8eSAndroid Build Coastguard Worker bool forceSlowJpegMode, const std::string& originalCameraId, bool sharedMode,
1495*ec779b8eSAndroid Build Coastguard Worker bool isVendorClient,
1496*ec779b8eSAndroid Build Coastguard Worker /*out*/sp<BasicClient>* client) {
1497*ec779b8eSAndroid Build Coastguard Worker // For HIDL devices
1498*ec779b8eSAndroid Build Coastguard Worker if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
1499*ec779b8eSAndroid Build Coastguard Worker // Create CameraClient based on device version reported by the HAL.
1500*ec779b8eSAndroid Build Coastguard Worker int deviceVersion = deviceVersionAndTransport.first;
1501*ec779b8eSAndroid Build Coastguard Worker switch(deviceVersion) {
1502*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_1_0:
1503*ec779b8eSAndroid Build Coastguard Worker ALOGE("Camera using old HAL version: %d", deviceVersion);
1504*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
1505*ec779b8eSAndroid Build Coastguard Worker "Camera device \"%s\" HAL version %d no longer supported",
1506*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), deviceVersion);
1507*ec779b8eSAndroid Build Coastguard Worker break;
1508*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_0:
1509*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_1:
1510*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_2:
1511*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_3:
1512*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_4:
1513*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_5:
1514*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_6:
1515*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_7:
1516*ec779b8eSAndroid Build Coastguard Worker break;
1517*ec779b8eSAndroid Build Coastguard Worker default:
1518*ec779b8eSAndroid Build Coastguard Worker // Should not be reachable
1519*ec779b8eSAndroid Build Coastguard Worker ALOGE("Unknown camera device HAL version: %d", deviceVersion);
1520*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1521*ec779b8eSAndroid Build Coastguard Worker "Camera device \"%s\" has unknown HAL version %d",
1522*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), deviceVersion);
1523*ec779b8eSAndroid Build Coastguard Worker }
1524*ec779b8eSAndroid Build Coastguard Worker }
1525*ec779b8eSAndroid Build Coastguard Worker if (effectiveApiLevel == API_1) { // Camera1 API route
1526*ec779b8eSAndroid Build Coastguard Worker sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
1527*ec779b8eSAndroid Build Coastguard Worker *client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
1528*ec779b8eSAndroid Build Coastguard Worker cameraService->mAttributionAndPermissionUtils,
1529*ec779b8eSAndroid Build Coastguard Worker clientAttribution, callingPid, cameraId, api1CameraId, facing,
1530*ec779b8eSAndroid Build Coastguard Worker sensorOrientation, servicePid, overrideForPerfClass,
1531*ec779b8eSAndroid Build Coastguard Worker rotationOverride, forceSlowJpegMode, /*sharedMode*/false);
1532*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Camera1 API (legacy), rotationOverride %d, forceSlowJpegMode %d",
1533*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, rotationOverride, forceSlowJpegMode);
1534*ec779b8eSAndroid Build Coastguard Worker } else { // Camera2 API route
1535*ec779b8eSAndroid Build Coastguard Worker sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
1536*ec779b8eSAndroid Build Coastguard Worker static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
1537*ec779b8eSAndroid Build Coastguard Worker *client = new CameraDeviceClient(
1538*ec779b8eSAndroid Build Coastguard Worker cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
1539*ec779b8eSAndroid Build Coastguard Worker cameraService->mAttributionAndPermissionUtils, clientAttribution, callingPid,
1540*ec779b8eSAndroid Build Coastguard Worker systemNativeClient, cameraId, facing, sensorOrientation, servicePid,
1541*ec779b8eSAndroid Build Coastguard Worker overrideForPerfClass, rotationOverride, originalCameraId, sharedMode,
1542*ec779b8eSAndroid Build Coastguard Worker isVendorClient);
1543*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Camera2 API, rotationOverride %d", __FUNCTION__, rotationOverride);
1544*ec779b8eSAndroid Build Coastguard Worker }
1545*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1546*ec779b8eSAndroid Build Coastguard Worker }
1547*ec779b8eSAndroid Build Coastguard Worker
toString(std::set<userid_t> intSet)1548*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::toString(std::set<userid_t> intSet) {
1549*ec779b8eSAndroid Build Coastguard Worker std::ostringstream s;
1550*ec779b8eSAndroid Build Coastguard Worker bool first = true;
1551*ec779b8eSAndroid Build Coastguard Worker for (userid_t i : intSet) {
1552*ec779b8eSAndroid Build Coastguard Worker if (first) {
1553*ec779b8eSAndroid Build Coastguard Worker s << std::to_string(i);
1554*ec779b8eSAndroid Build Coastguard Worker first = false;
1555*ec779b8eSAndroid Build Coastguard Worker } else {
1556*ec779b8eSAndroid Build Coastguard Worker s << ", " << std::to_string(i);
1557*ec779b8eSAndroid Build Coastguard Worker }
1558*ec779b8eSAndroid Build Coastguard Worker }
1559*ec779b8eSAndroid Build Coastguard Worker return s.str();
1560*ec779b8eSAndroid Build Coastguard Worker }
1561*ec779b8eSAndroid Build Coastguard Worker
mapToInterface(TorchModeStatus status)1562*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::mapToInterface(TorchModeStatus status) {
1563*ec779b8eSAndroid Build Coastguard Worker int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
1564*ec779b8eSAndroid Build Coastguard Worker switch (status) {
1565*ec779b8eSAndroid Build Coastguard Worker case TorchModeStatus::NOT_AVAILABLE:
1566*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
1567*ec779b8eSAndroid Build Coastguard Worker break;
1568*ec779b8eSAndroid Build Coastguard Worker case TorchModeStatus::AVAILABLE_OFF:
1569*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
1570*ec779b8eSAndroid Build Coastguard Worker break;
1571*ec779b8eSAndroid Build Coastguard Worker case TorchModeStatus::AVAILABLE_ON:
1572*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
1573*ec779b8eSAndroid Build Coastguard Worker break;
1574*ec779b8eSAndroid Build Coastguard Worker default:
1575*ec779b8eSAndroid Build Coastguard Worker ALOGW("Unknown new flash status: %d", eToI(status));
1576*ec779b8eSAndroid Build Coastguard Worker }
1577*ec779b8eSAndroid Build Coastguard Worker return serviceStatus;
1578*ec779b8eSAndroid Build Coastguard Worker }
1579*ec779b8eSAndroid Build Coastguard Worker
mapToInternal(CameraDeviceStatus status)1580*ec779b8eSAndroid Build Coastguard Worker CameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) {
1581*ec779b8eSAndroid Build Coastguard Worker StatusInternal serviceStatus = StatusInternal::NOT_PRESENT;
1582*ec779b8eSAndroid Build Coastguard Worker switch (status) {
1583*ec779b8eSAndroid Build Coastguard Worker case CameraDeviceStatus::NOT_PRESENT:
1584*ec779b8eSAndroid Build Coastguard Worker serviceStatus = StatusInternal::NOT_PRESENT;
1585*ec779b8eSAndroid Build Coastguard Worker break;
1586*ec779b8eSAndroid Build Coastguard Worker case CameraDeviceStatus::PRESENT:
1587*ec779b8eSAndroid Build Coastguard Worker serviceStatus = StatusInternal::PRESENT;
1588*ec779b8eSAndroid Build Coastguard Worker break;
1589*ec779b8eSAndroid Build Coastguard Worker case CameraDeviceStatus::ENUMERATING:
1590*ec779b8eSAndroid Build Coastguard Worker serviceStatus = StatusInternal::ENUMERATING;
1591*ec779b8eSAndroid Build Coastguard Worker break;
1592*ec779b8eSAndroid Build Coastguard Worker default:
1593*ec779b8eSAndroid Build Coastguard Worker ALOGW("Unknown new HAL device status: %d", eToI(status));
1594*ec779b8eSAndroid Build Coastguard Worker }
1595*ec779b8eSAndroid Build Coastguard Worker return serviceStatus;
1596*ec779b8eSAndroid Build Coastguard Worker }
1597*ec779b8eSAndroid Build Coastguard Worker
mapToInterface(StatusInternal status)1598*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::mapToInterface(StatusInternal status) {
1599*ec779b8eSAndroid Build Coastguard Worker int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
1600*ec779b8eSAndroid Build Coastguard Worker switch (status) {
1601*ec779b8eSAndroid Build Coastguard Worker case StatusInternal::NOT_PRESENT:
1602*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT;
1603*ec779b8eSAndroid Build Coastguard Worker break;
1604*ec779b8eSAndroid Build Coastguard Worker case StatusInternal::PRESENT:
1605*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::STATUS_PRESENT;
1606*ec779b8eSAndroid Build Coastguard Worker break;
1607*ec779b8eSAndroid Build Coastguard Worker case StatusInternal::ENUMERATING:
1608*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::STATUS_ENUMERATING;
1609*ec779b8eSAndroid Build Coastguard Worker break;
1610*ec779b8eSAndroid Build Coastguard Worker case StatusInternal::NOT_AVAILABLE:
1611*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE;
1612*ec779b8eSAndroid Build Coastguard Worker break;
1613*ec779b8eSAndroid Build Coastguard Worker case StatusInternal::UNKNOWN:
1614*ec779b8eSAndroid Build Coastguard Worker serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
1615*ec779b8eSAndroid Build Coastguard Worker break;
1616*ec779b8eSAndroid Build Coastguard Worker default:
1617*ec779b8eSAndroid Build Coastguard Worker ALOGW("Unknown new internal device status: %d", eToI(status));
1618*ec779b8eSAndroid Build Coastguard Worker }
1619*ec779b8eSAndroid Build Coastguard Worker return serviceStatus;
1620*ec779b8eSAndroid Build Coastguard Worker }
1621*ec779b8eSAndroid Build Coastguard Worker
initializeShimMetadata(int cameraId)1622*ec779b8eSAndroid Build Coastguard Worker Status CameraService::initializeShimMetadata(int cameraId) {
1623*ec779b8eSAndroid Build Coastguard Worker int uid = getCallingUid();
1624*ec779b8eSAndroid Build Coastguard Worker
1625*ec779b8eSAndroid Build Coastguard Worker std::string cameraIdStr = std::to_string(cameraId);
1626*ec779b8eSAndroid Build Coastguard Worker Status ret = Status::ok();
1627*ec779b8eSAndroid Build Coastguard Worker sp<Client> tmp = nullptr;
1628*ec779b8eSAndroid Build Coastguard Worker
1629*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
1630*ec779b8eSAndroid Build Coastguard Worker logConnectionAttempt(callingPid, kServiceName, cameraIdStr, API_1);
1631*ec779b8eSAndroid Build Coastguard Worker
1632*ec779b8eSAndroid Build Coastguard Worker AttributionSourceState clientAttribution =
1633*ec779b8eSAndroid Build Coastguard Worker buildAttributionSource(callingPid, uid, kServiceName, kDefaultDeviceId);
1634*ec779b8eSAndroid Build Coastguard Worker
1635*ec779b8eSAndroid Build Coastguard Worker if (!(ret = connectHelper<ICameraClient, Client>(
1636*ec779b8eSAndroid Build Coastguard Worker sp<ICameraClient>{nullptr}, cameraIdStr, cameraId, clientAttribution,
1637*ec779b8eSAndroid Build Coastguard Worker /*systemNativeClient*/ false, API_1, /*shimUpdateOnly*/ true,
1638*ec779b8eSAndroid Build Coastguard Worker /*oomScoreOffset*/ 0,
1639*ec779b8eSAndroid Build Coastguard Worker /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
1640*ec779b8eSAndroid Build Coastguard Worker /*rotationOverride*/
1641*ec779b8eSAndroid Build Coastguard Worker hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
1642*ec779b8eSAndroid Build Coastguard Worker /*forceSlowJpegMode*/ false, cameraIdStr, /*isNonSystemNdk*/ false,
1643*ec779b8eSAndroid Build Coastguard Worker /*sharedMode*/false, /*isVendorClient*/false,/*out*/ tmp))
1644*ec779b8eSAndroid Build Coastguard Worker .isOk()) {
1645*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str());
1646*ec779b8eSAndroid Build Coastguard Worker }
1647*ec779b8eSAndroid Build Coastguard Worker return ret;
1648*ec779b8eSAndroid Build Coastguard Worker }
1649*ec779b8eSAndroid Build Coastguard Worker
getLegacyParametersLazy(int cameraId,CameraParameters * parameters)1650*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getLegacyParametersLazy(int cameraId,
1651*ec779b8eSAndroid Build Coastguard Worker /*out*/
1652*ec779b8eSAndroid Build Coastguard Worker CameraParameters* parameters) {
1653*ec779b8eSAndroid Build Coastguard Worker
1654*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId);
1655*ec779b8eSAndroid Build Coastguard Worker
1656*ec779b8eSAndroid Build Coastguard Worker Status ret = Status::ok();
1657*ec779b8eSAndroid Build Coastguard Worker
1658*ec779b8eSAndroid Build Coastguard Worker if (parameters == NULL) {
1659*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: parameters must not be null", __FUNCTION__);
1660*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
1661*ec779b8eSAndroid Build Coastguard Worker }
1662*ec779b8eSAndroid Build Coastguard Worker
1663*ec779b8eSAndroid Build Coastguard Worker std::string cameraIdStr = std::to_string(cameraId);
1664*ec779b8eSAndroid Build Coastguard Worker
1665*ec779b8eSAndroid Build Coastguard Worker // Check if we already have parameters
1666*ec779b8eSAndroid Build Coastguard Worker {
1667*ec779b8eSAndroid Build Coastguard Worker // Scope for service lock
1668*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
1669*ec779b8eSAndroid Build Coastguard Worker auto cameraState = getCameraState(cameraIdStr);
1670*ec779b8eSAndroid Build Coastguard Worker if (cameraState == nullptr) {
1671*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str());
1672*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1673*ec779b8eSAndroid Build Coastguard Worker "Invalid camera ID: %s", cameraIdStr.c_str());
1674*ec779b8eSAndroid Build Coastguard Worker }
1675*ec779b8eSAndroid Build Coastguard Worker CameraParameters p = cameraState->getShimParams();
1676*ec779b8eSAndroid Build Coastguard Worker if (!p.isEmpty()) {
1677*ec779b8eSAndroid Build Coastguard Worker *parameters = p;
1678*ec779b8eSAndroid Build Coastguard Worker return ret;
1679*ec779b8eSAndroid Build Coastguard Worker }
1680*ec779b8eSAndroid Build Coastguard Worker }
1681*ec779b8eSAndroid Build Coastguard Worker
1682*ec779b8eSAndroid Build Coastguard Worker int64_t token = clearCallingIdentity();
1683*ec779b8eSAndroid Build Coastguard Worker ret = initializeShimMetadata(cameraId);
1684*ec779b8eSAndroid Build Coastguard Worker restoreCallingIdentity(token);
1685*ec779b8eSAndroid Build Coastguard Worker if (!ret.isOk()) {
1686*ec779b8eSAndroid Build Coastguard Worker // Error already logged by callee
1687*ec779b8eSAndroid Build Coastguard Worker return ret;
1688*ec779b8eSAndroid Build Coastguard Worker }
1689*ec779b8eSAndroid Build Coastguard Worker
1690*ec779b8eSAndroid Build Coastguard Worker // Check for parameters again
1691*ec779b8eSAndroid Build Coastguard Worker {
1692*ec779b8eSAndroid Build Coastguard Worker // Scope for service lock
1693*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
1694*ec779b8eSAndroid Build Coastguard Worker auto cameraState = getCameraState(cameraIdStr);
1695*ec779b8eSAndroid Build Coastguard Worker if (cameraState == nullptr) {
1696*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str());
1697*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1698*ec779b8eSAndroid Build Coastguard Worker "Invalid camera ID: %s", cameraIdStr.c_str());
1699*ec779b8eSAndroid Build Coastguard Worker }
1700*ec779b8eSAndroid Build Coastguard Worker CameraParameters p = cameraState->getShimParams();
1701*ec779b8eSAndroid Build Coastguard Worker if (!p.isEmpty()) {
1702*ec779b8eSAndroid Build Coastguard Worker *parameters = p;
1703*ec779b8eSAndroid Build Coastguard Worker return ret;
1704*ec779b8eSAndroid Build Coastguard Worker }
1705*ec779b8eSAndroid Build Coastguard Worker }
1706*ec779b8eSAndroid Build Coastguard Worker
1707*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Parameters were not initialized, or were empty. Device may not be present.",
1708*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
1709*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters");
1710*ec779b8eSAndroid Build Coastguard Worker }
1711*ec779b8eSAndroid Build Coastguard Worker
validateConnectLocked(const std::string & cameraId,const AttributionSourceState & clientAttribution,bool sharedMode) const1712*ec779b8eSAndroid Build Coastguard Worker Status CameraService::validateConnectLocked(const std::string& cameraId,
1713*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution,
1714*ec779b8eSAndroid Build Coastguard Worker bool sharedMode) const {
1715*ec779b8eSAndroid Build Coastguard Worker #ifdef __BRILLO__
1716*ec779b8eSAndroid Build Coastguard Worker UNUSED(clientAttribution);
1717*ec779b8eSAndroid Build Coastguard Worker #else
1718*ec779b8eSAndroid Build Coastguard Worker Status allowed = validateClientPermissionsLocked(cameraId, clientAttribution, sharedMode);
1719*ec779b8eSAndroid Build Coastguard Worker if (!allowed.isOk()) {
1720*ec779b8eSAndroid Build Coastguard Worker return allowed;
1721*ec779b8eSAndroid Build Coastguard Worker }
1722*ec779b8eSAndroid Build Coastguard Worker #endif // __BRILLO__
1723*ec779b8eSAndroid Build Coastguard Worker
1724*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
1725*ec779b8eSAndroid Build Coastguard Worker
1726*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
1727*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)",
1728*ec779b8eSAndroid Build Coastguard Worker callingPid);
1729*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1730*ec779b8eSAndroid Build Coastguard Worker "No camera HAL module available to open camera device \"%s\"", cameraId.c_str());
1731*ec779b8eSAndroid Build Coastguard Worker }
1732*ec779b8eSAndroid Build Coastguard Worker
1733*ec779b8eSAndroid Build Coastguard Worker if (getCameraState(cameraId) == nullptr) {
1734*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
1735*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1736*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1737*ec779b8eSAndroid Build Coastguard Worker "No camera device with ID \"%s\" available", cameraId.c_str());
1738*ec779b8eSAndroid Build Coastguard Worker }
1739*ec779b8eSAndroid Build Coastguard Worker
1740*ec779b8eSAndroid Build Coastguard Worker status_t err = checkIfDeviceIsUsable(cameraId);
1741*ec779b8eSAndroid Build Coastguard Worker if (err != NO_ERROR) {
1742*ec779b8eSAndroid Build Coastguard Worker switch(err) {
1743*ec779b8eSAndroid Build Coastguard Worker case -ENODEV:
1744*ec779b8eSAndroid Build Coastguard Worker case -EBUSY:
1745*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1746*ec779b8eSAndroid Build Coastguard Worker "No camera device with ID \"%s\" currently available", cameraId.c_str());
1747*ec779b8eSAndroid Build Coastguard Worker default:
1748*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1749*ec779b8eSAndroid Build Coastguard Worker "Unknown error connecting to ID \"%s\"", cameraId.c_str());
1750*ec779b8eSAndroid Build Coastguard Worker }
1751*ec779b8eSAndroid Build Coastguard Worker }
1752*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1753*ec779b8eSAndroid Build Coastguard Worker }
1754*ec779b8eSAndroid Build Coastguard Worker
validateClientPermissionsLocked(const std::string & cameraId,const AttributionSourceState & clientAttribution,bool sharedMode) const1755*ec779b8eSAndroid Build Coastguard Worker Status CameraService::validateClientPermissionsLocked(
1756*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId, const AttributionSourceState& clientAttribution,
1757*ec779b8eSAndroid Build Coastguard Worker bool sharedMode) const {
1758*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
1759*ec779b8eSAndroid Build Coastguard Worker int callingUid = getCallingUid();
1760*ec779b8eSAndroid Build Coastguard Worker
1761*ec779b8eSAndroid Build Coastguard Worker int clientPid = clientAttribution.pid;
1762*ec779b8eSAndroid Build Coastguard Worker int clientUid = clientAttribution.uid;
1763*ec779b8eSAndroid Build Coastguard Worker const std::string clientName = clientAttribution.packageName.value_or(kUnknownPackageName);
1764*ec779b8eSAndroid Build Coastguard Worker
1765*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
1766*ec779b8eSAndroid Build Coastguard Worker ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
1767*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1768*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" is"
1769*ec779b8eSAndroid Build Coastguard Worker "available", cameraId.c_str());
1770*ec779b8eSAndroid Build Coastguard Worker }
1771*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
1772*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
1773*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
1774*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "No camera device with ID \"%s\""
1775*ec779b8eSAndroid Build Coastguard Worker "found while trying to query device kind", cameraId.c_str());
1776*ec779b8eSAndroid Build Coastguard Worker }
1777*ec779b8eSAndroid Build Coastguard Worker
1778*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_multi_client() && sharedMode
1779*ec779b8eSAndroid Build Coastguard Worker && (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA)) {
1780*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: camera id %s is not system camera. Device sharing only supported for"
1781*ec779b8eSAndroid Build Coastguard Worker " system cameras.", __FUNCTION__, cameraId.c_str());
1782*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "camera device sharing not supported for "
1783*ec779b8eSAndroid Build Coastguard Worker "camera ID \"%s\"", cameraId.c_str());
1784*ec779b8eSAndroid Build Coastguard Worker }
1785*ec779b8eSAndroid Build Coastguard Worker
1786*ec779b8eSAndroid Build Coastguard Worker // Get the device id that owns this camera.
1787*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
1788*ec779b8eSAndroid Build Coastguard Worker AttributionSourceState clientAttributionWithDeviceId = clientAttribution;
1789*ec779b8eSAndroid Build Coastguard Worker clientAttributionWithDeviceId.deviceId = deviceId;
1790*ec779b8eSAndroid Build Coastguard Worker
1791*ec779b8eSAndroid Build Coastguard Worker // If it's not calling from cameraserver, check the permission if the
1792*ec779b8eSAndroid Build Coastguard Worker // device isn't a system only camera (shouldRejectSystemCameraConnection already checks for
1793*ec779b8eSAndroid Build Coastguard Worker // android.permission.SYSTEM_CAMERA for system only camera devices).
1794*ec779b8eSAndroid Build Coastguard Worker bool checkPermissionForCamera =
1795*ec779b8eSAndroid Build Coastguard Worker hasPermissionsForCamera(cameraId, clientAttributionWithDeviceId);
1796*ec779b8eSAndroid Build Coastguard Worker if (callingPid != getpid() &&
1797*ec779b8eSAndroid Build Coastguard Worker (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
1798*ec779b8eSAndroid Build Coastguard Worker ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
1799*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1800*ec779b8eSAndroid Build Coastguard Worker "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
1801*ec779b8eSAndroid Build Coastguard Worker clientName.c_str(), clientPid, clientUid, cameraId.c_str());
1802*ec779b8eSAndroid Build Coastguard Worker }
1803*ec779b8eSAndroid Build Coastguard Worker
1804*ec779b8eSAndroid Build Coastguard Worker // Make sure the UID is in an active state to use the camera
1805*ec779b8eSAndroid Build Coastguard Worker if (!mUidPolicy->isUidActive(callingUid, clientName)) {
1806*ec779b8eSAndroid Build Coastguard Worker int32_t procState = mUidPolicy->getProcState(callingUid);
1807*ec779b8eSAndroid Build Coastguard Worker ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
1808*ec779b8eSAndroid Build Coastguard Worker clientPid, clientUid);
1809*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISABLED,
1810*ec779b8eSAndroid Build Coastguard Worker "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background ("
1811*ec779b8eSAndroid Build Coastguard Worker "calling UID %d proc state %" PRId32 ")",
1812*ec779b8eSAndroid Build Coastguard Worker clientName.c_str(), clientPid, clientUid, cameraId.c_str(),
1813*ec779b8eSAndroid Build Coastguard Worker callingUid, procState);
1814*ec779b8eSAndroid Build Coastguard Worker }
1815*ec779b8eSAndroid Build Coastguard Worker
1816*ec779b8eSAndroid Build Coastguard Worker // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases
1817*ec779b8eSAndroid Build Coastguard Worker // such as rear view and surround view cannot be disabled and are exempt from sensor privacy
1818*ec779b8eSAndroid Build Coastguard Worker // policy. In all other cases,if sensor privacy is enabled then prevent access to the camera.
1819*ec779b8eSAndroid Build Coastguard Worker if ((!isAutomotivePrivilegedClient(callingUid) ||
1820*ec779b8eSAndroid Build Coastguard Worker !isAutomotiveExteriorSystemCamera(cameraId)) &&
1821*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
1822*ec779b8eSAndroid Build Coastguard Worker ALOGE("Access Denial: cannot use the camera when sensor privacy is enabled");
1823*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISABLED,
1824*ec779b8eSAndroid Build Coastguard Worker "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" when sensor privacy "
1825*ec779b8eSAndroid Build Coastguard Worker "is enabled", clientName.c_str(), clientPid, clientUid, cameraId.c_str());
1826*ec779b8eSAndroid Build Coastguard Worker }
1827*ec779b8eSAndroid Build Coastguard Worker
1828*ec779b8eSAndroid Build Coastguard Worker userid_t clientUserId = multiuser_get_user_id(clientUid);
1829*ec779b8eSAndroid Build Coastguard Worker
1830*ec779b8eSAndroid Build Coastguard Worker // Only use passed in clientPid to check permission. Use calling PID as the client PID that's
1831*ec779b8eSAndroid Build Coastguard Worker // connected to camera service directly.
1832*ec779b8eSAndroid Build Coastguard Worker
1833*ec779b8eSAndroid Build Coastguard Worker // For non-system clients : Only allow clients who are being used by the current foreground
1834*ec779b8eSAndroid Build Coastguard Worker // device user, unless calling from our own process.
1835*ec779b8eSAndroid Build Coastguard Worker if (!callerHasSystemUid() && callingPid != getpid() &&
1836*ec779b8eSAndroid Build Coastguard Worker (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) {
1837*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from "
1838*ec779b8eSAndroid Build Coastguard Worker "device user %d, currently allowed device users: %s)", callingPid, clientUserId,
1839*ec779b8eSAndroid Build Coastguard Worker toString(mAllowedUsers).c_str());
1840*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1841*ec779b8eSAndroid Build Coastguard Worker "Callers from device user %d are not currently allowed to connect to camera \"%s\"",
1842*ec779b8eSAndroid Build Coastguard Worker clientUserId, cameraId.c_str());
1843*ec779b8eSAndroid Build Coastguard Worker }
1844*ec779b8eSAndroid Build Coastguard Worker
1845*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_hsum_permission()) {
1846*ec779b8eSAndroid Build Coastguard Worker // If the System User tries to access the camera when the device is running in
1847*ec779b8eSAndroid Build Coastguard Worker // headless system user mode, ensure that client has the required permission
1848*ec779b8eSAndroid Build Coastguard Worker // CAMERA_HEADLESS_SYSTEM_USER.
1849*ec779b8eSAndroid Build Coastguard Worker if (isHeadlessSystemUserMode()
1850*ec779b8eSAndroid Build Coastguard Worker && (clientUserId == USER_SYSTEM)
1851*ec779b8eSAndroid Build Coastguard Worker && !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) {
1852*ec779b8eSAndroid Build Coastguard Worker ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", callingPid, clientUid);
1853*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1854*ec779b8eSAndroid Build Coastguard Worker "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" as Headless System \
1855*ec779b8eSAndroid Build Coastguard Worker User without camera headless system user permission",
1856*ec779b8eSAndroid Build Coastguard Worker clientName.c_str(), callingPid, clientUid, cameraId.c_str());
1857*ec779b8eSAndroid Build Coastguard Worker }
1858*ec779b8eSAndroid Build Coastguard Worker }
1859*ec779b8eSAndroid Build Coastguard Worker
1860*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
1861*ec779b8eSAndroid Build Coastguard Worker }
1862*ec779b8eSAndroid Build Coastguard Worker
checkIfDeviceIsUsable(const std::string & cameraId) const1863*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::checkIfDeviceIsUsable(const std::string& cameraId) const {
1864*ec779b8eSAndroid Build Coastguard Worker auto cameraState = getCameraState(cameraId);
1865*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
1866*ec779b8eSAndroid Build Coastguard Worker if (cameraState == nullptr) {
1867*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid,
1868*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
1869*ec779b8eSAndroid Build Coastguard Worker return -ENODEV;
1870*ec779b8eSAndroid Build Coastguard Worker }
1871*ec779b8eSAndroid Build Coastguard Worker
1872*ec779b8eSAndroid Build Coastguard Worker StatusInternal currentStatus = cameraState->getStatus();
1873*ec779b8eSAndroid Build Coastguard Worker if (currentStatus == StatusInternal::NOT_PRESENT) {
1874*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)",
1875*ec779b8eSAndroid Build Coastguard Worker callingPid, cameraId.c_str());
1876*ec779b8eSAndroid Build Coastguard Worker return -ENODEV;
1877*ec779b8eSAndroid Build Coastguard Worker } else if (currentStatus == StatusInternal::ENUMERATING) {
1878*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)",
1879*ec779b8eSAndroid Build Coastguard Worker callingPid, cameraId.c_str());
1880*ec779b8eSAndroid Build Coastguard Worker return -EBUSY;
1881*ec779b8eSAndroid Build Coastguard Worker }
1882*ec779b8eSAndroid Build Coastguard Worker
1883*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
1884*ec779b8eSAndroid Build Coastguard Worker }
1885*ec779b8eSAndroid Build Coastguard Worker
finishConnectLocked(const sp<BasicClient> & client,const CameraService::DescriptorPtr & desc,int oomScoreOffset,bool systemNativeClient)1886*ec779b8eSAndroid Build Coastguard Worker void CameraService::finishConnectLocked(const sp<BasicClient>& client,
1887*ec779b8eSAndroid Build Coastguard Worker const CameraService::DescriptorPtr& desc, int oomScoreOffset, bool systemNativeClient) {
1888*ec779b8eSAndroid Build Coastguard Worker
1889*ec779b8eSAndroid Build Coastguard Worker // Make a descriptor for the incoming client
1890*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor =
1891*ec779b8eSAndroid Build Coastguard Worker CameraService::CameraClientManager::makeClientDescriptor(client, desc,
1892*ec779b8eSAndroid Build Coastguard Worker oomScoreOffset, systemNativeClient);
1893*ec779b8eSAndroid Build Coastguard Worker auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
1894*ec779b8eSAndroid Build Coastguard Worker
1895*ec779b8eSAndroid Build Coastguard Worker logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
1896*ec779b8eSAndroid Build Coastguard Worker client->getPackageName());
1897*ec779b8eSAndroid Build Coastguard Worker
1898*ec779b8eSAndroid Build Coastguard Worker if (evicted.size() > 0) {
1899*ec779b8eSAndroid Build Coastguard Worker // This should never happen - clients should already have been removed in disconnect
1900*ec779b8eSAndroid Build Coastguard Worker for (auto& i : evicted) {
1901*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect",
1902*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, i->getKey().c_str());
1903*ec779b8eSAndroid Build Coastguard Worker }
1904*ec779b8eSAndroid Build Coastguard Worker
1905*ec779b8eSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly",
1906*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
1907*ec779b8eSAndroid Build Coastguard Worker }
1908*ec779b8eSAndroid Build Coastguard Worker
1909*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_multi_client()) {
1910*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp = clientDescriptor->getValue();
1911*ec779b8eSAndroid Build Coastguard Worker auto primaryClient = mActiveClientManager.getPrimaryClient(desc->getKey());
1912*ec779b8eSAndroid Build Coastguard Worker if (primaryClient == nullptr) {
1913*ec779b8eSAndroid Build Coastguard Worker // There is no primary client yet. Assign this first client as
1914*ec779b8eSAndroid Build Coastguard Worker // primary
1915*ec779b8eSAndroid Build Coastguard Worker clientSp->setPrimaryClient(true);
1916*ec779b8eSAndroid Build Coastguard Worker } else {
1917*ec779b8eSAndroid Build Coastguard Worker // There is already primary client. If the incoming client has a
1918*ec779b8eSAndroid Build Coastguard Worker // higher priority than the existing primary, then assign incoming
1919*ec779b8eSAndroid Build Coastguard Worker // client as primary and change the existing client to secondary.
1920*ec779b8eSAndroid Build Coastguard Worker // Otherwise incoming client is secondary client.
1921*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor->getPriority() <= primaryClient->getPriority()) {
1922*ec779b8eSAndroid Build Coastguard Worker clientSp->setPrimaryClient(true);
1923*ec779b8eSAndroid Build Coastguard Worker primaryClient->getValue()->setPrimaryClient(false);
1924*ec779b8eSAndroid Build Coastguard Worker primaryClient->getValue()->notifyClientSharedAccessPriorityChanged(false);
1925*ec779b8eSAndroid Build Coastguard Worker } else {
1926*ec779b8eSAndroid Build Coastguard Worker clientSp->setPrimaryClient(false);
1927*ec779b8eSAndroid Build Coastguard Worker }
1928*ec779b8eSAndroid Build Coastguard Worker }
1929*ec779b8eSAndroid Build Coastguard Worker }
1930*ec779b8eSAndroid Build Coastguard Worker
1931*ec779b8eSAndroid Build Coastguard Worker // And register a death notification for the client callback. Do
1932*ec779b8eSAndroid Build Coastguard Worker // this last to avoid Binder policy where a nested Binder
1933*ec779b8eSAndroid Build Coastguard Worker // transaction might be pre-empted to service the client death
1934*ec779b8eSAndroid Build Coastguard Worker // notification if the client process dies before linkToDeath is
1935*ec779b8eSAndroid Build Coastguard Worker // invoked.
1936*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> remoteCallback = client->getRemote();
1937*ec779b8eSAndroid Build Coastguard Worker if (remoteCallback != nullptr) {
1938*ec779b8eSAndroid Build Coastguard Worker remoteCallback->linkToDeath(this);
1939*ec779b8eSAndroid Build Coastguard Worker }
1940*ec779b8eSAndroid Build Coastguard Worker }
1941*ec779b8eSAndroid Build Coastguard Worker
handleEvictionsLocked(const std::string & cameraId,int clientPid,apiLevel effectiveApiLevel,const sp<IBinder> & remoteCallback,const std::string & packageName,int oomScoreOffset,bool systemNativeClient,bool sharedMode,sp<BasicClient> * client,std::shared_ptr<resource_policy::ClientDescriptor<std::string,sp<BasicClient>>> * partial)1942*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleEvictionsLocked(const std::string& cameraId, int clientPid,
1943*ec779b8eSAndroid Build Coastguard Worker apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback,
1944*ec779b8eSAndroid Build Coastguard Worker const std::string& packageName, int oomScoreOffset, bool systemNativeClient,
1945*ec779b8eSAndroid Build Coastguard Worker bool sharedMode,
1946*ec779b8eSAndroid Build Coastguard Worker /*out*/
1947*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient>* client,
1948*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>* partial) {
1949*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
1950*ec779b8eSAndroid Build Coastguard Worker status_t ret = NO_ERROR;
1951*ec779b8eSAndroid Build Coastguard Worker std::vector<DescriptorPtr> evictedClients;
1952*ec779b8eSAndroid Build Coastguard Worker DescriptorPtr clientDescriptor;
1953*ec779b8eSAndroid Build Coastguard Worker {
1954*ec779b8eSAndroid Build Coastguard Worker if (effectiveApiLevel == API_1) {
1955*ec779b8eSAndroid Build Coastguard Worker // If we are using API1, any existing client for this camera ID with the same remote
1956*ec779b8eSAndroid Build Coastguard Worker // should be returned rather than evicted to allow MediaRecorder to work properly.
1957*ec779b8eSAndroid Build Coastguard Worker
1958*ec779b8eSAndroid Build Coastguard Worker auto current = mActiveClientManager.get(cameraId);
1959*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
1960*ec779b8eSAndroid Build Coastguard Worker auto clientSp = current->getValue();
1961*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() != nullptr) { // should never be needed
1962*ec779b8eSAndroid Build Coastguard Worker if (!clientSp->canCastToApiClient(effectiveApiLevel)) {
1963*ec779b8eSAndroid Build Coastguard Worker ALOGW("CameraService connect called with a different"
1964*ec779b8eSAndroid Build Coastguard Worker " API level, evicting prior client...");
1965*ec779b8eSAndroid Build Coastguard Worker } else if (clientSp->getRemote() == remoteCallback) {
1966*ec779b8eSAndroid Build Coastguard Worker ALOGI("CameraService::connect X (PID %d) (second call from same"
1967*ec779b8eSAndroid Build Coastguard Worker " app binder, returning the same client)", clientPid);
1968*ec779b8eSAndroid Build Coastguard Worker *client = clientSp;
1969*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
1970*ec779b8eSAndroid Build Coastguard Worker }
1971*ec779b8eSAndroid Build Coastguard Worker }
1972*ec779b8eSAndroid Build Coastguard Worker }
1973*ec779b8eSAndroid Build Coastguard Worker }
1974*ec779b8eSAndroid Build Coastguard Worker
1975*ec779b8eSAndroid Build Coastguard Worker // Get state for the given cameraId
1976*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
1977*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
1978*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)",
1979*ec779b8eSAndroid Build Coastguard Worker clientPid, cameraId.c_str());
1980*ec779b8eSAndroid Build Coastguard Worker // Should never get here because validateConnectLocked should have errored out
1981*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
1982*ec779b8eSAndroid Build Coastguard Worker }
1983*ec779b8eSAndroid Build Coastguard Worker
1984*ec779b8eSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
1985*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = sm->checkService(String16(kProcessInfoServiceName));
1986*ec779b8eSAndroid Build Coastguard Worker if (!binder && isAutomotivePrivilegedClient(getCallingUid())) {
1987*ec779b8eSAndroid Build Coastguard Worker // If processinfo service is not available and the client is automotive privileged
1988*ec779b8eSAndroid Build Coastguard Worker // client used for safety critical uses cases such as rear-view and surround-view which
1989*ec779b8eSAndroid Build Coastguard Worker // needs to be available before android boot completes, then use the hardcoded values
1990*ec779b8eSAndroid Build Coastguard Worker // for the process state and priority score. As this scenario is before android system
1991*ec779b8eSAndroid Build Coastguard Worker // services are up and client is native client, hence using NATIVE_ADJ as the priority
1992*ec779b8eSAndroid Build Coastguard Worker // score and state as PROCESS_STATE_BOUND_TOP as such automotive apps need to be
1993*ec779b8eSAndroid Build Coastguard Worker // visible on the top.
1994*ec779b8eSAndroid Build Coastguard Worker clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
1995*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
1996*ec779b8eSAndroid Build Coastguard Worker state->getConflicting(), resource_policy::NATIVE_ADJ, clientPid,
1997*ec779b8eSAndroid Build Coastguard Worker ActivityManager::PROCESS_STATE_BOUND_TOP, oomScoreOffset, systemNativeClient,
1998*ec779b8eSAndroid Build Coastguard Worker sharedMode);
1999*ec779b8eSAndroid Build Coastguard Worker } else {
2000*ec779b8eSAndroid Build Coastguard Worker // Get current active client PIDs
2001*ec779b8eSAndroid Build Coastguard Worker std::vector<int> ownerPids(mActiveClientManager.getAllOwners());
2002*ec779b8eSAndroid Build Coastguard Worker ownerPids.push_back(clientPid);
2003*ec779b8eSAndroid Build Coastguard Worker
2004*ec779b8eSAndroid Build Coastguard Worker std::vector<int> priorityScores(ownerPids.size());
2005*ec779b8eSAndroid Build Coastguard Worker std::vector<int> states(ownerPids.size());
2006*ec779b8eSAndroid Build Coastguard Worker
2007*ec779b8eSAndroid Build Coastguard Worker // Get priority scores of all active PIDs
2008*ec779b8eSAndroid Build Coastguard Worker status_t err = ProcessInfoService::getProcessStatesScoresFromPids(ownerPids.size(),
2009*ec779b8eSAndroid Build Coastguard Worker &ownerPids[0], /*out*/&states[0], /*out*/&priorityScores[0]);
2010*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
2011*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Priority score query failed: %d", __FUNCTION__, err);
2012*ec779b8eSAndroid Build Coastguard Worker return err;
2013*ec779b8eSAndroid Build Coastguard Worker }
2014*ec779b8eSAndroid Build Coastguard Worker
2015*ec779b8eSAndroid Build Coastguard Worker // Update all active clients' priorities
2016*ec779b8eSAndroid Build Coastguard Worker std::map<int,resource_policy::ClientPriority> pidToPriorityMap;
2017*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < ownerPids.size() - 1; i++) {
2018*ec779b8eSAndroid Build Coastguard Worker pidToPriorityMap.emplace(ownerPids[i],
2019*ec779b8eSAndroid Build Coastguard Worker resource_policy::ClientPriority(priorityScores[i], states[i],
2020*ec779b8eSAndroid Build Coastguard Worker /* isVendorClient won't get copied over*/ false,
2021*ec779b8eSAndroid Build Coastguard Worker /* oomScoreOffset won't get copied over*/ 0));
2022*ec779b8eSAndroid Build Coastguard Worker }
2023*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.updatePriorities(pidToPriorityMap);
2024*ec779b8eSAndroid Build Coastguard Worker
2025*ec779b8eSAndroid Build Coastguard Worker int32_t actualScore = priorityScores[priorityScores.size() - 1];
2026*ec779b8eSAndroid Build Coastguard Worker int32_t actualState = states[states.size() - 1];
2027*ec779b8eSAndroid Build Coastguard Worker
2028*ec779b8eSAndroid Build Coastguard Worker // Make descriptor for incoming client. We store the oomScoreOffset
2029*ec779b8eSAndroid Build Coastguard Worker // since we might need it later on new handleEvictionsLocked and
2030*ec779b8eSAndroid Build Coastguard Worker // ProcessInfoService would not take that into account.
2031*ec779b8eSAndroid Build Coastguard Worker clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
2032*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
2033*ec779b8eSAndroid Build Coastguard Worker state->getConflicting(), actualScore, clientPid, actualState,
2034*ec779b8eSAndroid Build Coastguard Worker oomScoreOffset, systemNativeClient, sharedMode);
2035*ec779b8eSAndroid Build Coastguard Worker }
2036*ec779b8eSAndroid Build Coastguard Worker
2037*ec779b8eSAndroid Build Coastguard Worker resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
2038*ec779b8eSAndroid Build Coastguard Worker
2039*ec779b8eSAndroid Build Coastguard Worker // Find clients that would be evicted
2040*ec779b8eSAndroid Build Coastguard Worker auto evicted = mActiveClientManager.wouldEvict(clientDescriptor);
2041*ec779b8eSAndroid Build Coastguard Worker
2042*ec779b8eSAndroid Build Coastguard Worker // If the incoming client was 'evicted,' higher priority clients have the camera in the
2043*ec779b8eSAndroid Build Coastguard Worker // background, so we cannot do evictions
2044*ec779b8eSAndroid Build Coastguard Worker if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) {
2045*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher"
2046*ec779b8eSAndroid Build Coastguard Worker " priority).", clientPid);
2047*ec779b8eSAndroid Build Coastguard Worker
2048*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp = clientDescriptor->getValue();
2049*ec779b8eSAndroid Build Coastguard Worker std::string curTime = getFormattedCurrentTime();
2050*ec779b8eSAndroid Build Coastguard Worker auto incompatibleClients =
2051*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.getIncompatibleClients(clientDescriptor);
2052*ec779b8eSAndroid Build Coastguard Worker
2053*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("%s : DENIED connect device %s client for package %s "
2054*ec779b8eSAndroid Build Coastguard Worker "(PID %d, score %d state %d) due to eviction policy", curTime.c_str(),
2055*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), packageName.c_str(), clientPid,
2056*ec779b8eSAndroid Build Coastguard Worker clientPriority.getScore(), clientPriority.getState());
2057*ec779b8eSAndroid Build Coastguard Worker
2058*ec779b8eSAndroid Build Coastguard Worker for (auto& i : incompatibleClients) {
2059*ec779b8eSAndroid Build Coastguard Worker msg += fmt::sprintf("\n - Blocked by existing device %s client for package %s"
2060*ec779b8eSAndroid Build Coastguard Worker "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")",
2061*ec779b8eSAndroid Build Coastguard Worker i->getKey().c_str(),
2062*ec779b8eSAndroid Build Coastguard Worker i->getValue()->getPackageName().c_str(),
2063*ec779b8eSAndroid Build Coastguard Worker i->getOwnerId(), i->getPriority().getScore(),
2064*ec779b8eSAndroid Build Coastguard Worker i->getPriority().getState());
2065*ec779b8eSAndroid Build Coastguard Worker ALOGE(" Conflicts with: Device %s, client package %s (PID %"
2066*ec779b8eSAndroid Build Coastguard Worker PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().c_str(),
2067*ec779b8eSAndroid Build Coastguard Worker i->getValue()->getPackageName().c_str(), i->getOwnerId(),
2068*ec779b8eSAndroid Build Coastguard Worker i->getPriority().getScore(), i->getPriority().getState());
2069*ec779b8eSAndroid Build Coastguard Worker }
2070*ec779b8eSAndroid Build Coastguard Worker
2071*ec779b8eSAndroid Build Coastguard Worker // Log the client's attempt
2072*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mLogLock);
2073*ec779b8eSAndroid Build Coastguard Worker mEventLog.add(msg);
2074*ec779b8eSAndroid Build Coastguard Worker
2075*ec779b8eSAndroid Build Coastguard Worker auto current = mActiveClientManager.get(cameraId);
2076*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
2077*ec779b8eSAndroid Build Coastguard Worker return -EBUSY; // CAMERA_IN_USE
2078*ec779b8eSAndroid Build Coastguard Worker } else {
2079*ec779b8eSAndroid Build Coastguard Worker return -EUSERS; // MAX_CAMERAS_IN_USE
2080*ec779b8eSAndroid Build Coastguard Worker }
2081*ec779b8eSAndroid Build Coastguard Worker }
2082*ec779b8eSAndroid Build Coastguard Worker
2083*ec779b8eSAndroid Build Coastguard Worker for (auto& i : evicted) {
2084*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp = i->getValue();
2085*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() == nullptr) {
2086*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__);
2087*ec779b8eSAndroid Build Coastguard Worker
2088*ec779b8eSAndroid Build Coastguard Worker // TODO: Remove this
2089*ec779b8eSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list",
2090*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
2091*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.remove(i);
2092*ec779b8eSAndroid Build Coastguard Worker continue;
2093*ec779b8eSAndroid Build Coastguard Worker }
2094*ec779b8eSAndroid Build Coastguard Worker
2095*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
2096*ec779b8eSAndroid Build Coastguard Worker i->getKey().c_str());
2097*ec779b8eSAndroid Build Coastguard Worker evictedClients.push_back(i);
2098*ec779b8eSAndroid Build Coastguard Worker
2099*ec779b8eSAndroid Build Coastguard Worker // Log the clients evicted
2100*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID"
2101*ec779b8eSAndroid Build Coastguard Worker " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for"
2102*ec779b8eSAndroid Build Coastguard Worker " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")",
2103*ec779b8eSAndroid Build Coastguard Worker i->getKey().c_str(), clientSp->getPackageName().c_str(),
2104*ec779b8eSAndroid Build Coastguard Worker i->getOwnerId(), i->getPriority().getScore(),
2105*ec779b8eSAndroid Build Coastguard Worker i->getPriority().getState(), cameraId.c_str(),
2106*ec779b8eSAndroid Build Coastguard Worker packageName.c_str(), clientPid, clientPriority.getScore(),
2107*ec779b8eSAndroid Build Coastguard Worker clientPriority.getState()));
2108*ec779b8eSAndroid Build Coastguard Worker
2109*ec779b8eSAndroid Build Coastguard Worker // Notify the client of disconnection
2110*ec779b8eSAndroid Build Coastguard Worker clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
2111*ec779b8eSAndroid Build Coastguard Worker CaptureResultExtras());
2112*ec779b8eSAndroid Build Coastguard Worker }
2113*ec779b8eSAndroid Build Coastguard Worker }
2114*ec779b8eSAndroid Build Coastguard Worker
2115*ec779b8eSAndroid Build Coastguard Worker // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
2116*ec779b8eSAndroid Build Coastguard Worker // other clients from connecting in mServiceLockWrapper if held
2117*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
2118*ec779b8eSAndroid Build Coastguard Worker
2119*ec779b8eSAndroid Build Coastguard Worker // Clear caller identity temporarily so client disconnect PID checks work correctly
2120*ec779b8eSAndroid Build Coastguard Worker int64_t token = clearCallingIdentity();
2121*ec779b8eSAndroid Build Coastguard Worker
2122*ec779b8eSAndroid Build Coastguard Worker // Destroy evicted clients
2123*ec779b8eSAndroid Build Coastguard Worker for (auto& i : evictedClients) {
2124*ec779b8eSAndroid Build Coastguard Worker // Disconnect is blocking, and should only have returned when HAL has cleaned up
2125*ec779b8eSAndroid Build Coastguard Worker i->getValue()->disconnect(); // Clients will remove themselves from the active client list
2126*ec779b8eSAndroid Build Coastguard Worker }
2127*ec779b8eSAndroid Build Coastguard Worker
2128*ec779b8eSAndroid Build Coastguard Worker restoreCallingIdentity(token);
2129*ec779b8eSAndroid Build Coastguard Worker
2130*ec779b8eSAndroid Build Coastguard Worker for (const auto& i : evictedClients) {
2131*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
2132*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, i->getKey().c_str(), i->getOwnerId());
2133*ec779b8eSAndroid Build Coastguard Worker ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
2134*ec779b8eSAndroid Build Coastguard Worker if (ret == TIMED_OUT) {
2135*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
2136*ec779b8eSAndroid Build Coastguard Worker "current clients:\n%s", __FUNCTION__, i->getKey().c_str(),
2137*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.toString().c_str());
2138*ec779b8eSAndroid Build Coastguard Worker return -EBUSY;
2139*ec779b8eSAndroid Build Coastguard Worker }
2140*ec779b8eSAndroid Build Coastguard Worker if (ret != NO_ERROR) {
2141*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
2142*ec779b8eSAndroid Build Coastguard Worker "current clients:\n%s", __FUNCTION__, i->getKey().c_str(), strerror(-ret),
2143*ec779b8eSAndroid Build Coastguard Worker ret, mActiveClientManager.toString().c_str());
2144*ec779b8eSAndroid Build Coastguard Worker return ret;
2145*ec779b8eSAndroid Build Coastguard Worker }
2146*ec779b8eSAndroid Build Coastguard Worker }
2147*ec779b8eSAndroid Build Coastguard Worker
2148*ec779b8eSAndroid Build Coastguard Worker evictedClients.clear();
2149*ec779b8eSAndroid Build Coastguard Worker
2150*ec779b8eSAndroid Build Coastguard Worker // Once clients have been disconnected, relock
2151*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
2152*ec779b8eSAndroid Build Coastguard Worker
2153*ec779b8eSAndroid Build Coastguard Worker // Check again if the device was unplugged or something while we weren't holding mServiceLock
2154*ec779b8eSAndroid Build Coastguard Worker if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) {
2155*ec779b8eSAndroid Build Coastguard Worker return ret;
2156*ec779b8eSAndroid Build Coastguard Worker }
2157*ec779b8eSAndroid Build Coastguard Worker
2158*ec779b8eSAndroid Build Coastguard Worker *partial = clientDescriptor;
2159*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
2160*ec779b8eSAndroid Build Coastguard Worker }
2161*ec779b8eSAndroid Build Coastguard Worker
connect(const sp<ICameraClient> & cameraClient,int api1CameraId,int targetSdkVersion,int rotationOverride,bool forceSlowJpegMode,const AttributionSourceState & clientAttribution,int32_t devicePolicy,sp<ICamera> * device)2162*ec779b8eSAndroid Build Coastguard Worker Status CameraService::connect(
2163*ec779b8eSAndroid Build Coastguard Worker const sp<ICameraClient>& cameraClient,
2164*ec779b8eSAndroid Build Coastguard Worker int api1CameraId,
2165*ec779b8eSAndroid Build Coastguard Worker int targetSdkVersion,
2166*ec779b8eSAndroid Build Coastguard Worker int rotationOverride,
2167*ec779b8eSAndroid Build Coastguard Worker bool forceSlowJpegMode,
2168*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution,
2169*ec779b8eSAndroid Build Coastguard Worker int32_t devicePolicy,
2170*ec779b8eSAndroid Build Coastguard Worker /*out*/
2171*ec779b8eSAndroid Build Coastguard Worker sp<ICamera>* device) {
2172*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
2173*ec779b8eSAndroid Build Coastguard Worker Status ret = Status::ok();
2174*ec779b8eSAndroid Build Coastguard Worker
2175*ec779b8eSAndroid Build Coastguard Worker std::string cameraIdStr =
2176*ec779b8eSAndroid Build Coastguard Worker cameraIdIntToStr(api1CameraId, clientAttribution.deviceId, devicePolicy);
2177*ec779b8eSAndroid Build Coastguard Worker if (cameraIdStr.empty()) {
2178*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %d: Invalid camera id for device id %d",
2179*ec779b8eSAndroid Build Coastguard Worker api1CameraId, clientAttribution.deviceId);
2180*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2181*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
2182*ec779b8eSAndroid Build Coastguard Worker }
2183*ec779b8eSAndroid Build Coastguard Worker
2184*ec779b8eSAndroid Build Coastguard Worker std::string clientPackageNameMaybe = clientAttribution.packageName.value_or("");
2185*ec779b8eSAndroid Build Coastguard Worker bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
2186*ec779b8eSAndroid Build Coastguard Worker
2187*ec779b8eSAndroid Build Coastguard Worker AttributionSourceState resolvedClientAttribution(clientAttribution);
2188*ec779b8eSAndroid Build Coastguard Worker ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraIdStr);
2189*ec779b8eSAndroid Build Coastguard Worker if (!ret.isOk()) {
2190*ec779b8eSAndroid Build Coastguard Worker logRejected(cameraIdStr, getCallingPid(),
2191*ec779b8eSAndroid Build Coastguard Worker clientAttribution.packageName.value_or(kUnknownPackageName),
2192*ec779b8eSAndroid Build Coastguard Worker toStdString(ret.toString8()));
2193*ec779b8eSAndroid Build Coastguard Worker return ret;
2194*ec779b8eSAndroid Build Coastguard Worker }
2195*ec779b8eSAndroid Build Coastguard Worker
2196*ec779b8eSAndroid Build Coastguard Worker const int clientPid = resolvedClientAttribution.pid;
2197*ec779b8eSAndroid Build Coastguard Worker const int clientUid = resolvedClientAttribution.uid;
2198*ec779b8eSAndroid Build Coastguard Worker const std::string& clientPackageName = *resolvedClientAttribution.packageName;
2199*ec779b8eSAndroid Build Coastguard Worker
2200*ec779b8eSAndroid Build Coastguard Worker logConnectionAttempt(clientPid, clientPackageName, cameraIdStr, API_1);
2201*ec779b8eSAndroid Build Coastguard Worker
2202*ec779b8eSAndroid Build Coastguard Worker sp<Client> client = nullptr;
2203*ec779b8eSAndroid Build Coastguard Worker ret = connectHelper<ICameraClient, Client>(
2204*ec779b8eSAndroid Build Coastguard Worker cameraClient, cameraIdStr, api1CameraId, resolvedClientAttribution,
2205*ec779b8eSAndroid Build Coastguard Worker /*systemNativeClient*/ false, API_1,
2206*ec779b8eSAndroid Build Coastguard Worker /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion, rotationOverride,
2207*ec779b8eSAndroid Build Coastguard Worker forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*sharedMode*/false,
2208*ec779b8eSAndroid Build Coastguard Worker /*isVendorClient*/ false, /*out*/ client);
2209*ec779b8eSAndroid Build Coastguard Worker
2210*ec779b8eSAndroid Build Coastguard Worker if (!ret.isOk()) {
2211*ec779b8eSAndroid Build Coastguard Worker logRejected(cameraIdStr, getCallingPid(),
2212*ec779b8eSAndroid Build Coastguard Worker clientAttribution.packageName.value_or(kUnknownPackageName),
2213*ec779b8eSAndroid Build Coastguard Worker toStdString(ret.toString8()));
2214*ec779b8eSAndroid Build Coastguard Worker return ret;
2215*ec779b8eSAndroid Build Coastguard Worker }
2216*ec779b8eSAndroid Build Coastguard Worker
2217*ec779b8eSAndroid Build Coastguard Worker *device = client;
2218*ec779b8eSAndroid Build Coastguard Worker
2219*ec779b8eSAndroid Build Coastguard Worker const sp<IServiceManager> sm(defaultServiceManager());
2220*ec779b8eSAndroid Build Coastguard Worker const auto& mActivityManager = getActivityManager();
2221*ec779b8eSAndroid Build Coastguard Worker if (mActivityManager) {
2222*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiBegin(LOG_FGS_CAMERA_API,
2223*ec779b8eSAndroid Build Coastguard Worker getCallingUid(),
2224*ec779b8eSAndroid Build Coastguard Worker getCallingPid());
2225*ec779b8eSAndroid Build Coastguard Worker }
2226*ec779b8eSAndroid Build Coastguard Worker
2227*ec779b8eSAndroid Build Coastguard Worker return ret;
2228*ec779b8eSAndroid Build Coastguard Worker }
2229*ec779b8eSAndroid Build Coastguard Worker
shouldSkipStatusUpdates(SystemCameraKind systemCameraKind,bool isVendorListener,int clientPid,int clientUid)2230*ec779b8eSAndroid Build Coastguard Worker bool CameraService::shouldSkipStatusUpdates(SystemCameraKind systemCameraKind,
2231*ec779b8eSAndroid Build Coastguard Worker bool isVendorListener, int clientPid, int clientUid) {
2232*ec779b8eSAndroid Build Coastguard Worker // If the client is not a vendor client, don't add listener if
2233*ec779b8eSAndroid Build Coastguard Worker // a) the camera is a publicly hidden secure camera OR
2234*ec779b8eSAndroid Build Coastguard Worker // b) the camera is a system only camera and the client doesn't
2235*ec779b8eSAndroid Build Coastguard Worker // have android.permission.SYSTEM_CAMERA permissions.
2236*ec779b8eSAndroid Build Coastguard Worker if (!isVendorListener && (systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA ||
2237*ec779b8eSAndroid Build Coastguard Worker (systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
2238*ec779b8eSAndroid Build Coastguard Worker !hasPermissionsForSystemCamera(std::string(), clientPid, clientUid)))) {
2239*ec779b8eSAndroid Build Coastguard Worker return true;
2240*ec779b8eSAndroid Build Coastguard Worker }
2241*ec779b8eSAndroid Build Coastguard Worker return false;
2242*ec779b8eSAndroid Build Coastguard Worker }
2243*ec779b8eSAndroid Build Coastguard Worker
shouldRejectSystemCameraConnection(const std::string & cameraId) const2244*ec779b8eSAndroid Build Coastguard Worker bool CameraService::shouldRejectSystemCameraConnection(const std::string& cameraId) const {
2245*ec779b8eSAndroid Build Coastguard Worker // Rules for rejection:
2246*ec779b8eSAndroid Build Coastguard Worker // 1) If cameraserver tries to access this camera device, accept the
2247*ec779b8eSAndroid Build Coastguard Worker // connection.
2248*ec779b8eSAndroid Build Coastguard Worker // 2) The camera device is a publicly hidden secure camera device AND some
2249*ec779b8eSAndroid Build Coastguard Worker // non system component is trying to access it.
2250*ec779b8eSAndroid Build Coastguard Worker // 3) if the camera device is advertised by the camera HAL as SYSTEM_ONLY
2251*ec779b8eSAndroid Build Coastguard Worker // and the serving thread is a non hwbinder thread, the client must have
2252*ec779b8eSAndroid Build Coastguard Worker // android.permission.SYSTEM_CAMERA permissions to connect.
2253*ec779b8eSAndroid Build Coastguard Worker
2254*ec779b8eSAndroid Build Coastguard Worker int cPid = getCallingPid();
2255*ec779b8eSAndroid Build Coastguard Worker int cUid = getCallingUid();
2256*ec779b8eSAndroid Build Coastguard Worker bool systemClient = callerHasSystemUid();
2257*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
2258*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cameraId, &systemCameraKind) != OK) {
2259*ec779b8eSAndroid Build Coastguard Worker // This isn't a known camera ID, so it's not a system camera
2260*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Unknown camera id %s, ", __FUNCTION__, cameraId.c_str());
2261*ec779b8eSAndroid Build Coastguard Worker return false;
2262*ec779b8eSAndroid Build Coastguard Worker }
2263*ec779b8eSAndroid Build Coastguard Worker
2264*ec779b8eSAndroid Build Coastguard Worker // (1) Cameraserver trying to connect, accept.
2265*ec779b8eSAndroid Build Coastguard Worker if (isCallerCameraServerNotDelegating()) {
2266*ec779b8eSAndroid Build Coastguard Worker return false;
2267*ec779b8eSAndroid Build Coastguard Worker }
2268*ec779b8eSAndroid Build Coastguard Worker // (2)
2269*ec779b8eSAndroid Build Coastguard Worker if (!systemClient && systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA) {
2270*ec779b8eSAndroid Build Coastguard Worker ALOGW("Rejecting access to secure hidden camera %s", cameraId.c_str());
2271*ec779b8eSAndroid Build Coastguard Worker return true;
2272*ec779b8eSAndroid Build Coastguard Worker }
2273*ec779b8eSAndroid Build Coastguard Worker // (3) Here we only check for permissions if it is a system only camera device. This is since
2274*ec779b8eSAndroid Build Coastguard Worker // getCameraCharacteristics() allows for calls to succeed (albeit after hiding some
2275*ec779b8eSAndroid Build Coastguard Worker // characteristics) even if clients don't have android.permission.CAMERA. We do not want the
2276*ec779b8eSAndroid Build Coastguard Worker // same behavior for system camera devices.
2277*ec779b8eSAndroid Build Coastguard Worker if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
2278*ec779b8eSAndroid Build Coastguard Worker !hasPermissionsForSystemCamera(cameraId, cPid, cUid)) {
2279*ec779b8eSAndroid Build Coastguard Worker ALOGW("Rejecting access to system only camera %s, inadequete permissions",
2280*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2281*ec779b8eSAndroid Build Coastguard Worker return true;
2282*ec779b8eSAndroid Build Coastguard Worker }
2283*ec779b8eSAndroid Build Coastguard Worker
2284*ec779b8eSAndroid Build Coastguard Worker return false;
2285*ec779b8eSAndroid Build Coastguard Worker }
2286*ec779b8eSAndroid Build Coastguard Worker
connectDevice(const sp<hardware::camera2::ICameraDeviceCallbacks> & cameraCb,const std::string & unresolvedCameraId,int oomScoreOffset,int targetSdkVersion,int rotationOverride,const AttributionSourceState & clientAttribution,int32_t devicePolicy,bool sharedMode,sp<hardware::camera2::ICameraDeviceUser> * device)2287*ec779b8eSAndroid Build Coastguard Worker Status CameraService::connectDevice(
2288*ec779b8eSAndroid Build Coastguard Worker const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
2289*ec779b8eSAndroid Build Coastguard Worker const std::string& unresolvedCameraId,
2290*ec779b8eSAndroid Build Coastguard Worker int oomScoreOffset, int targetSdkVersion,
2291*ec779b8eSAndroid Build Coastguard Worker int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
2292*ec779b8eSAndroid Build Coastguard Worker bool sharedMode,
2293*ec779b8eSAndroid Build Coastguard Worker /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
2294*ec779b8eSAndroid Build Coastguard Worker return connectDeviceImpl(cameraCb, unresolvedCameraId, oomScoreOffset, targetSdkVersion,
2295*ec779b8eSAndroid Build Coastguard Worker rotationOverride, clientAttribution, devicePolicy, sharedMode,
2296*ec779b8eSAndroid Build Coastguard Worker /*isVendorClient*/false, device);
2297*ec779b8eSAndroid Build Coastguard Worker }
2298*ec779b8eSAndroid Build Coastguard Worker
connectDeviceVendor(const sp<hardware::camera2::ICameraDeviceCallbacks> & cameraCb,const std::string & unresolvedCameraId,int oomScoreOffset,int targetSdkVersion,int rotationOverride,const AttributionSourceState & clientAttribution,int32_t devicePolicy,bool sharedMode,sp<hardware::camera2::ICameraDeviceUser> * device)2299*ec779b8eSAndroid Build Coastguard Worker Status CameraService::connectDeviceVendor(
2300*ec779b8eSAndroid Build Coastguard Worker const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
2301*ec779b8eSAndroid Build Coastguard Worker const std::string& unresolvedCameraId,
2302*ec779b8eSAndroid Build Coastguard Worker int oomScoreOffset, int targetSdkVersion,
2303*ec779b8eSAndroid Build Coastguard Worker int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
2304*ec779b8eSAndroid Build Coastguard Worker bool sharedMode,
2305*ec779b8eSAndroid Build Coastguard Worker /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
2306*ec779b8eSAndroid Build Coastguard Worker return connectDeviceImpl(cameraCb, unresolvedCameraId, oomScoreOffset, targetSdkVersion,
2307*ec779b8eSAndroid Build Coastguard Worker rotationOverride, clientAttribution, devicePolicy, sharedMode,
2308*ec779b8eSAndroid Build Coastguard Worker /*isVendorClient*/true, device);
2309*ec779b8eSAndroid Build Coastguard Worker }
2310*ec779b8eSAndroid Build Coastguard Worker
connectDeviceImpl(const sp<hardware::camera2::ICameraDeviceCallbacks> & cameraCb,const std::string & unresolvedCameraId,int oomScoreOffset,int targetSdkVersion,int rotationOverride,const AttributionSourceState & clientAttribution,int32_t devicePolicy,bool sharedMode,bool isVendorClient,sp<hardware::camera2::ICameraDeviceUser> * device)2311*ec779b8eSAndroid Build Coastguard Worker Status CameraService::connectDeviceImpl(
2312*ec779b8eSAndroid Build Coastguard Worker const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
2313*ec779b8eSAndroid Build Coastguard Worker const std::string& unresolvedCameraId,
2314*ec779b8eSAndroid Build Coastguard Worker int oomScoreOffset, int targetSdkVersion,
2315*ec779b8eSAndroid Build Coastguard Worker int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
2316*ec779b8eSAndroid Build Coastguard Worker bool sharedMode, bool isVendorClient,
2317*ec779b8eSAndroid Build Coastguard Worker /*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {
2318*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
2319*ec779b8eSAndroid Build Coastguard Worker RunThreadWithRealtimePriority priorityBump;
2320*ec779b8eSAndroid Build Coastguard Worker Status ret = Status::ok();
2321*ec779b8eSAndroid Build Coastguard Worker sp<CameraDeviceClient> client = nullptr;
2322*ec779b8eSAndroid Build Coastguard Worker std::string clientPackageNameMaybe = clientAttribution.packageName.value_or("");
2323*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
2324*ec779b8eSAndroid Build Coastguard Worker int callingUid = getCallingUid();
2325*ec779b8eSAndroid Build Coastguard Worker bool systemNativeClient = false;
2326*ec779b8eSAndroid Build Coastguard Worker AttributionSourceState resolvedClientAttribution(clientAttribution);
2327*ec779b8eSAndroid Build Coastguard Worker if (callerHasSystemUid() && (clientPackageNameMaybe.size() == 0)) {
2328*ec779b8eSAndroid Build Coastguard Worker std::string systemClient = fmt::sprintf("client.pid<%d>", callingPid);
2329*ec779b8eSAndroid Build Coastguard Worker clientPackageNameMaybe = systemClient;
2330*ec779b8eSAndroid Build Coastguard Worker // Pass in packageName since AttributionAndPermissionUtils can't resolve vndk clients.
2331*ec779b8eSAndroid Build Coastguard Worker resolvedClientAttribution.packageName = clientPackageNameMaybe;
2332*ec779b8eSAndroid Build Coastguard Worker systemNativeClient = true;
2333*ec779b8eSAndroid Build Coastguard Worker }
2334*ec779b8eSAndroid Build Coastguard Worker
2335*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
2336*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId, devicePolicy);
2337*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
2338*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
2339*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
2340*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2341*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
2342*ec779b8eSAndroid Build Coastguard Worker }
2343*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
2344*ec779b8eSAndroid Build Coastguard Worker
2345*ec779b8eSAndroid Build Coastguard Worker bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
2346*ec779b8eSAndroid Build Coastguard Worker
2347*ec779b8eSAndroid Build Coastguard Worker if (!flags::data_delivery_permission_checks()) {
2348*ec779b8eSAndroid Build Coastguard Worker resolvedClientAttribution.pid = USE_CALLING_PID;
2349*ec779b8eSAndroid Build Coastguard Worker }
2350*ec779b8eSAndroid Build Coastguard Worker
2351*ec779b8eSAndroid Build Coastguard Worker ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraId);
2352*ec779b8eSAndroid Build Coastguard Worker if (!ret.isOk()) {
2353*ec779b8eSAndroid Build Coastguard Worker logRejected(cameraId, getCallingPid(), clientAttribution.packageName.value_or(""),
2354*ec779b8eSAndroid Build Coastguard Worker toStdString(ret.toString8()));
2355*ec779b8eSAndroid Build Coastguard Worker return ret;
2356*ec779b8eSAndroid Build Coastguard Worker }
2357*ec779b8eSAndroid Build Coastguard Worker
2358*ec779b8eSAndroid Build Coastguard Worker const int clientPid = resolvedClientAttribution.pid;
2359*ec779b8eSAndroid Build Coastguard Worker const int clientUid = resolvedClientAttribution.uid;
2360*ec779b8eSAndroid Build Coastguard Worker const std::string& clientPackageName = *resolvedClientAttribution.packageName;
2361*ec779b8eSAndroid Build Coastguard Worker userid_t clientUserId = multiuser_get_user_id(resolvedClientAttribution.uid);
2362*ec779b8eSAndroid Build Coastguard Worker
2363*ec779b8eSAndroid Build Coastguard Worker logConnectionAttempt(clientPid, clientPackageName, cameraId, API_2);
2364*ec779b8eSAndroid Build Coastguard Worker
2365*ec779b8eSAndroid Build Coastguard Worker if (oomScoreOffset < 0) {
2366*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
2367*ec779b8eSAndroid Build Coastguard Worker "Cannot increase the priority of a client %s pid %d for "
2368*ec779b8eSAndroid Build Coastguard Worker "camera id %s",
2369*ec779b8eSAndroid Build Coastguard Worker clientPackageName.c_str(), clientPid, cameraId.c_str());
2370*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2371*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
2372*ec779b8eSAndroid Build Coastguard Worker }
2373*ec779b8eSAndroid Build Coastguard Worker
2374*ec779b8eSAndroid Build Coastguard Worker // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases
2375*ec779b8eSAndroid Build Coastguard Worker // such as rear view and surround view cannot be disabled.
2376*ec779b8eSAndroid Build Coastguard Worker if ((!isAutomotivePrivilegedClient(callingUid) || !isAutomotiveExteriorSystemCamera(cameraId))
2377*ec779b8eSAndroid Build Coastguard Worker && mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) {
2378*ec779b8eSAndroid Build Coastguard Worker std::string msg = "Camera disabled by device policy";
2379*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2380*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISABLED, msg.c_str());
2381*ec779b8eSAndroid Build Coastguard Worker }
2382*ec779b8eSAndroid Build Coastguard Worker
2383*ec779b8eSAndroid Build Coastguard Worker // enforce system camera permissions
2384*ec779b8eSAndroid Build Coastguard Worker if (oomScoreOffset > 0 && !hasPermissionsForSystemCamera(cameraId, clientPid, callingUid) &&
2385*ec779b8eSAndroid Build Coastguard Worker !isTrustedCallingUid(callingUid)) {
2386*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf(
2387*ec779b8eSAndroid Build Coastguard Worker "Cannot change the priority of a client %s pid %d for "
2388*ec779b8eSAndroid Build Coastguard Worker "camera id %s without SYSTEM_CAMERA permissions",
2389*ec779b8eSAndroid Build Coastguard Worker clientPackageName.c_str(), clientPid, cameraId.c_str());
2390*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2391*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
2392*ec779b8eSAndroid Build Coastguard Worker }
2393*ec779b8eSAndroid Build Coastguard Worker
2394*ec779b8eSAndroid Build Coastguard Worker ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks, CameraDeviceClient>(
2395*ec779b8eSAndroid Build Coastguard Worker cameraCb, cameraId, /*api1CameraId*/ -1, resolvedClientAttribution, systemNativeClient,
2396*ec779b8eSAndroid Build Coastguard Worker API_2, /*shimUpdateOnly*/ false, oomScoreOffset, targetSdkVersion, rotationOverride,
2397*ec779b8eSAndroid Build Coastguard Worker /*forceSlowJpegMode*/ false, unresolvedCameraId, isNonSystemNdk, sharedMode,
2398*ec779b8eSAndroid Build Coastguard Worker isVendorClient, /*out*/ client);
2399*ec779b8eSAndroid Build Coastguard Worker
2400*ec779b8eSAndroid Build Coastguard Worker if (!ret.isOk()) {
2401*ec779b8eSAndroid Build Coastguard Worker logRejected(cameraId, clientPid, clientPackageName, toStdString(ret.toString8()));
2402*ec779b8eSAndroid Build Coastguard Worker return ret;
2403*ec779b8eSAndroid Build Coastguard Worker }
2404*ec779b8eSAndroid Build Coastguard Worker
2405*ec779b8eSAndroid Build Coastguard Worker *device = client;
2406*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
2407*ec779b8eSAndroid Build Coastguard Worker
2408*ec779b8eSAndroid Build Coastguard Worker // Clear the previous cached logs and reposition the
2409*ec779b8eSAndroid Build Coastguard Worker // file offset to beginning of the file to log new data.
2410*ec779b8eSAndroid Build Coastguard Worker // If either truncate or lseek fails, close the previous file and create a new one.
2411*ec779b8eSAndroid Build Coastguard Worker if ((ftruncate(mMemFd, 0) == -1) || (lseek(mMemFd, 0, SEEK_SET) == -1)) {
2412*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error while truncating the file: %s", __FUNCTION__, sFileName);
2413*ec779b8eSAndroid Build Coastguard Worker // Close the previous memfd.
2414*ec779b8eSAndroid Build Coastguard Worker close(mMemFd);
2415*ec779b8eSAndroid Build Coastguard Worker // If failure to wipe the data, then create a new file and
2416*ec779b8eSAndroid Build Coastguard Worker // assign the new value to mMemFd.
2417*ec779b8eSAndroid Build Coastguard Worker mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
2418*ec779b8eSAndroid Build Coastguard Worker if (mMemFd == -1) {
2419*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName);
2420*ec779b8eSAndroid Build Coastguard Worker }
2421*ec779b8eSAndroid Build Coastguard Worker }
2422*ec779b8eSAndroid Build Coastguard Worker const sp<IServiceManager> sm(defaultServiceManager());
2423*ec779b8eSAndroid Build Coastguard Worker const auto& mActivityManager = getActivityManager();
2424*ec779b8eSAndroid Build Coastguard Worker if (mActivityManager) {
2425*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiBegin(LOG_FGS_CAMERA_API,
2426*ec779b8eSAndroid Build Coastguard Worker callingUid,
2427*ec779b8eSAndroid Build Coastguard Worker callingPid);
2428*ec779b8eSAndroid Build Coastguard Worker }
2429*ec779b8eSAndroid Build Coastguard Worker return ret;
2430*ec779b8eSAndroid Build Coastguard Worker }
2431*ec779b8eSAndroid Build Coastguard Worker
isCameraPrivacyEnabled(const String16 & packageName,const std::string & cam_id,int callingPid,int callingUid)2432*ec779b8eSAndroid Build Coastguard Worker bool CameraService::isCameraPrivacyEnabled(const String16& packageName, const std::string& cam_id,
2433*ec779b8eSAndroid Build Coastguard Worker int callingPid, int callingUid) {
2434*ec779b8eSAndroid Build Coastguard Worker if (!isAutomotiveDevice()) {
2435*ec779b8eSAndroid Build Coastguard Worker return mSensorPrivacyPolicy->isCameraPrivacyEnabled();
2436*ec779b8eSAndroid Build Coastguard Worker }
2437*ec779b8eSAndroid Build Coastguard Worker
2438*ec779b8eSAndroid Build Coastguard Worker // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for
2439*ec779b8eSAndroid Build Coastguard Worker // safety-critical use cases cannot be disabled and are exempt from camera privacy policy.
2440*ec779b8eSAndroid Build Coastguard Worker if ((isAutomotivePrivilegedClient(callingUid) && isAutomotiveExteriorSystemCamera(cam_id))) {
2441*ec779b8eSAndroid Build Coastguard Worker ALOGI("Camera privacy cannot be enabled for automotive privileged client %d "
2442*ec779b8eSAndroid Build Coastguard Worker "using camera %s", callingUid, cam_id.c_str());
2443*ec779b8eSAndroid Build Coastguard Worker return false;
2444*ec779b8eSAndroid Build Coastguard Worker }
2445*ec779b8eSAndroid Build Coastguard Worker
2446*ec779b8eSAndroid Build Coastguard Worker if (mSensorPrivacyPolicy->isCameraPrivacyEnabled(packageName)) {
2447*ec779b8eSAndroid Build Coastguard Worker return true;
2448*ec779b8eSAndroid Build Coastguard Worker } else if (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::DISABLED) {
2449*ec779b8eSAndroid Build Coastguard Worker return false;
2450*ec779b8eSAndroid Build Coastguard Worker } else if (mSensorPrivacyPolicy->getCameraPrivacyState()
2451*ec779b8eSAndroid Build Coastguard Worker == SensorPrivacyManager::ENABLED_EXCEPT_ALLOWLISTED_APPS) {
2452*ec779b8eSAndroid Build Coastguard Worker if (hasPermissionsForCameraPrivacyAllowlist(callingPid, callingUid)) {
2453*ec779b8eSAndroid Build Coastguard Worker return false;
2454*ec779b8eSAndroid Build Coastguard Worker } else {
2455*ec779b8eSAndroid Build Coastguard Worker return true;
2456*ec779b8eSAndroid Build Coastguard Worker }
2457*ec779b8eSAndroid Build Coastguard Worker }
2458*ec779b8eSAndroid Build Coastguard Worker return false;
2459*ec779b8eSAndroid Build Coastguard Worker }
2460*ec779b8eSAndroid Build Coastguard Worker
logConnectionAttempt(int clientPid,const std::string & clientPackageName,const std::string & cameraId,apiLevel effectiveApiLevel) const2461*ec779b8eSAndroid Build Coastguard Worker void CameraService::logConnectionAttempt(int clientPid, const std::string& clientPackageName,
2462*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId,
2463*ec779b8eSAndroid Build Coastguard Worker apiLevel effectiveApiLevel) const {
2464*ec779b8eSAndroid Build Coastguard Worker ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
2465*ec779b8eSAndroid Build Coastguard Worker "Camera API version %d",
2466*ec779b8eSAndroid Build Coastguard Worker clientPid, clientPackageName.c_str(), cameraId.c_str(),
2467*ec779b8eSAndroid Build Coastguard Worker static_cast<int>(effectiveApiLevel));
2468*ec779b8eSAndroid Build Coastguard Worker }
2469*ec779b8eSAndroid Build Coastguard Worker
2470*ec779b8eSAndroid Build Coastguard Worker template <class CALLBACK, class CLIENT>
connectHelper(const sp<CALLBACK> & cameraCb,const std::string & cameraId,int api1CameraId,const AttributionSourceState & clientAttribution,bool systemNativeClient,apiLevel effectiveApiLevel,bool shimUpdateOnly,int oomScoreOffset,int targetSdkVersion,int rotationOverride,bool forceSlowJpegMode,const std::string & originalCameraId,bool isNonSystemNdk,bool sharedMode,bool isVendorClient,sp<CLIENT> & device)2471*ec779b8eSAndroid Build Coastguard Worker Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
2472*ec779b8eSAndroid Build Coastguard Worker int api1CameraId,
2473*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution,
2474*ec779b8eSAndroid Build Coastguard Worker bool systemNativeClient, apiLevel effectiveApiLevel,
2475*ec779b8eSAndroid Build Coastguard Worker bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
2476*ec779b8eSAndroid Build Coastguard Worker int rotationOverride, bool forceSlowJpegMode,
2477*ec779b8eSAndroid Build Coastguard Worker const std::string& originalCameraId, bool isNonSystemNdk,
2478*ec779b8eSAndroid Build Coastguard Worker bool sharedMode, bool isVendorClient,
2479*ec779b8eSAndroid Build Coastguard Worker /*out*/ sp<CLIENT>& device) {
2480*ec779b8eSAndroid Build Coastguard Worker binder::Status ret = binder::Status::ok();
2481*ec779b8eSAndroid Build Coastguard Worker
2482*ec779b8eSAndroid Build Coastguard Worker nsecs_t openTimeNs = systemTime();
2483*ec779b8eSAndroid Build Coastguard Worker
2484*ec779b8eSAndroid Build Coastguard Worker sp<CLIENT> client = nullptr;
2485*ec779b8eSAndroid Build Coastguard Worker int facing = -1;
2486*ec779b8eSAndroid Build Coastguard Worker int orientation = 0;
2487*ec779b8eSAndroid Build Coastguard Worker
2488*ec779b8eSAndroid Build Coastguard Worker const std::string clientPackageName =
2489*ec779b8eSAndroid Build Coastguard Worker clientAttribution.packageName.value_or(kUnknownPackageName);
2490*ec779b8eSAndroid Build Coastguard Worker
2491*ec779b8eSAndroid Build Coastguard Worker {
2492*ec779b8eSAndroid Build Coastguard Worker // Acquire mServiceLock and prevent other clients from connecting
2493*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<AutoConditionLock> lock =
2494*ec779b8eSAndroid Build Coastguard Worker AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
2495*ec779b8eSAndroid Build Coastguard Worker
2496*ec779b8eSAndroid Build Coastguard Worker if (lock == nullptr) {
2497*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting).",
2498*ec779b8eSAndroid Build Coastguard Worker clientAttribution.pid);
2499*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(
2500*ec779b8eSAndroid Build Coastguard Worker ERROR_MAX_CAMERAS_IN_USE,
2501*ec779b8eSAndroid Build Coastguard Worker "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
2502*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), clientPackageName.c_str(), clientAttribution.pid);
2503*ec779b8eSAndroid Build Coastguard Worker }
2504*ec779b8eSAndroid Build Coastguard Worker
2505*ec779b8eSAndroid Build Coastguard Worker // Enforce client permissions and do basic validity checks
2506*ec779b8eSAndroid Build Coastguard Worker if (!(ret = validateConnectLocked(cameraId, clientAttribution, sharedMode)).isOk()) {
2507*ec779b8eSAndroid Build Coastguard Worker return ret;
2508*ec779b8eSAndroid Build Coastguard Worker }
2509*ec779b8eSAndroid Build Coastguard Worker
2510*ec779b8eSAndroid Build Coastguard Worker // Check the shim parameters after acquiring lock, if they have already been updated and
2511*ec779b8eSAndroid Build Coastguard Worker // we were doing a shim update, return immediately
2512*ec779b8eSAndroid Build Coastguard Worker if (shimUpdateOnly) {
2513*ec779b8eSAndroid Build Coastguard Worker auto cameraState = getCameraState(cameraId);
2514*ec779b8eSAndroid Build Coastguard Worker if (cameraState != nullptr) {
2515*ec779b8eSAndroid Build Coastguard Worker if (!cameraState->getShimParams().isEmpty()) return ret;
2516*ec779b8eSAndroid Build Coastguard Worker }
2517*ec779b8eSAndroid Build Coastguard Worker }
2518*ec779b8eSAndroid Build Coastguard Worker
2519*ec779b8eSAndroid Build Coastguard Worker status_t err;
2520*ec779b8eSAndroid Build Coastguard Worker
2521*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientTmp = nullptr;
2522*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>> partial;
2523*ec779b8eSAndroid Build Coastguard Worker if ((err = handleEvictionsLocked(
2524*ec779b8eSAndroid Build Coastguard Worker cameraId, clientAttribution.pid, effectiveApiLevel,
2525*ec779b8eSAndroid Build Coastguard Worker IInterface::asBinder(cameraCb),
2526*ec779b8eSAndroid Build Coastguard Worker clientAttribution.packageName.value_or(kUnknownPackageName), oomScoreOffset,
2527*ec779b8eSAndroid Build Coastguard Worker systemNativeClient, sharedMode, /*out*/ &clientTmp,
2528*ec779b8eSAndroid Build Coastguard Worker /*out*/ &partial)) != NO_ERROR) {
2529*ec779b8eSAndroid Build Coastguard Worker switch (err) {
2530*ec779b8eSAndroid Build Coastguard Worker case -ENODEV:
2531*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
2532*ec779b8eSAndroid Build Coastguard Worker "No camera device with ID \"%s\" currently available",
2533*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2534*ec779b8eSAndroid Build Coastguard Worker case -EBUSY:
2535*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
2536*ec779b8eSAndroid Build Coastguard Worker "Higher-priority client using camera, ID \"%s\" currently unavailable",
2537*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2538*ec779b8eSAndroid Build Coastguard Worker case -EUSERS:
2539*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
2540*ec779b8eSAndroid Build Coastguard Worker "Too many cameras already open, cannot open camera \"%s\"",
2541*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2542*ec779b8eSAndroid Build Coastguard Worker default:
2543*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
2544*ec779b8eSAndroid Build Coastguard Worker "Unexpected error %s (%d) opening camera \"%s\"",
2545*ec779b8eSAndroid Build Coastguard Worker strerror(-err), err, cameraId.c_str());
2546*ec779b8eSAndroid Build Coastguard Worker }
2547*ec779b8eSAndroid Build Coastguard Worker }
2548*ec779b8eSAndroid Build Coastguard Worker
2549*ec779b8eSAndroid Build Coastguard Worker if (clientTmp.get() != nullptr) {
2550*ec779b8eSAndroid Build Coastguard Worker // Handle special case for API1 MediaRecorder where the existing client is returned
2551*ec779b8eSAndroid Build Coastguard Worker device = static_cast<CLIENT*>(clientTmp.get());
2552*ec779b8eSAndroid Build Coastguard Worker return ret;
2553*ec779b8eSAndroid Build Coastguard Worker }
2554*ec779b8eSAndroid Build Coastguard Worker
2555*ec779b8eSAndroid Build Coastguard Worker // give flashlight a chance to close devices if necessary.
2556*ec779b8eSAndroid Build Coastguard Worker mFlashlight->prepareDeviceOpen(cameraId);
2557*ec779b8eSAndroid Build Coastguard Worker
2558*ec779b8eSAndroid Build Coastguard Worker int portraitRotation;
2559*ec779b8eSAndroid Build Coastguard Worker auto deviceVersionAndTransport =
2560*ec779b8eSAndroid Build Coastguard Worker getDeviceVersion(cameraId, rotationOverride, /*out*/&portraitRotation,
2561*ec779b8eSAndroid Build Coastguard Worker /*out*/&facing, /*out*/&orientation);
2562*ec779b8eSAndroid Build Coastguard Worker if (facing == -1) {
2563*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str());
2564*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
2565*ec779b8eSAndroid Build Coastguard Worker "Unable to get camera device \"%s\" facing", cameraId.c_str());
2566*ec779b8eSAndroid Build Coastguard Worker }
2567*ec779b8eSAndroid Build Coastguard Worker
2568*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> tmp = nullptr;
2569*ec779b8eSAndroid Build Coastguard Worker bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
2570*ec779b8eSAndroid Build Coastguard Worker mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion);
2571*ec779b8eSAndroid Build Coastguard Worker
2572*ec779b8eSAndroid Build Coastguard Worker // Only use passed in clientPid to check permission. Use calling PID as the client PID
2573*ec779b8eSAndroid Build Coastguard Worker // that's connected to camera service directly.
2574*ec779b8eSAndroid Build Coastguard Worker if (!(ret = makeClient(this, cameraCb, clientAttribution, getCallingPid(),
2575*ec779b8eSAndroid Build Coastguard Worker systemNativeClient, cameraId, api1CameraId, facing, orientation,
2576*ec779b8eSAndroid Build Coastguard Worker getpid(), deviceVersionAndTransport, effectiveApiLevel,
2577*ec779b8eSAndroid Build Coastguard Worker overrideForPerfClass, rotationOverride, forceSlowJpegMode,
2578*ec779b8eSAndroid Build Coastguard Worker originalCameraId, sharedMode, isVendorClient,
2579*ec779b8eSAndroid Build Coastguard Worker /*out*/ &tmp))
2580*ec779b8eSAndroid Build Coastguard Worker .isOk()) {
2581*ec779b8eSAndroid Build Coastguard Worker return ret;
2582*ec779b8eSAndroid Build Coastguard Worker }
2583*ec779b8eSAndroid Build Coastguard Worker client = static_cast<CLIENT*>(tmp.get());
2584*ec779b8eSAndroid Build Coastguard Worker
2585*ec779b8eSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
2586*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
2587*ec779b8eSAndroid Build Coastguard Worker
2588*ec779b8eSAndroid Build Coastguard Worker std::string monitorTags = isClientWatched(client.get()) ? mMonitorTags : std::string();
2589*ec779b8eSAndroid Build Coastguard Worker err = client->initialize(mCameraProviderManager, monitorTags);
2590*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
2591*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
2592*ec779b8eSAndroid Build Coastguard Worker // Errors could be from the HAL module open call or from AppOpsManager
2593*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
2594*ec779b8eSAndroid Build Coastguard Worker client->disconnect();
2595*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
2596*ec779b8eSAndroid Build Coastguard Worker switch(err) {
2597*ec779b8eSAndroid Build Coastguard Worker case BAD_VALUE:
2598*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
2599*ec779b8eSAndroid Build Coastguard Worker "Illegal argument to HAL module for camera \"%s\"", cameraId.c_str());
2600*ec779b8eSAndroid Build Coastguard Worker case -EBUSY:
2601*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
2602*ec779b8eSAndroid Build Coastguard Worker "Camera \"%s\" is already open", cameraId.c_str());
2603*ec779b8eSAndroid Build Coastguard Worker case -EUSERS:
2604*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
2605*ec779b8eSAndroid Build Coastguard Worker "Too many cameras already open, cannot open camera \"%s\"",
2606*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2607*ec779b8eSAndroid Build Coastguard Worker case PERMISSION_DENIED:
2608*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
2609*ec779b8eSAndroid Build Coastguard Worker "No permission to open camera \"%s\"", cameraId.c_str());
2610*ec779b8eSAndroid Build Coastguard Worker case -EACCES:
2611*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISABLED,
2612*ec779b8eSAndroid Build Coastguard Worker "Camera \"%s\" disabled by policy", cameraId.c_str());
2613*ec779b8eSAndroid Build Coastguard Worker case -ENODEV:
2614*ec779b8eSAndroid Build Coastguard Worker default:
2615*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
2616*ec779b8eSAndroid Build Coastguard Worker "Failed to initialize camera \"%s\": %s (%d)", cameraId.c_str(),
2617*ec779b8eSAndroid Build Coastguard Worker strerror(-err), err);
2618*ec779b8eSAndroid Build Coastguard Worker }
2619*ec779b8eSAndroid Build Coastguard Worker }
2620*ec779b8eSAndroid Build Coastguard Worker
2621*ec779b8eSAndroid Build Coastguard Worker // Update shim paremeters for legacy clients
2622*ec779b8eSAndroid Build Coastguard Worker if (effectiveApiLevel == API_1) {
2623*ec779b8eSAndroid Build Coastguard Worker // Assume we have always received a Client subclass for API1
2624*ec779b8eSAndroid Build Coastguard Worker sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
2625*ec779b8eSAndroid Build Coastguard Worker String8 rawParams = shimClient->getParameters();
2626*ec779b8eSAndroid Build Coastguard Worker CameraParameters params(rawParams);
2627*ec779b8eSAndroid Build Coastguard Worker
2628*ec779b8eSAndroid Build Coastguard Worker auto cameraState = getCameraState(cameraId);
2629*ec779b8eSAndroid Build Coastguard Worker if (cameraState != nullptr) {
2630*ec779b8eSAndroid Build Coastguard Worker cameraState->setShimParams(params);
2631*ec779b8eSAndroid Build Coastguard Worker } else {
2632*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
2633*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
2634*ec779b8eSAndroid Build Coastguard Worker }
2635*ec779b8eSAndroid Build Coastguard Worker }
2636*ec779b8eSAndroid Build Coastguard Worker
2637*ec779b8eSAndroid Build Coastguard Worker // Enable/disable camera service watchdog
2638*ec779b8eSAndroid Build Coastguard Worker client->setCameraServiceWatchdog(mCameraServiceWatchdogEnabled);
2639*ec779b8eSAndroid Build Coastguard Worker
2640*ec779b8eSAndroid Build Coastguard Worker CameraMetadata chars;
2641*ec779b8eSAndroid Build Coastguard Worker bool rotateAndCropSupported = true;
2642*ec779b8eSAndroid Build Coastguard Worker err = mCameraProviderManager->getCameraCharacteristics(cameraId, overrideForPerfClass,
2643*ec779b8eSAndroid Build Coastguard Worker &chars, rotationOverride);
2644*ec779b8eSAndroid Build Coastguard Worker if (err == OK) {
2645*ec779b8eSAndroid Build Coastguard Worker auto availableRotateCropEntry = chars.find(
2646*ec779b8eSAndroid Build Coastguard Worker ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES);
2647*ec779b8eSAndroid Build Coastguard Worker if (availableRotateCropEntry.count <= 1) {
2648*ec779b8eSAndroid Build Coastguard Worker rotateAndCropSupported = false;
2649*ec779b8eSAndroid Build Coastguard Worker }
2650*ec779b8eSAndroid Build Coastguard Worker } else {
2651*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Unable to query static metadata for camera %s: %s (%d)", __FUNCTION__,
2652*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-err), err);
2653*ec779b8eSAndroid Build Coastguard Worker }
2654*ec779b8eSAndroid Build Coastguard Worker
2655*ec779b8eSAndroid Build Coastguard Worker if (rotateAndCropSupported) {
2656*ec779b8eSAndroid Build Coastguard Worker // Set rotate-and-crop override behavior
2657*ec779b8eSAndroid Build Coastguard Worker if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
2658*ec779b8eSAndroid Build Coastguard Worker client->setRotateAndCropOverride(mOverrideRotateAndCropMode);
2659*ec779b8eSAndroid Build Coastguard Worker } else if (rotationOverride != hardware::ICameraService::ROTATION_OVERRIDE_NONE &&
2660*ec779b8eSAndroid Build Coastguard Worker portraitRotation != 0) {
2661*ec779b8eSAndroid Build Coastguard Worker uint8_t rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_AUTO;
2662*ec779b8eSAndroid Build Coastguard Worker switch (portraitRotation) {
2663*ec779b8eSAndroid Build Coastguard Worker case 90:
2664*ec779b8eSAndroid Build Coastguard Worker rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_90;
2665*ec779b8eSAndroid Build Coastguard Worker break;
2666*ec779b8eSAndroid Build Coastguard Worker case 180:
2667*ec779b8eSAndroid Build Coastguard Worker rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_180;
2668*ec779b8eSAndroid Build Coastguard Worker break;
2669*ec779b8eSAndroid Build Coastguard Worker case 270:
2670*ec779b8eSAndroid Build Coastguard Worker rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_270;
2671*ec779b8eSAndroid Build Coastguard Worker break;
2672*ec779b8eSAndroid Build Coastguard Worker default:
2673*ec779b8eSAndroid Build Coastguard Worker ALOGE("Unexpected portrait rotation: %d", portraitRotation);
2674*ec779b8eSAndroid Build Coastguard Worker break;
2675*ec779b8eSAndroid Build Coastguard Worker }
2676*ec779b8eSAndroid Build Coastguard Worker // Here we're communicating to the client the chosen rotate
2677*ec779b8eSAndroid Build Coastguard Worker // and crop mode to send to the HAL
2678*ec779b8eSAndroid Build Coastguard Worker client->setRotateAndCropOverride(rotateAndCropMode);
2679*ec779b8eSAndroid Build Coastguard Worker } else {
2680*ec779b8eSAndroid Build Coastguard Worker client->setRotateAndCropOverride(
2681*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->getRotateAndCropOverride(
2682*ec779b8eSAndroid Build Coastguard Worker clientPackageName, facing,
2683*ec779b8eSAndroid Build Coastguard Worker multiuser_get_user_id(clientAttribution.uid)));
2684*ec779b8eSAndroid Build Coastguard Worker }
2685*ec779b8eSAndroid Build Coastguard Worker }
2686*ec779b8eSAndroid Build Coastguard Worker
2687*ec779b8eSAndroid Build Coastguard Worker bool autoframingSupported = true;
2688*ec779b8eSAndroid Build Coastguard Worker auto availableAutoframingEntry = chars.find(ANDROID_CONTROL_AUTOFRAMING_AVAILABLE);
2689*ec779b8eSAndroid Build Coastguard Worker if ((availableAutoframingEntry.count == 1) && (availableAutoframingEntry.data.u8[0] ==
2690*ec779b8eSAndroid Build Coastguard Worker ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE)) {
2691*ec779b8eSAndroid Build Coastguard Worker autoframingSupported = false;
2692*ec779b8eSAndroid Build Coastguard Worker }
2693*ec779b8eSAndroid Build Coastguard Worker
2694*ec779b8eSAndroid Build Coastguard Worker if (autoframingSupported) {
2695*ec779b8eSAndroid Build Coastguard Worker // Set autoframing override behaviour
2696*ec779b8eSAndroid Build Coastguard Worker if (mOverrideAutoframingMode != ANDROID_CONTROL_AUTOFRAMING_AUTO) {
2697*ec779b8eSAndroid Build Coastguard Worker client->setAutoframingOverride(mOverrideAutoframingMode);
2698*ec779b8eSAndroid Build Coastguard Worker } else {
2699*ec779b8eSAndroid Build Coastguard Worker client->setAutoframingOverride(
2700*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->getAutoframingOverride(
2701*ec779b8eSAndroid Build Coastguard Worker clientPackageName));
2702*ec779b8eSAndroid Build Coastguard Worker }
2703*ec779b8eSAndroid Build Coastguard Worker }
2704*ec779b8eSAndroid Build Coastguard Worker
2705*ec779b8eSAndroid Build Coastguard Worker bool isCameraPrivacyEnabled;
2706*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_privacy_allowlist()) {
2707*ec779b8eSAndroid Build Coastguard Worker // Set camera muting behavior.
2708*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled =
2709*ec779b8eSAndroid Build Coastguard Worker this->isCameraPrivacyEnabled(toString16(client->getPackageName()), cameraId,
2710*ec779b8eSAndroid Build Coastguard Worker clientAttribution.pid, clientAttribution.uid);
2711*ec779b8eSAndroid Build Coastguard Worker } else {
2712*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled =
2713*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy->isCameraPrivacyEnabled();
2714*ec779b8eSAndroid Build Coastguard Worker }
2715*ec779b8eSAndroid Build Coastguard Worker
2716*ec779b8eSAndroid Build Coastguard Worker if (client->supportsCameraMute()) {
2717*ec779b8eSAndroid Build Coastguard Worker client->setCameraMute(
2718*ec779b8eSAndroid Build Coastguard Worker mOverrideCameraMuteMode || isCameraPrivacyEnabled);
2719*ec779b8eSAndroid Build Coastguard Worker } else if (isCameraPrivacyEnabled) {
2720*ec779b8eSAndroid Build Coastguard Worker // no camera mute supported, but privacy is on! => disconnect
2721*ec779b8eSAndroid Build Coastguard Worker ALOGI("Camera mute not supported for package: %s, camera id: %s",
2722*ec779b8eSAndroid Build Coastguard Worker client->getPackageName().c_str(), cameraId.c_str());
2723*ec779b8eSAndroid Build Coastguard Worker // Do not hold mServiceLock while disconnecting clients, but
2724*ec779b8eSAndroid Build Coastguard Worker // retain the condition blocking other clients from connecting
2725*ec779b8eSAndroid Build Coastguard Worker // in mServiceLockWrapper if held.
2726*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
2727*ec779b8eSAndroid Build Coastguard Worker // Clear caller identity temporarily so client disconnect PID
2728*ec779b8eSAndroid Build Coastguard Worker // checks work correctly
2729*ec779b8eSAndroid Build Coastguard Worker int64_t token = clearCallingIdentity();
2730*ec779b8eSAndroid Build Coastguard Worker // Note AppOp to trigger the "Unblock" dialog
2731*ec779b8eSAndroid Build Coastguard Worker client->noteAppOp();
2732*ec779b8eSAndroid Build Coastguard Worker client->disconnect();
2733*ec779b8eSAndroid Build Coastguard Worker restoreCallingIdentity(token);
2734*ec779b8eSAndroid Build Coastguard Worker // Reacquire mServiceLock
2735*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
2736*ec779b8eSAndroid Build Coastguard Worker
2737*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISABLED,
2738*ec779b8eSAndroid Build Coastguard Worker "Camera \"%s\" disabled due to camera mute", cameraId.c_str());
2739*ec779b8eSAndroid Build Coastguard Worker }
2740*ec779b8eSAndroid Build Coastguard Worker
2741*ec779b8eSAndroid Build Coastguard Worker if (shimUpdateOnly) {
2742*ec779b8eSAndroid Build Coastguard Worker // If only updating legacy shim parameters, immediately disconnect client
2743*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
2744*ec779b8eSAndroid Build Coastguard Worker client->disconnect();
2745*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
2746*ec779b8eSAndroid Build Coastguard Worker } else {
2747*ec779b8eSAndroid Build Coastguard Worker // Otherwise, add client to active clients list
2748*ec779b8eSAndroid Build Coastguard Worker finishConnectLocked(client, partial, oomScoreOffset, systemNativeClient);
2749*ec779b8eSAndroid Build Coastguard Worker }
2750*ec779b8eSAndroid Build Coastguard Worker
2751*ec779b8eSAndroid Build Coastguard Worker client->setImageDumpMask(mImageDumpMask);
2752*ec779b8eSAndroid Build Coastguard Worker client->setStreamUseCaseOverrides(mStreamUseCaseOverrides);
2753*ec779b8eSAndroid Build Coastguard Worker client->setZoomOverride(mZoomOverrideValue);
2754*ec779b8eSAndroid Build Coastguard Worker } // lock is destroyed, allow further connect calls
2755*ec779b8eSAndroid Build Coastguard Worker
2756*ec779b8eSAndroid Build Coastguard Worker // Important: release the mutex here so the client can call back into the service from its
2757*ec779b8eSAndroid Build Coastguard Worker // destructor (can be at the end of the call)
2758*ec779b8eSAndroid Build Coastguard Worker device = client;
2759*ec779b8eSAndroid Build Coastguard Worker
2760*ec779b8eSAndroid Build Coastguard Worker int32_t openLatencyMs = ns2ms(systemTime() - openTimeNs);
2761*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->logOpen(cameraId, facing, clientPackageName,
2762*ec779b8eSAndroid Build Coastguard Worker effectiveApiLevel, isNonSystemNdk, openLatencyMs);
2763*ec779b8eSAndroid Build Coastguard Worker
2764*ec779b8eSAndroid Build Coastguard Worker {
2765*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mInjectionParametersLock);
2766*ec779b8eSAndroid Build Coastguard Worker if (cameraId == mInjectionInternalCamId && mInjectionInitPending) {
2767*ec779b8eSAndroid Build Coastguard Worker mInjectionInitPending = false;
2768*ec779b8eSAndroid Build Coastguard Worker status_t res = NO_ERROR;
2769*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId);
2770*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor != nullptr) {
2771*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp = clientDescriptor->getValue();
2772*ec779b8eSAndroid Build Coastguard Worker res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp);
2773*ec779b8eSAndroid Build Coastguard Worker if(res != OK) {
2774*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
2775*ec779b8eSAndroid Build Coastguard Worker "No camera device with ID \"%s\" currently available",
2776*ec779b8eSAndroid Build Coastguard Worker mInjectionExternalCamId.c_str());
2777*ec779b8eSAndroid Build Coastguard Worker }
2778*ec779b8eSAndroid Build Coastguard Worker res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager);
2779*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
2780*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res);
2781*ec779b8eSAndroid Build Coastguard Worker }
2782*ec779b8eSAndroid Build Coastguard Worker } else {
2783*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Internal camera ID = %s 's client does not exist!",
2784*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, mInjectionInternalCamId.c_str());
2785*ec779b8eSAndroid Build Coastguard Worker res = NO_INIT;
2786*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res);
2787*ec779b8eSAndroid Build Coastguard Worker }
2788*ec779b8eSAndroid Build Coastguard Worker }
2789*ec779b8eSAndroid Build Coastguard Worker }
2790*ec779b8eSAndroid Build Coastguard Worker
2791*ec779b8eSAndroid Build Coastguard Worker return ret;
2792*ec779b8eSAndroid Build Coastguard Worker }
2793*ec779b8eSAndroid Build Coastguard Worker
addOfflineClient(const std::string & cameraId,sp<BasicClient> offlineClient)2794*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::addOfflineClient(const std::string &cameraId,
2795*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> offlineClient) {
2796*ec779b8eSAndroid Build Coastguard Worker if (offlineClient.get() == nullptr) {
2797*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
2798*ec779b8eSAndroid Build Coastguard Worker }
2799*ec779b8eSAndroid Build Coastguard Worker
2800*ec779b8eSAndroid Build Coastguard Worker {
2801*ec779b8eSAndroid Build Coastguard Worker // Acquire mServiceLock and prevent other clients from connecting
2802*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<AutoConditionLock> lock =
2803*ec779b8eSAndroid Build Coastguard Worker AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
2804*ec779b8eSAndroid Build Coastguard Worker
2805*ec779b8eSAndroid Build Coastguard Worker if (lock == nullptr) {
2806*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: (PID %d) rejected (too many other clients connecting)."
2807*ec779b8eSAndroid Build Coastguard Worker , __FUNCTION__, offlineClient->getClientCallingPid());
2808*ec779b8eSAndroid Build Coastguard Worker return TIMED_OUT;
2809*ec779b8eSAndroid Build Coastguard Worker }
2810*ec779b8eSAndroid Build Coastguard Worker
2811*ec779b8eSAndroid Build Coastguard Worker auto onlineClientDesc = mActiveClientManager.get(cameraId);
2812*ec779b8eSAndroid Build Coastguard Worker if (onlineClientDesc.get() == nullptr) {
2813*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: No active online client using camera id: %s", __FUNCTION__,
2814*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2815*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
2816*ec779b8eSAndroid Build Coastguard Worker }
2817*ec779b8eSAndroid Build Coastguard Worker
2818*ec779b8eSAndroid Build Coastguard Worker // Offline clients do not evict or conflict with other online devices. Resource sharing
2819*ec779b8eSAndroid Build Coastguard Worker // conflicts are handled by the camera provider which will either succeed or fail before
2820*ec779b8eSAndroid Build Coastguard Worker // reaching this method.
2821*ec779b8eSAndroid Build Coastguard Worker const auto& onlinePriority = onlineClientDesc->getPriority();
2822*ec779b8eSAndroid Build Coastguard Worker auto offlineClientDesc = CameraClientManager::makeClientDescriptor(
2823*ec779b8eSAndroid Build Coastguard Worker kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
2824*ec779b8eSAndroid Build Coastguard Worker /*conflictingKeys*/ std::set<std::string>(), onlinePriority.getScore(),
2825*ec779b8eSAndroid Build Coastguard Worker onlineClientDesc->getOwnerId(), onlinePriority.getState(),
2826*ec779b8eSAndroid Build Coastguard Worker // native clients don't have offline processing support.
2827*ec779b8eSAndroid Build Coastguard Worker /*ommScoreOffset*/ 0, /*systemNativeClient*/false, /*sharedMode*/false);
2828*ec779b8eSAndroid Build Coastguard Worker if (offlineClientDesc == nullptr) {
2829*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Offline client descriptor was NULL", __FUNCTION__);
2830*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
2831*ec779b8eSAndroid Build Coastguard Worker }
2832*ec779b8eSAndroid Build Coastguard Worker
2833*ec779b8eSAndroid Build Coastguard Worker // Allow only one offline device per camera
2834*ec779b8eSAndroid Build Coastguard Worker auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc);
2835*ec779b8eSAndroid Build Coastguard Worker if (!incompatibleClients.empty()) {
2836*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Incompatible offline clients present!", __FUNCTION__);
2837*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
2838*ec779b8eSAndroid Build Coastguard Worker }
2839*ec779b8eSAndroid Build Coastguard Worker
2840*ec779b8eSAndroid Build Coastguard Worker std::string monitorTags = isClientWatched(offlineClient.get())
2841*ec779b8eSAndroid Build Coastguard Worker ? mMonitorTags : std::string();
2842*ec779b8eSAndroid Build Coastguard Worker auto err = offlineClient->initialize(mCameraProviderManager, monitorTags);
2843*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
2844*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Could not initialize offline client.", __FUNCTION__);
2845*ec779b8eSAndroid Build Coastguard Worker return err;
2846*ec779b8eSAndroid Build Coastguard Worker }
2847*ec779b8eSAndroid Build Coastguard Worker
2848*ec779b8eSAndroid Build Coastguard Worker auto evicted = mActiveClientManager.addAndEvict(offlineClientDesc);
2849*ec779b8eSAndroid Build Coastguard Worker if (evicted.size() > 0) {
2850*ec779b8eSAndroid Build Coastguard Worker for (auto& i : evicted) {
2851*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid state: Offline client for camera %s was not removed ",
2852*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, i->getKey().c_str());
2853*ec779b8eSAndroid Build Coastguard Worker }
2854*ec779b8eSAndroid Build Coastguard Worker
2855*ec779b8eSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, offline clients not evicted "
2856*ec779b8eSAndroid Build Coastguard Worker "properly", __FUNCTION__);
2857*ec779b8eSAndroid Build Coastguard Worker
2858*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
2859*ec779b8eSAndroid Build Coastguard Worker }
2860*ec779b8eSAndroid Build Coastguard Worker
2861*ec779b8eSAndroid Build Coastguard Worker logConnectedOffline(offlineClientDesc->getKey(),
2862*ec779b8eSAndroid Build Coastguard Worker static_cast<int>(offlineClientDesc->getOwnerId()),
2863*ec779b8eSAndroid Build Coastguard Worker offlineClient->getPackageName());
2864*ec779b8eSAndroid Build Coastguard Worker
2865*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> remoteCallback = offlineClient->getRemote();
2866*ec779b8eSAndroid Build Coastguard Worker if (remoteCallback != nullptr) {
2867*ec779b8eSAndroid Build Coastguard Worker remoteCallback->linkToDeath(this);
2868*ec779b8eSAndroid Build Coastguard Worker }
2869*ec779b8eSAndroid Build Coastguard Worker } // lock is destroyed, allow further connect calls
2870*ec779b8eSAndroid Build Coastguard Worker
2871*ec779b8eSAndroid Build Coastguard Worker return OK;
2872*ec779b8eSAndroid Build Coastguard Worker }
2873*ec779b8eSAndroid Build Coastguard Worker
turnOnTorchWithStrengthLevel(const std::string & unresolvedCameraId,int32_t torchStrength,const sp<IBinder> & clientBinder,const AttributionSourceState & clientAttribution,int32_t devicePolicy)2874*ec779b8eSAndroid Build Coastguard Worker Status CameraService::turnOnTorchWithStrengthLevel(const std::string& unresolvedCameraId,
2875*ec779b8eSAndroid Build Coastguard Worker int32_t torchStrength, const sp<IBinder>& clientBinder,
2876*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int32_t devicePolicy) {
2877*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
2878*ec779b8eSAndroid Build Coastguard Worker
2879*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
2880*ec779b8eSAndroid Build Coastguard Worker if (clientBinder == nullptr) {
2881*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch client binder is NULL", __FUNCTION__);
2882*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
2883*ec779b8eSAndroid Build Coastguard Worker "Torch client binder in null.");
2884*ec779b8eSAndroid Build Coastguard Worker }
2885*ec779b8eSAndroid Build Coastguard Worker
2886*ec779b8eSAndroid Build Coastguard Worker int uid = getCallingUid();
2887*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
2888*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId, devicePolicy);
2889*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
2890*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
2891*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
2892*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2893*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
2894*ec779b8eSAndroid Build Coastguard Worker }
2895*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
2896*ec779b8eSAndroid Build Coastguard Worker
2897*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
2898*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to change the strength level"
2899*ec779b8eSAndroid Build Coastguard Worker "for system only device %s: ", cameraId.c_str());
2900*ec779b8eSAndroid Build Coastguard Worker }
2901*ec779b8eSAndroid Build Coastguard Worker
2902*ec779b8eSAndroid Build Coastguard Worker // verify id is valid
2903*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
2904*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
2905*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str());
2906*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
2907*ec779b8eSAndroid Build Coastguard Worker "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
2908*ec779b8eSAndroid Build Coastguard Worker }
2909*ec779b8eSAndroid Build Coastguard Worker
2910*ec779b8eSAndroid Build Coastguard Worker StatusInternal cameraStatus = state->getStatus();
2911*ec779b8eSAndroid Build Coastguard Worker if (cameraStatus != StatusInternal::NOT_AVAILABLE &&
2912*ec779b8eSAndroid Build Coastguard Worker cameraStatus != StatusInternal::PRESENT) {
2913*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(),
2914*ec779b8eSAndroid Build Coastguard Worker (int)cameraStatus);
2915*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
2916*ec779b8eSAndroid Build Coastguard Worker "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
2917*ec779b8eSAndroid Build Coastguard Worker }
2918*ec779b8eSAndroid Build Coastguard Worker
2919*ec779b8eSAndroid Build Coastguard Worker {
2920*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
2921*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus status;
2922*ec779b8eSAndroid Build Coastguard Worker status_t err = getTorchStatusLocked(cameraId, &status);
2923*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
2924*ec779b8eSAndroid Build Coastguard Worker if (err == NAME_NOT_FOUND) {
2925*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
2926*ec779b8eSAndroid Build Coastguard Worker "Camera \"%s\" does not have a flash unit", cameraId.c_str());
2927*ec779b8eSAndroid Build Coastguard Worker }
2928*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: getting current torch status failed for camera %s",
2929*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
2930*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
2931*ec779b8eSAndroid Build Coastguard Worker "Error changing torch strength level for camera \"%s\": %s (%d)",
2932*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), strerror(-err), err);
2933*ec779b8eSAndroid Build Coastguard Worker }
2934*ec779b8eSAndroid Build Coastguard Worker
2935*ec779b8eSAndroid Build Coastguard Worker if (status == TorchModeStatus::NOT_AVAILABLE) {
2936*ec779b8eSAndroid Build Coastguard Worker if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
2937*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch mode of camera %s is not available because "
2938*ec779b8eSAndroid Build Coastguard Worker "camera is in use.", __FUNCTION__, cameraId.c_str());
2939*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
2940*ec779b8eSAndroid Build Coastguard Worker "Torch for camera \"%s\" is not available due to an existing camera user",
2941*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2942*ec779b8eSAndroid Build Coastguard Worker } else {
2943*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch mode of camera %s is not available due to "
2944*ec779b8eSAndroid Build Coastguard Worker "insufficient resources", __FUNCTION__, cameraId.c_str());
2945*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
2946*ec779b8eSAndroid Build Coastguard Worker "Torch for camera \"%s\" is not available due to insufficient resources",
2947*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2948*ec779b8eSAndroid Build Coastguard Worker }
2949*ec779b8eSAndroid Build Coastguard Worker }
2950*ec779b8eSAndroid Build Coastguard Worker }
2951*ec779b8eSAndroid Build Coastguard Worker
2952*ec779b8eSAndroid Build Coastguard Worker {
2953*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchUidMapMutex);
2954*ec779b8eSAndroid Build Coastguard Worker updateTorchUidMapLocked(cameraId, uid);
2955*ec779b8eSAndroid Build Coastguard Worker }
2956*ec779b8eSAndroid Build Coastguard Worker // Check if the current torch strength level is same as the new one.
2957*ec779b8eSAndroid Build Coastguard Worker bool shouldSkipTorchStrengthUpdates = mCameraProviderManager->shouldSkipTorchStrengthUpdate(
2958*ec779b8eSAndroid Build Coastguard Worker cameraId, torchStrength);
2959*ec779b8eSAndroid Build Coastguard Worker
2960*ec779b8eSAndroid Build Coastguard Worker status_t err = mFlashlight->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
2961*ec779b8eSAndroid Build Coastguard Worker
2962*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
2963*ec779b8eSAndroid Build Coastguard Worker int32_t errorCode;
2964*ec779b8eSAndroid Build Coastguard Worker std::string msg;
2965*ec779b8eSAndroid Build Coastguard Worker switch (err) {
2966*ec779b8eSAndroid Build Coastguard Worker case -ENOSYS:
2967*ec779b8eSAndroid Build Coastguard Worker msg = fmt::sprintf("Camera \"%s\" has no flashlight.",
2968*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2969*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_ILLEGAL_ARGUMENT;
2970*ec779b8eSAndroid Build Coastguard Worker break;
2971*ec779b8eSAndroid Build Coastguard Worker case -EBUSY:
2972*ec779b8eSAndroid Build Coastguard Worker msg = fmt::sprintf("Camera \"%s\" is in use",
2973*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
2974*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_CAMERA_IN_USE;
2975*ec779b8eSAndroid Build Coastguard Worker break;
2976*ec779b8eSAndroid Build Coastguard Worker case -EINVAL:
2977*ec779b8eSAndroid Build Coastguard Worker msg = fmt::sprintf("Torch strength level %d is not within the "
2978*ec779b8eSAndroid Build Coastguard Worker "valid range.", torchStrength);
2979*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_ILLEGAL_ARGUMENT;
2980*ec779b8eSAndroid Build Coastguard Worker break;
2981*ec779b8eSAndroid Build Coastguard Worker default:
2982*ec779b8eSAndroid Build Coastguard Worker msg = "Changing torch strength level failed.";
2983*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_INVALID_OPERATION;
2984*ec779b8eSAndroid Build Coastguard Worker }
2985*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
2986*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(errorCode, msg.c_str());
2987*ec779b8eSAndroid Build Coastguard Worker }
2988*ec779b8eSAndroid Build Coastguard Worker
2989*ec779b8eSAndroid Build Coastguard Worker {
2990*ec779b8eSAndroid Build Coastguard Worker // update the link to client's death
2991*ec779b8eSAndroid Build Coastguard Worker // Store the last client that turns on each camera's torch mode.
2992*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchClientMapMutex);
2993*ec779b8eSAndroid Build Coastguard Worker ssize_t index = mTorchClientMap.indexOfKey(cameraId);
2994*ec779b8eSAndroid Build Coastguard Worker if (index == NAME_NOT_FOUND) {
2995*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.add(cameraId, clientBinder);
2996*ec779b8eSAndroid Build Coastguard Worker } else {
2997*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.valueAt(index)->unlinkToDeath(this);
2998*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.replaceValueAt(index, clientBinder);
2999*ec779b8eSAndroid Build Coastguard Worker }
3000*ec779b8eSAndroid Build Coastguard Worker clientBinder->linkToDeath(this);
3001*ec779b8eSAndroid Build Coastguard Worker }
3002*ec779b8eSAndroid Build Coastguard Worker
3003*ec779b8eSAndroid Build Coastguard Worker int clientPid = getCallingPid();
3004*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Torch strength for camera id %s changed to %d for client PID %d",
3005*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str(), torchStrength, clientPid);
3006*ec779b8eSAndroid Build Coastguard Worker if (!shouldSkipTorchStrengthUpdates) {
3007*ec779b8eSAndroid Build Coastguard Worker broadcastTorchStrengthLevel(cameraId, torchStrength);
3008*ec779b8eSAndroid Build Coastguard Worker }
3009*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3010*ec779b8eSAndroid Build Coastguard Worker }
3011*ec779b8eSAndroid Build Coastguard Worker
setTorchMode(const std::string & unresolvedCameraId,bool enabled,const sp<IBinder> & clientBinder,const AttributionSourceState & clientAttribution,int32_t devicePolicy)3012*ec779b8eSAndroid Build Coastguard Worker Status CameraService::setTorchMode(const std::string& unresolvedCameraId, bool enabled,
3013*ec779b8eSAndroid Build Coastguard Worker const sp<IBinder>& clientBinder, const AttributionSourceState& clientAttribution,
3014*ec779b8eSAndroid Build Coastguard Worker int32_t devicePolicy) {
3015*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3016*ec779b8eSAndroid Build Coastguard Worker
3017*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3018*ec779b8eSAndroid Build Coastguard Worker if (enabled && clientBinder == nullptr) {
3019*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch client binder is NULL", __FUNCTION__);
3020*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
3021*ec779b8eSAndroid Build Coastguard Worker "Torch client Binder is null");
3022*ec779b8eSAndroid Build Coastguard Worker }
3023*ec779b8eSAndroid Build Coastguard Worker
3024*ec779b8eSAndroid Build Coastguard Worker int uid = getCallingUid();
3025*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
3026*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId, devicePolicy);
3027*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
3028*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
3029*ec779b8eSAndroid Build Coastguard Worker unresolvedCameraId.c_str(), clientAttribution.deviceId);
3030*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3031*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
3032*ec779b8eSAndroid Build Coastguard Worker }
3033*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = cameraIdOptional.value();
3034*ec779b8eSAndroid Build Coastguard Worker
3035*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
3036*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to set torch mode"
3037*ec779b8eSAndroid Build Coastguard Worker " for system only device %s: ", cameraId.c_str());
3038*ec779b8eSAndroid Build Coastguard Worker }
3039*ec779b8eSAndroid Build Coastguard Worker // verify id is valid.
3040*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
3041*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
3042*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str());
3043*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
3044*ec779b8eSAndroid Build Coastguard Worker "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
3045*ec779b8eSAndroid Build Coastguard Worker }
3046*ec779b8eSAndroid Build Coastguard Worker
3047*ec779b8eSAndroid Build Coastguard Worker StatusInternal cameraStatus = state->getStatus();
3048*ec779b8eSAndroid Build Coastguard Worker if (cameraStatus != StatusInternal::PRESENT &&
3049*ec779b8eSAndroid Build Coastguard Worker cameraStatus != StatusInternal::NOT_AVAILABLE) {
3050*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(),
3051*ec779b8eSAndroid Build Coastguard Worker (int)cameraStatus);
3052*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
3053*ec779b8eSAndroid Build Coastguard Worker "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str());
3054*ec779b8eSAndroid Build Coastguard Worker }
3055*ec779b8eSAndroid Build Coastguard Worker
3056*ec779b8eSAndroid Build Coastguard Worker {
3057*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
3058*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus status;
3059*ec779b8eSAndroid Build Coastguard Worker status_t err = getTorchStatusLocked(cameraId, &status);
3060*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
3061*ec779b8eSAndroid Build Coastguard Worker if (err == NAME_NOT_FOUND) {
3062*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
3063*ec779b8eSAndroid Build Coastguard Worker "Camera \"%s\" does not have a flash unit", cameraId.c_str());
3064*ec779b8eSAndroid Build Coastguard Worker }
3065*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: getting current torch status failed for camera %s",
3066*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
3067*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
3068*ec779b8eSAndroid Build Coastguard Worker "Error updating torch status for camera \"%s\": %s (%d)", cameraId.c_str(),
3069*ec779b8eSAndroid Build Coastguard Worker strerror(-err), err);
3070*ec779b8eSAndroid Build Coastguard Worker }
3071*ec779b8eSAndroid Build Coastguard Worker
3072*ec779b8eSAndroid Build Coastguard Worker if (status == TorchModeStatus::NOT_AVAILABLE) {
3073*ec779b8eSAndroid Build Coastguard Worker if (cameraStatus == StatusInternal::NOT_AVAILABLE) {
3074*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch mode of camera %s is not available because "
3075*ec779b8eSAndroid Build Coastguard Worker "camera is in use", __FUNCTION__, cameraId.c_str());
3076*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
3077*ec779b8eSAndroid Build Coastguard Worker "Torch for camera \"%s\" is not available due to an existing camera user",
3078*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
3079*ec779b8eSAndroid Build Coastguard Worker } else {
3080*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch mode of camera %s is not available due to "
3081*ec779b8eSAndroid Build Coastguard Worker "insufficient resources", __FUNCTION__, cameraId.c_str());
3082*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
3083*ec779b8eSAndroid Build Coastguard Worker "Torch for camera \"%s\" is not available due to insufficient resources",
3084*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
3085*ec779b8eSAndroid Build Coastguard Worker }
3086*ec779b8eSAndroid Build Coastguard Worker }
3087*ec779b8eSAndroid Build Coastguard Worker }
3088*ec779b8eSAndroid Build Coastguard Worker
3089*ec779b8eSAndroid Build Coastguard Worker {
3090*ec779b8eSAndroid Build Coastguard Worker // Update UID map - this is used in the torch status changed callbacks, so must be done
3091*ec779b8eSAndroid Build Coastguard Worker // before setTorchMode
3092*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchUidMapMutex);
3093*ec779b8eSAndroid Build Coastguard Worker updateTorchUidMapLocked(cameraId, uid);
3094*ec779b8eSAndroid Build Coastguard Worker }
3095*ec779b8eSAndroid Build Coastguard Worker
3096*ec779b8eSAndroid Build Coastguard Worker status_t err = mFlashlight->setTorchMode(cameraId, enabled);
3097*ec779b8eSAndroid Build Coastguard Worker
3098*ec779b8eSAndroid Build Coastguard Worker if (err != OK) {
3099*ec779b8eSAndroid Build Coastguard Worker int32_t errorCode;
3100*ec779b8eSAndroid Build Coastguard Worker std::string msg;
3101*ec779b8eSAndroid Build Coastguard Worker switch (err) {
3102*ec779b8eSAndroid Build Coastguard Worker case -ENOSYS:
3103*ec779b8eSAndroid Build Coastguard Worker msg = fmt::sprintf("Camera \"%s\" has no flashlight",
3104*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
3105*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_ILLEGAL_ARGUMENT;
3106*ec779b8eSAndroid Build Coastguard Worker break;
3107*ec779b8eSAndroid Build Coastguard Worker case -EBUSY:
3108*ec779b8eSAndroid Build Coastguard Worker msg = fmt::sprintf("Camera \"%s\" is in use",
3109*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
3110*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_CAMERA_IN_USE;
3111*ec779b8eSAndroid Build Coastguard Worker break;
3112*ec779b8eSAndroid Build Coastguard Worker default:
3113*ec779b8eSAndroid Build Coastguard Worker msg = fmt::sprintf(
3114*ec779b8eSAndroid Build Coastguard Worker "Setting torch mode of camera \"%s\" to %d failed: %s (%d)",
3115*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), enabled, strerror(-err), err);
3116*ec779b8eSAndroid Build Coastguard Worker errorCode = ERROR_INVALID_OPERATION;
3117*ec779b8eSAndroid Build Coastguard Worker }
3118*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3119*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, errorCode);
3120*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(errorCode, msg.c_str());
3121*ec779b8eSAndroid Build Coastguard Worker }
3122*ec779b8eSAndroid Build Coastguard Worker
3123*ec779b8eSAndroid Build Coastguard Worker {
3124*ec779b8eSAndroid Build Coastguard Worker // update the link to client's death
3125*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchClientMapMutex);
3126*ec779b8eSAndroid Build Coastguard Worker ssize_t index = mTorchClientMap.indexOfKey(cameraId);
3127*ec779b8eSAndroid Build Coastguard Worker if (enabled) {
3128*ec779b8eSAndroid Build Coastguard Worker if (index == NAME_NOT_FOUND) {
3129*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.add(cameraId, clientBinder);
3130*ec779b8eSAndroid Build Coastguard Worker } else {
3131*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.valueAt(index)->unlinkToDeath(this);
3132*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.replaceValueAt(index, clientBinder);
3133*ec779b8eSAndroid Build Coastguard Worker }
3134*ec779b8eSAndroid Build Coastguard Worker clientBinder->linkToDeath(this);
3135*ec779b8eSAndroid Build Coastguard Worker } else if (index != NAME_NOT_FOUND) {
3136*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.valueAt(index)->unlinkToDeath(this);
3137*ec779b8eSAndroid Build Coastguard Worker }
3138*ec779b8eSAndroid Build Coastguard Worker }
3139*ec779b8eSAndroid Build Coastguard Worker
3140*ec779b8eSAndroid Build Coastguard Worker int clientPid = getCallingPid();
3141*ec779b8eSAndroid Build Coastguard Worker std::string torchState = enabled ? "on" : "off";
3142*ec779b8eSAndroid Build Coastguard Worker ALOGI("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(),
3143*ec779b8eSAndroid Build Coastguard Worker torchState.c_str(), clientPid);
3144*ec779b8eSAndroid Build Coastguard Worker logTorchEvent(cameraId, torchState, clientPid);
3145*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3146*ec779b8eSAndroid Build Coastguard Worker }
3147*ec779b8eSAndroid Build Coastguard Worker
updateTorchUidMapLocked(const std::string & cameraId,int uid)3148*ec779b8eSAndroid Build Coastguard Worker void CameraService::updateTorchUidMapLocked(const std::string& cameraId, int uid) {
3149*ec779b8eSAndroid Build Coastguard Worker if (mTorchUidMap.find(cameraId) == mTorchUidMap.end()) {
3150*ec779b8eSAndroid Build Coastguard Worker mTorchUidMap[cameraId].first = uid;
3151*ec779b8eSAndroid Build Coastguard Worker mTorchUidMap[cameraId].second = uid;
3152*ec779b8eSAndroid Build Coastguard Worker } else {
3153*ec779b8eSAndroid Build Coastguard Worker // Set the pending UID
3154*ec779b8eSAndroid Build Coastguard Worker mTorchUidMap[cameraId].first = uid;
3155*ec779b8eSAndroid Build Coastguard Worker }
3156*ec779b8eSAndroid Build Coastguard Worker }
3157*ec779b8eSAndroid Build Coastguard Worker
notifySystemEvent(int32_t eventId,const std::vector<int32_t> & args)3158*ec779b8eSAndroid Build Coastguard Worker Status CameraService::notifySystemEvent(int32_t eventId,
3159*ec779b8eSAndroid Build Coastguard Worker const std::vector<int32_t>& args) {
3160*ec779b8eSAndroid Build Coastguard Worker const int pid = getCallingPid();
3161*ec779b8eSAndroid Build Coastguard Worker const int selfPid = getpid();
3162*ec779b8eSAndroid Build Coastguard Worker
3163*ec779b8eSAndroid Build Coastguard Worker // Permission checks
3164*ec779b8eSAndroid Build Coastguard Worker if (pid != selfPid) {
3165*ec779b8eSAndroid Build Coastguard Worker // Ensure we're being called by system_server, or similar process with
3166*ec779b8eSAndroid Build Coastguard Worker // permissions to notify the camera service about system events
3167*ec779b8eSAndroid Build Coastguard Worker if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
3168*ec779b8eSAndroid Build Coastguard Worker const int uid = getCallingUid();
3169*ec779b8eSAndroid Build Coastguard Worker ALOGE("Permission Denial: cannot send updates to camera service about system"
3170*ec779b8eSAndroid Build Coastguard Worker " events from pid=%d, uid=%d", pid, uid);
3171*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
3172*ec779b8eSAndroid Build Coastguard Worker "No permission to send updates to camera service about system events"
3173*ec779b8eSAndroid Build Coastguard Worker " from pid=%d, uid=%d", pid, uid);
3174*ec779b8eSAndroid Build Coastguard Worker }
3175*ec779b8eSAndroid Build Coastguard Worker }
3176*ec779b8eSAndroid Build Coastguard Worker
3177*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3178*ec779b8eSAndroid Build Coastguard Worker
3179*ec779b8eSAndroid Build Coastguard Worker switch(eventId) {
3180*ec779b8eSAndroid Build Coastguard Worker case ICameraService::EVENT_USER_SWITCHED: {
3181*ec779b8eSAndroid Build Coastguard Worker // Try to register for UID and sensor privacy policy updates, in case we're recovering
3182*ec779b8eSAndroid Build Coastguard Worker // from a system server crash
3183*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->registerSelf();
3184*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy->registerSelf();
3185*ec779b8eSAndroid Build Coastguard Worker doUserSwitch(/*newUserIds*/ args);
3186*ec779b8eSAndroid Build Coastguard Worker break;
3187*ec779b8eSAndroid Build Coastguard Worker }
3188*ec779b8eSAndroid Build Coastguard Worker case ICameraService::EVENT_USB_DEVICE_ATTACHED:
3189*ec779b8eSAndroid Build Coastguard Worker case ICameraService::EVENT_USB_DEVICE_DETACHED: {
3190*ec779b8eSAndroid Build Coastguard Worker if (args.size() != 1) {
3191*ec779b8eSAndroid Build Coastguard Worker return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT,
3192*ec779b8eSAndroid Build Coastguard Worker "USB Device Event requires 1 argument");
3193*ec779b8eSAndroid Build Coastguard Worker }
3194*ec779b8eSAndroid Build Coastguard Worker
3195*ec779b8eSAndroid Build Coastguard Worker // Notify CameraProviderManager for lazy HALs
3196*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->notifyUsbDeviceEvent(eventId,
3197*ec779b8eSAndroid Build Coastguard Worker std::to_string(args[0]));
3198*ec779b8eSAndroid Build Coastguard Worker break;
3199*ec779b8eSAndroid Build Coastguard Worker }
3200*ec779b8eSAndroid Build Coastguard Worker case ICameraService::EVENT_NONE:
3201*ec779b8eSAndroid Build Coastguard Worker default: {
3202*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__,
3203*ec779b8eSAndroid Build Coastguard Worker eventId);
3204*ec779b8eSAndroid Build Coastguard Worker break;
3205*ec779b8eSAndroid Build Coastguard Worker }
3206*ec779b8eSAndroid Build Coastguard Worker }
3207*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3208*ec779b8eSAndroid Build Coastguard Worker }
3209*ec779b8eSAndroid Build Coastguard Worker
notifyMonitoredUids()3210*ec779b8eSAndroid Build Coastguard Worker void CameraService::notifyMonitoredUids() {
3211*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
3212*ec779b8eSAndroid Build Coastguard Worker
3213*ec779b8eSAndroid Build Coastguard Worker for (const auto& it : mListenerList) {
3214*ec779b8eSAndroid Build Coastguard Worker auto ret = it->getListener()->onCameraAccessPrioritiesChanged();
3215*ec779b8eSAndroid Build Coastguard Worker it->handleBinderStatus(ret, "%s: Failed to trigger permission callback for %d:%d: %d",
3216*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode());
3217*ec779b8eSAndroid Build Coastguard Worker }
3218*ec779b8eSAndroid Build Coastguard Worker }
3219*ec779b8eSAndroid Build Coastguard Worker
notifyMonitoredUids(const std::unordered_set<uid_t> & notifyUidSet)3220*ec779b8eSAndroid Build Coastguard Worker void CameraService::notifyMonitoredUids(const std::unordered_set<uid_t> ¬ifyUidSet) {
3221*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
3222*ec779b8eSAndroid Build Coastguard Worker
3223*ec779b8eSAndroid Build Coastguard Worker for (const auto& it : mListenerList) {
3224*ec779b8eSAndroid Build Coastguard Worker if (notifyUidSet.find(it->getListenerUid()) != notifyUidSet.end()) {
3225*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: notifying uid %d", __FUNCTION__, it->getListenerUid());
3226*ec779b8eSAndroid Build Coastguard Worker auto ret = it->getListener()->onCameraAccessPrioritiesChanged();
3227*ec779b8eSAndroid Build Coastguard Worker it->handleBinderStatus(ret, "%s: Failed to trigger permission callback for %d:%d: %d",
3228*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode());
3229*ec779b8eSAndroid Build Coastguard Worker }
3230*ec779b8eSAndroid Build Coastguard Worker }
3231*ec779b8eSAndroid Build Coastguard Worker }
3232*ec779b8eSAndroid Build Coastguard Worker
notifyDeviceStateChange(int64_t newState)3233*ec779b8eSAndroid Build Coastguard Worker Status CameraService::notifyDeviceStateChange(int64_t newState) {
3234*ec779b8eSAndroid Build Coastguard Worker const int pid = getCallingPid();
3235*ec779b8eSAndroid Build Coastguard Worker const int selfPid = getpid();
3236*ec779b8eSAndroid Build Coastguard Worker
3237*ec779b8eSAndroid Build Coastguard Worker // Permission checks
3238*ec779b8eSAndroid Build Coastguard Worker if (pid != selfPid) {
3239*ec779b8eSAndroid Build Coastguard Worker // Ensure we're being called by system_server, or similar process with
3240*ec779b8eSAndroid Build Coastguard Worker // permissions to notify the camera service about system events
3241*ec779b8eSAndroid Build Coastguard Worker if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
3242*ec779b8eSAndroid Build Coastguard Worker const int uid = getCallingUid();
3243*ec779b8eSAndroid Build Coastguard Worker ALOGE("Permission Denial: cannot send updates to camera service about device"
3244*ec779b8eSAndroid Build Coastguard Worker " state changes from pid=%d, uid=%d", pid, uid);
3245*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
3246*ec779b8eSAndroid Build Coastguard Worker "No permission to send updates to camera service about device state"
3247*ec779b8eSAndroid Build Coastguard Worker " changes from pid=%d, uid=%d", pid, uid);
3248*ec779b8eSAndroid Build Coastguard Worker }
3249*ec779b8eSAndroid Build Coastguard Worker }
3250*ec779b8eSAndroid Build Coastguard Worker
3251*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3252*ec779b8eSAndroid Build Coastguard Worker
3253*ec779b8eSAndroid Build Coastguard Worker {
3254*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3255*ec779b8eSAndroid Build Coastguard Worker mDeviceState = newState;
3256*ec779b8eSAndroid Build Coastguard Worker }
3257*ec779b8eSAndroid Build Coastguard Worker
3258*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->notifyDeviceStateChange(newState);
3259*ec779b8eSAndroid Build Coastguard Worker
3260*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3261*ec779b8eSAndroid Build Coastguard Worker }
3262*ec779b8eSAndroid Build Coastguard Worker
notifyDisplayConfigurationChange()3263*ec779b8eSAndroid Build Coastguard Worker Status CameraService::notifyDisplayConfigurationChange() {
3264*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3265*ec779b8eSAndroid Build Coastguard Worker const int callingPid = getCallingPid();
3266*ec779b8eSAndroid Build Coastguard Worker const int selfPid = getpid();
3267*ec779b8eSAndroid Build Coastguard Worker
3268*ec779b8eSAndroid Build Coastguard Worker // Permission checks
3269*ec779b8eSAndroid Build Coastguard Worker if (callingPid != selfPid) {
3270*ec779b8eSAndroid Build Coastguard Worker // Ensure we're being called by system_server, or similar process with
3271*ec779b8eSAndroid Build Coastguard Worker // permissions to notify the camera service about system events
3272*ec779b8eSAndroid Build Coastguard Worker if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) {
3273*ec779b8eSAndroid Build Coastguard Worker const int uid = getCallingUid();
3274*ec779b8eSAndroid Build Coastguard Worker ALOGE("Permission Denial: cannot send updates to camera service about orientation"
3275*ec779b8eSAndroid Build Coastguard Worker " changes from pid=%d, uid=%d", callingPid, uid);
3276*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
3277*ec779b8eSAndroid Build Coastguard Worker "No permission to send updates to camera service about orientation"
3278*ec779b8eSAndroid Build Coastguard Worker " changes from pid=%d, uid=%d", callingPid, uid);
3279*ec779b8eSAndroid Build Coastguard Worker }
3280*ec779b8eSAndroid Build Coastguard Worker }
3281*ec779b8eSAndroid Build Coastguard Worker
3282*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3283*ec779b8eSAndroid Build Coastguard Worker
3284*ec779b8eSAndroid Build Coastguard Worker // Don't do anything if rotate-and-crop override via cmd is active
3285*ec779b8eSAndroid Build Coastguard Worker if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return Status::ok();
3286*ec779b8eSAndroid Build Coastguard Worker
3287*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
3288*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
3289*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
3290*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
3291*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr && !basicClient->getOverrideToPortrait()) {
3292*ec779b8eSAndroid Build Coastguard Worker basicClient->setRotateAndCropOverride(
3293*ec779b8eSAndroid Build Coastguard Worker mCameraServiceProxyWrapper->getRotateAndCropOverride(
3294*ec779b8eSAndroid Build Coastguard Worker basicClient->getPackageName(),
3295*ec779b8eSAndroid Build Coastguard Worker basicClient->getCameraFacing(),
3296*ec779b8eSAndroid Build Coastguard Worker multiuser_get_user_id(basicClient->getClientUid())));
3297*ec779b8eSAndroid Build Coastguard Worker }
3298*ec779b8eSAndroid Build Coastguard Worker }
3299*ec779b8eSAndroid Build Coastguard Worker }
3300*ec779b8eSAndroid Build Coastguard Worker
3301*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3302*ec779b8eSAndroid Build Coastguard Worker }
3303*ec779b8eSAndroid Build Coastguard Worker
getConcurrentCameraIds(std::vector<ConcurrentCameraIdCombination> * concurrentCameraIds)3304*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getConcurrentCameraIds(
3305*ec779b8eSAndroid Build Coastguard Worker std::vector<ConcurrentCameraIdCombination>* concurrentCameraIds) {
3306*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3307*ec779b8eSAndroid Build Coastguard Worker if (!concurrentCameraIds) {
3308*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: concurrentCameraIds is NULL", __FUNCTION__);
3309*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "concurrentCameraIds is NULL");
3310*ec779b8eSAndroid Build Coastguard Worker }
3311*ec779b8eSAndroid Build Coastguard Worker
3312*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
3313*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
3314*ec779b8eSAndroid Build Coastguard Worker logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
3315*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED,
3316*ec779b8eSAndroid Build Coastguard Worker "Camera subsystem is not available");
3317*ec779b8eSAndroid Build Coastguard Worker }
3318*ec779b8eSAndroid Build Coastguard Worker // First call into the provider and get the set of concurrent camera
3319*ec779b8eSAndroid Build Coastguard Worker // combinations
3320*ec779b8eSAndroid Build Coastguard Worker std::vector<std::unordered_set<std::string>> concurrentCameraCombinations =
3321*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->getConcurrentCameraIds();
3322*ec779b8eSAndroid Build Coastguard Worker for (auto &combination : concurrentCameraCombinations) {
3323*ec779b8eSAndroid Build Coastguard Worker std::vector<std::pair<std::string, int32_t>> validCombination;
3324*ec779b8eSAndroid Build Coastguard Worker int32_t firstDeviceId = kInvalidDeviceId;
3325*ec779b8eSAndroid Build Coastguard Worker for (auto &cameraId : combination) {
3326*ec779b8eSAndroid Build Coastguard Worker // if the camera state is not present, skip
3327*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
3328*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
3329*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: camera id %s does not exist", __FUNCTION__, cameraId.c_str());
3330*ec779b8eSAndroid Build Coastguard Worker continue;
3331*ec779b8eSAndroid Build Coastguard Worker }
3332*ec779b8eSAndroid Build Coastguard Worker StatusInternal status = state->getStatus();
3333*ec779b8eSAndroid Build Coastguard Worker if (status == StatusInternal::NOT_PRESENT || status == StatusInternal::ENUMERATING) {
3334*ec779b8eSAndroid Build Coastguard Worker continue;
3335*ec779b8eSAndroid Build Coastguard Worker }
3336*ec779b8eSAndroid Build Coastguard Worker if (shouldRejectSystemCameraConnection(cameraId)) {
3337*ec779b8eSAndroid Build Coastguard Worker continue;
3338*ec779b8eSAndroid Build Coastguard Worker }
3339*ec779b8eSAndroid Build Coastguard Worker auto [cameraOwnerDeviceId, mappedCameraId] =
3340*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
3341*ec779b8eSAndroid Build Coastguard Worker if (firstDeviceId == kInvalidDeviceId) {
3342*ec779b8eSAndroid Build Coastguard Worker firstDeviceId = cameraOwnerDeviceId;
3343*ec779b8eSAndroid Build Coastguard Worker } else if (firstDeviceId != cameraOwnerDeviceId) {
3344*ec779b8eSAndroid Build Coastguard Worker // Found an invalid combination which contains cameras with different device id's,
3345*ec779b8eSAndroid Build Coastguard Worker // hence discard it.
3346*ec779b8eSAndroid Build Coastguard Worker validCombination.clear();
3347*ec779b8eSAndroid Build Coastguard Worker break;
3348*ec779b8eSAndroid Build Coastguard Worker }
3349*ec779b8eSAndroid Build Coastguard Worker validCombination.push_back({mappedCameraId, cameraOwnerDeviceId});
3350*ec779b8eSAndroid Build Coastguard Worker }
3351*ec779b8eSAndroid Build Coastguard Worker if (validCombination.size() != 0) {
3352*ec779b8eSAndroid Build Coastguard Worker concurrentCameraIds->push_back(std::move(validCombination));
3353*ec779b8eSAndroid Build Coastguard Worker }
3354*ec779b8eSAndroid Build Coastguard Worker }
3355*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3356*ec779b8eSAndroid Build Coastguard Worker }
3357*ec779b8eSAndroid Build Coastguard Worker
isConcurrentSessionConfigurationSupported(const std::vector<CameraIdAndSessionConfiguration> & cameraIdsAndSessionConfigurations,int targetSdkVersion,const AttributionSourceState & clientAttribution,int32_t devicePolicy,bool * isSupported)3358*ec779b8eSAndroid Build Coastguard Worker Status CameraService::isConcurrentSessionConfigurationSupported(
3359*ec779b8eSAndroid Build Coastguard Worker const std::vector<CameraIdAndSessionConfiguration>& cameraIdsAndSessionConfigurations,
3360*ec779b8eSAndroid Build Coastguard Worker int targetSdkVersion, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
3361*ec779b8eSAndroid Build Coastguard Worker /*out*/bool* isSupported) {
3362*ec779b8eSAndroid Build Coastguard Worker if (!isSupported) {
3363*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: isSupported is NULL", __FUNCTION__);
3364*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "isSupported is NULL");
3365*ec779b8eSAndroid Build Coastguard Worker }
3366*ec779b8eSAndroid Build Coastguard Worker
3367*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
3368*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
3369*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_DISCONNECTED,
3370*ec779b8eSAndroid Build Coastguard Worker "Camera subsystem is not available");
3371*ec779b8eSAndroid Build Coastguard Worker }
3372*ec779b8eSAndroid Build Coastguard Worker
3373*ec779b8eSAndroid Build Coastguard Worker for (auto cameraIdAndSessionConfiguration : cameraIdsAndSessionConfigurations) {
3374*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional =
3375*ec779b8eSAndroid Build Coastguard Worker resolveCameraId(cameraIdAndSessionConfiguration.mCameraId,
3376*ec779b8eSAndroid Build Coastguard Worker clientAttribution.deviceId, devicePolicy);
3377*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
3378*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
3379*ec779b8eSAndroid Build Coastguard Worker cameraIdAndSessionConfiguration.mCameraId.c_str(), clientAttribution.deviceId);
3380*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3381*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
3382*ec779b8eSAndroid Build Coastguard Worker }
3383*ec779b8eSAndroid Build Coastguard Worker cameraIdAndSessionConfiguration.mCameraId = cameraIdOptional.value();
3384*ec779b8eSAndroid Build Coastguard Worker }
3385*ec779b8eSAndroid Build Coastguard Worker
3386*ec779b8eSAndroid Build Coastguard Worker // Check for camera permissions
3387*ec779b8eSAndroid Build Coastguard Worker int callingPid = getCallingPid();
3388*ec779b8eSAndroid Build Coastguard Worker int callingUid = getCallingUid();
3389*ec779b8eSAndroid Build Coastguard Worker bool hasCameraPermission = ((callingPid == getpid()) ||
3390*ec779b8eSAndroid Build Coastguard Worker hasPermissionsForCamera(callingPid, callingUid,
3391*ec779b8eSAndroid Build Coastguard Worker devicePolicy == IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT
3392*ec779b8eSAndroid Build Coastguard Worker ? kDefaultDeviceId : clientAttribution.deviceId));
3393*ec779b8eSAndroid Build Coastguard Worker if (!hasCameraPermission) {
3394*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_PERMISSION_DENIED,
3395*ec779b8eSAndroid Build Coastguard Worker "android.permission.CAMERA needed to call"
3396*ec779b8eSAndroid Build Coastguard Worker "isConcurrentSessionConfigurationSupported");
3397*ec779b8eSAndroid Build Coastguard Worker }
3398*ec779b8eSAndroid Build Coastguard Worker
3399*ec779b8eSAndroid Build Coastguard Worker status_t res =
3400*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->isConcurrentSessionConfigurationSupported(
3401*ec779b8eSAndroid Build Coastguard Worker cameraIdsAndSessionConfigurations, mPerfClassPrimaryCameraIds,
3402*ec779b8eSAndroid Build Coastguard Worker targetSdkVersion, isSupported);
3403*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
3404*ec779b8eSAndroid Build Coastguard Worker logServiceError("Unable to query session configuration support",
3405*ec779b8eSAndroid Build Coastguard Worker ERROR_INVALID_OPERATION);
3406*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query session configuration "
3407*ec779b8eSAndroid Build Coastguard Worker "support %s (%d)", strerror(-res), res);
3408*ec779b8eSAndroid Build Coastguard Worker }
3409*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3410*ec779b8eSAndroid Build Coastguard Worker }
3411*ec779b8eSAndroid Build Coastguard Worker
addListener(const sp<ICameraServiceListener> & listener,std::vector<hardware::CameraStatus> * cameraStatuses)3412*ec779b8eSAndroid Build Coastguard Worker Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
3413*ec779b8eSAndroid Build Coastguard Worker /*out*/
3414*ec779b8eSAndroid Build Coastguard Worker std::vector<hardware::CameraStatus> *cameraStatuses) {
3415*ec779b8eSAndroid Build Coastguard Worker return addListenerHelper(listener, cameraStatuses);
3416*ec779b8eSAndroid Build Coastguard Worker }
3417*ec779b8eSAndroid Build Coastguard Worker
addListenerTest(const sp<hardware::ICameraServiceListener> & listener,std::vector<hardware::CameraStatus> * cameraStatuses)3418*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraService::addListenerTest(const sp<hardware::ICameraServiceListener>& listener,
3419*ec779b8eSAndroid Build Coastguard Worker std::vector<hardware::CameraStatus>* cameraStatuses) {
3420*ec779b8eSAndroid Build Coastguard Worker return addListenerHelper(listener, cameraStatuses, false, true);
3421*ec779b8eSAndroid Build Coastguard Worker }
3422*ec779b8eSAndroid Build Coastguard Worker
addListenerHelper(const sp<ICameraServiceListener> & listener,std::vector<hardware::CameraStatus> * cameraStatuses,bool isVendorListener,bool isProcessLocalTest)3423*ec779b8eSAndroid Build Coastguard Worker Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listener,
3424*ec779b8eSAndroid Build Coastguard Worker /*out*/
3425*ec779b8eSAndroid Build Coastguard Worker std::vector<hardware::CameraStatus> *cameraStatuses,
3426*ec779b8eSAndroid Build Coastguard Worker bool isVendorListener, bool isProcessLocalTest) {
3427*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3428*ec779b8eSAndroid Build Coastguard Worker
3429*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
3430*ec779b8eSAndroid Build Coastguard Worker
3431*ec779b8eSAndroid Build Coastguard Worker if (listener == nullptr) {
3432*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Listener must not be null", __FUNCTION__);
3433*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
3434*ec779b8eSAndroid Build Coastguard Worker }
3435*ec779b8eSAndroid Build Coastguard Worker
3436*ec779b8eSAndroid Build Coastguard Worker auto clientPid = getCallingPid();
3437*ec779b8eSAndroid Build Coastguard Worker auto clientUid = getCallingUid();
3438*ec779b8eSAndroid Build Coastguard Worker bool openCloseCallbackAllowed = hasPermissionsForOpenCloseListener(clientPid, clientUid);
3439*ec779b8eSAndroid Build Coastguard Worker
3440*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3441*ec779b8eSAndroid Build Coastguard Worker
3442*ec779b8eSAndroid Build Coastguard Worker {
3443*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
3444*ec779b8eSAndroid Build Coastguard Worker for (const auto &it : mListenerList) {
3445*ec779b8eSAndroid Build Coastguard Worker if (IInterface::asBinder(it->getListener()) == IInterface::asBinder(listener)) {
3446*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Tried to add listener %p which was already subscribed",
3447*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, listener.get());
3448*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
3449*ec779b8eSAndroid Build Coastguard Worker }
3450*ec779b8eSAndroid Build Coastguard Worker }
3451*ec779b8eSAndroid Build Coastguard Worker
3452*ec779b8eSAndroid Build Coastguard Worker sp<ServiceListener> serviceListener =
3453*ec779b8eSAndroid Build Coastguard Worker new ServiceListener(this, listener, clientUid, clientPid, isVendorListener,
3454*ec779b8eSAndroid Build Coastguard Worker openCloseCallbackAllowed);
3455*ec779b8eSAndroid Build Coastguard Worker auto ret = serviceListener->initialize(isProcessLocalTest);
3456*ec779b8eSAndroid Build Coastguard Worker if (ret != NO_ERROR) {
3457*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Failed to initialize service listener: %s (%d)",
3458*ec779b8eSAndroid Build Coastguard Worker strerror(-ret), ret);
3459*ec779b8eSAndroid Build Coastguard Worker logServiceError(msg, ERROR_ILLEGAL_ARGUMENT);
3460*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3461*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
3462*ec779b8eSAndroid Build Coastguard Worker }
3463*ec779b8eSAndroid Build Coastguard Worker // The listener still needs to be added to the list of listeners, regardless of what
3464*ec779b8eSAndroid Build Coastguard Worker // permissions the listener process has / whether it is a vendor listener. Since it might be
3465*ec779b8eSAndroid Build Coastguard Worker // eligible to listen to other camera ids.
3466*ec779b8eSAndroid Build Coastguard Worker mListenerList.emplace_back(serviceListener);
3467*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->registerMonitorUid(clientUid, /*openCamera*/false);
3468*ec779b8eSAndroid Build Coastguard Worker }
3469*ec779b8eSAndroid Build Coastguard Worker
3470*ec779b8eSAndroid Build Coastguard Worker /* Collect current devices and status */
3471*ec779b8eSAndroid Build Coastguard Worker {
3472*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mCameraStatesLock);
3473*ec779b8eSAndroid Build Coastguard Worker for (auto& i : mCameraStates) {
3474*ec779b8eSAndroid Build Coastguard Worker // Get the device id and app-visible camera id for the given HAL-visible camera id.
3475*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, mappedCameraId] =
3476*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(i.first);
3477*ec779b8eSAndroid Build Coastguard Worker
3478*ec779b8eSAndroid Build Coastguard Worker cameraStatuses->emplace_back(mappedCameraId,
3479*ec779b8eSAndroid Build Coastguard Worker mapToInterface(i.second->getStatus()), i.second->getUnavailablePhysicalIds(),
3480*ec779b8eSAndroid Build Coastguard Worker openCloseCallbackAllowed ? i.second->getClientPackage() : std::string(),
3481*ec779b8eSAndroid Build Coastguard Worker deviceId);
3482*ec779b8eSAndroid Build Coastguard Worker }
3483*ec779b8eSAndroid Build Coastguard Worker }
3484*ec779b8eSAndroid Build Coastguard Worker // Remove the camera statuses that should be hidden from the client, we do
3485*ec779b8eSAndroid Build Coastguard Worker // this after collecting the states in order to avoid holding
3486*ec779b8eSAndroid Build Coastguard Worker // mCameraStatesLock and mInterfaceLock (held in getSystemCameraKind()) at
3487*ec779b8eSAndroid Build Coastguard Worker // the same time.
3488*ec779b8eSAndroid Build Coastguard Worker cameraStatuses->erase(std::remove_if(cameraStatuses->begin(), cameraStatuses->end(),
3489*ec779b8eSAndroid Build Coastguard Worker [this, &isVendorListener, &clientPid, &clientUid](const hardware::CameraStatus& s) {
3490*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = s.cameraId;
3491*ec779b8eSAndroid Build Coastguard Worker std::optional<std::string> cameraIdOptional = resolveCameraId(s.cameraId,
3492*ec779b8eSAndroid Build Coastguard Worker s.deviceId, IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM);
3493*ec779b8eSAndroid Build Coastguard Worker if (!cameraIdOptional.has_value()) {
3494*ec779b8eSAndroid Build Coastguard Worker std::string msg =
3495*ec779b8eSAndroid Build Coastguard Worker fmt::sprintf(
3496*ec779b8eSAndroid Build Coastguard Worker "Camera %s: Invalid camera id for device id %d",
3497*ec779b8eSAndroid Build Coastguard Worker s.cameraId.c_str(), s.deviceId);
3498*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3499*ec779b8eSAndroid Build Coastguard Worker return true;
3500*ec779b8eSAndroid Build Coastguard Worker }
3501*ec779b8eSAndroid Build Coastguard Worker cameraId = cameraIdOptional.value();
3502*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
3503*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
3504*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera id %s, skipping status update",
3505*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, s.cameraId.c_str());
3506*ec779b8eSAndroid Build Coastguard Worker return true;
3507*ec779b8eSAndroid Build Coastguard Worker }
3508*ec779b8eSAndroid Build Coastguard Worker return shouldSkipStatusUpdates(deviceKind, isVendorListener, clientPid,
3509*ec779b8eSAndroid Build Coastguard Worker clientUid);
3510*ec779b8eSAndroid Build Coastguard Worker }), cameraStatuses->end());
3511*ec779b8eSAndroid Build Coastguard Worker
3512*ec779b8eSAndroid Build Coastguard Worker // cameraStatuses will have non-eligible camera ids removed.
3513*ec779b8eSAndroid Build Coastguard Worker std::set<std::string> idsChosenForCallback;
3514*ec779b8eSAndroid Build Coastguard Worker for (const auto &s : *cameraStatuses) {
3515*ec779b8eSAndroid Build Coastguard Worker // Add only default device cameras here, as virtual cameras currently don't support torch
3516*ec779b8eSAndroid Build Coastguard Worker // anyway. Note that this is a simplification of the implementation here, and we should
3517*ec779b8eSAndroid Build Coastguard Worker // change this when virtual cameras support torch.
3518*ec779b8eSAndroid Build Coastguard Worker if (s.deviceId == kDefaultDeviceId) {
3519*ec779b8eSAndroid Build Coastguard Worker idsChosenForCallback.insert(s.cameraId);
3520*ec779b8eSAndroid Build Coastguard Worker }
3521*ec779b8eSAndroid Build Coastguard Worker }
3522*ec779b8eSAndroid Build Coastguard Worker
3523*ec779b8eSAndroid Build Coastguard Worker /*
3524*ec779b8eSAndroid Build Coastguard Worker * Immediately signal current torch status to this listener only
3525*ec779b8eSAndroid Build Coastguard Worker * This may be a subset of all the devices, so don't include it in the response directly
3526*ec779b8eSAndroid Build Coastguard Worker */
3527*ec779b8eSAndroid Build Coastguard Worker {
3528*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
3529*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) {
3530*ec779b8eSAndroid Build Coastguard Worker const std::string &id = mTorchStatusMap.keyAt(i);
3531*ec779b8eSAndroid Build Coastguard Worker // The camera id is visible to the client. Fine to send torch
3532*ec779b8eSAndroid Build Coastguard Worker // callback.
3533*ec779b8eSAndroid Build Coastguard Worker if (idsChosenForCallback.find(id) != idsChosenForCallback.end()) {
3534*ec779b8eSAndroid Build Coastguard Worker listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id,
3535*ec779b8eSAndroid Build Coastguard Worker kDefaultDeviceId);
3536*ec779b8eSAndroid Build Coastguard Worker }
3537*ec779b8eSAndroid Build Coastguard Worker }
3538*ec779b8eSAndroid Build Coastguard Worker }
3539*ec779b8eSAndroid Build Coastguard Worker
3540*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3541*ec779b8eSAndroid Build Coastguard Worker }
3542*ec779b8eSAndroid Build Coastguard Worker
removeListener(const sp<ICameraServiceListener> & listener)3543*ec779b8eSAndroid Build Coastguard Worker Status CameraService::removeListener(const sp<ICameraServiceListener>& listener) {
3544*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3545*ec779b8eSAndroid Build Coastguard Worker
3546*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
3547*ec779b8eSAndroid Build Coastguard Worker
3548*ec779b8eSAndroid Build Coastguard Worker if (listener == 0) {
3549*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Listener must not be null", __FUNCTION__);
3550*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener");
3551*ec779b8eSAndroid Build Coastguard Worker }
3552*ec779b8eSAndroid Build Coastguard Worker
3553*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3554*ec779b8eSAndroid Build Coastguard Worker
3555*ec779b8eSAndroid Build Coastguard Worker {
3556*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
3557*ec779b8eSAndroid Build Coastguard Worker for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
3558*ec779b8eSAndroid Build Coastguard Worker if (IInterface::asBinder((*it)->getListener()) == IInterface::asBinder(listener)) {
3559*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->unregisterMonitorUid((*it)->getListenerUid(), /*closeCamera*/false);
3560*ec779b8eSAndroid Build Coastguard Worker IInterface::asBinder(listener)->unlinkToDeath(*it);
3561*ec779b8eSAndroid Build Coastguard Worker mListenerList.erase(it);
3562*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3563*ec779b8eSAndroid Build Coastguard Worker }
3564*ec779b8eSAndroid Build Coastguard Worker }
3565*ec779b8eSAndroid Build Coastguard Worker }
3566*ec779b8eSAndroid Build Coastguard Worker
3567*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Tried to remove a listener %p which was not subscribed",
3568*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, listener.get());
3569*ec779b8eSAndroid Build Coastguard Worker
3570*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener");
3571*ec779b8eSAndroid Build Coastguard Worker }
3572*ec779b8eSAndroid Build Coastguard Worker
getLegacyParameters(int cameraId,std::string * parameters)3573*ec779b8eSAndroid Build Coastguard Worker Status CameraService::getLegacyParameters(int cameraId, /*out*/std::string* parameters) {
3574*ec779b8eSAndroid Build Coastguard Worker
3575*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3576*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId);
3577*ec779b8eSAndroid Build Coastguard Worker
3578*ec779b8eSAndroid Build Coastguard Worker if (parameters == NULL) {
3579*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: parameters must not be null", __FUNCTION__);
3580*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null");
3581*ec779b8eSAndroid Build Coastguard Worker }
3582*ec779b8eSAndroid Build Coastguard Worker
3583*ec779b8eSAndroid Build Coastguard Worker Status ret = Status::ok();
3584*ec779b8eSAndroid Build Coastguard Worker
3585*ec779b8eSAndroid Build Coastguard Worker CameraParameters shimParams;
3586*ec779b8eSAndroid Build Coastguard Worker if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) {
3587*ec779b8eSAndroid Build Coastguard Worker // Error logged by caller
3588*ec779b8eSAndroid Build Coastguard Worker return ret;
3589*ec779b8eSAndroid Build Coastguard Worker }
3590*ec779b8eSAndroid Build Coastguard Worker
3591*ec779b8eSAndroid Build Coastguard Worker String8 shimParamsString8 = shimParams.flatten();
3592*ec779b8eSAndroid Build Coastguard Worker
3593*ec779b8eSAndroid Build Coastguard Worker *parameters = toStdString(shimParamsString8);
3594*ec779b8eSAndroid Build Coastguard Worker
3595*ec779b8eSAndroid Build Coastguard Worker return ret;
3596*ec779b8eSAndroid Build Coastguard Worker }
3597*ec779b8eSAndroid Build Coastguard Worker
supportsCameraApi(const std::string & cameraId,int apiVersion,bool * isSupported)3598*ec779b8eSAndroid Build Coastguard Worker Status CameraService::supportsCameraApi(const std::string& cameraId, int apiVersion,
3599*ec779b8eSAndroid Build Coastguard Worker /*out*/ bool *isSupported) {
3600*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3601*ec779b8eSAndroid Build Coastguard Worker
3602*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
3603*ec779b8eSAndroid Build Coastguard Worker
3604*ec779b8eSAndroid Build Coastguard Worker switch (apiVersion) {
3605*ec779b8eSAndroid Build Coastguard Worker case API_VERSION_1:
3606*ec779b8eSAndroid Build Coastguard Worker case API_VERSION_2:
3607*ec779b8eSAndroid Build Coastguard Worker break;
3608*ec779b8eSAndroid Build Coastguard Worker default:
3609*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Unknown API version %d", apiVersion);
3610*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3611*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
3612*ec779b8eSAndroid Build Coastguard Worker }
3613*ec779b8eSAndroid Build Coastguard Worker
3614*ec779b8eSAndroid Build Coastguard Worker int portraitRotation;
3615*ec779b8eSAndroid Build Coastguard Worker auto deviceVersionAndTransport =
3616*ec779b8eSAndroid Build Coastguard Worker getDeviceVersion(cameraId,
3617*ec779b8eSAndroid Build Coastguard Worker /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
3618*ec779b8eSAndroid Build Coastguard Worker &portraitRotation);
3619*ec779b8eSAndroid Build Coastguard Worker if (deviceVersionAndTransport.first == -1) {
3620*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Unknown camera ID %s", cameraId.c_str());
3621*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3622*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
3623*ec779b8eSAndroid Build Coastguard Worker }
3624*ec779b8eSAndroid Build Coastguard Worker if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
3625*ec779b8eSAndroid Build Coastguard Worker int deviceVersion = deviceVersionAndTransport.first;
3626*ec779b8eSAndroid Build Coastguard Worker switch (deviceVersion) {
3627*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_1_0:
3628*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_0:
3629*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_1:
3630*ec779b8eSAndroid Build Coastguard Worker if (apiVersion == API_VERSION_2) {
3631*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without "
3632*ec779b8eSAndroid Build Coastguard Worker "shim", __FUNCTION__, cameraId.c_str(), deviceVersion);
3633*ec779b8eSAndroid Build Coastguard Worker *isSupported = false;
3634*ec779b8eSAndroid Build Coastguard Worker } else { // if (apiVersion == API_VERSION_1) {
3635*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always "
3636*ec779b8eSAndroid Build Coastguard Worker "supported", __FUNCTION__, cameraId.c_str());
3637*ec779b8eSAndroid Build Coastguard Worker *isSupported = true;
3638*ec779b8eSAndroid Build Coastguard Worker }
3639*ec779b8eSAndroid Build Coastguard Worker break;
3640*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_2:
3641*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_3:
3642*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_4:
3643*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_5:
3644*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_6:
3645*ec779b8eSAndroid Build Coastguard Worker case CAMERA_DEVICE_API_VERSION_3_7:
3646*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
3647*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
3648*ec779b8eSAndroid Build Coastguard Worker *isSupported = true;
3649*ec779b8eSAndroid Build Coastguard Worker break;
3650*ec779b8eSAndroid Build Coastguard Worker default: {
3651*ec779b8eSAndroid Build Coastguard Worker std::string msg = fmt::sprintf("Unknown device version %x for device %s",
3652*ec779b8eSAndroid Build Coastguard Worker deviceVersion, cameraId.c_str());
3653*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: %s", __FUNCTION__, msg.c_str());
3654*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.c_str());
3655*ec779b8eSAndroid Build Coastguard Worker }
3656*ec779b8eSAndroid Build Coastguard Worker }
3657*ec779b8eSAndroid Build Coastguard Worker } else {
3658*ec779b8eSAndroid Build Coastguard Worker *isSupported = true;
3659*ec779b8eSAndroid Build Coastguard Worker }
3660*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3661*ec779b8eSAndroid Build Coastguard Worker }
3662*ec779b8eSAndroid Build Coastguard Worker
isHiddenPhysicalCamera(const std::string & cameraId,bool * isSupported)3663*ec779b8eSAndroid Build Coastguard Worker Status CameraService::isHiddenPhysicalCamera(const std::string& cameraId,
3664*ec779b8eSAndroid Build Coastguard Worker /*out*/ bool *isSupported) {
3665*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3666*ec779b8eSAndroid Build Coastguard Worker
3667*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str());
3668*ec779b8eSAndroid Build Coastguard Worker *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(cameraId);
3669*ec779b8eSAndroid Build Coastguard Worker
3670*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3671*ec779b8eSAndroid Build Coastguard Worker }
3672*ec779b8eSAndroid Build Coastguard Worker
injectCamera(const std::string & packageName,const std::string & internalCamId,const std::string & externalCamId,const sp<ICameraInjectionCallback> & callback,sp<ICameraInjectionSession> * cameraInjectionSession)3673*ec779b8eSAndroid Build Coastguard Worker Status CameraService::injectCamera(
3674*ec779b8eSAndroid Build Coastguard Worker const std::string& packageName, const std::string& internalCamId,
3675*ec779b8eSAndroid Build Coastguard Worker const std::string& externalCamId,
3676*ec779b8eSAndroid Build Coastguard Worker const sp<ICameraInjectionCallback>& callback,
3677*ec779b8eSAndroid Build Coastguard Worker /*out*/
3678*ec779b8eSAndroid Build Coastguard Worker sp<ICameraInjectionSession>* cameraInjectionSession) {
3679*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
3680*ec779b8eSAndroid Build Coastguard Worker
3681*ec779b8eSAndroid Build Coastguard Worker if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) {
3682*ec779b8eSAndroid Build Coastguard Worker const int pid = getCallingPid();
3683*ec779b8eSAndroid Build Coastguard Worker const int uid = getCallingUid();
3684*ec779b8eSAndroid Build Coastguard Worker ALOGE("Permission Denial: can't inject camera pid=%d, uid=%d", pid, uid);
3685*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ERROR_PERMISSION_DENIED,
3686*ec779b8eSAndroid Build Coastguard Worker "Permission Denial: no permission to inject camera");
3687*ec779b8eSAndroid Build Coastguard Worker }
3688*ec779b8eSAndroid Build Coastguard Worker
3689*ec779b8eSAndroid Build Coastguard Worker // Do not allow any camera injection that injects or replaces a virtual camera.
3690*ec779b8eSAndroid Build Coastguard Worker auto [deviceIdForInternalCamera, _] =
3691*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(internalCamId);
3692*ec779b8eSAndroid Build Coastguard Worker if (deviceIdForInternalCamera != kDefaultDeviceId) {
3693*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED,
3694*ec779b8eSAndroid Build Coastguard Worker "Cannot replace a virtual camera");
3695*ec779b8eSAndroid Build Coastguard Worker }
3696*ec779b8eSAndroid Build Coastguard Worker [[maybe_unused]] auto [deviceIdForExternalCamera, unusedMappedCameraId] =
3697*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(externalCamId);
3698*ec779b8eSAndroid Build Coastguard Worker if (deviceIdForExternalCamera != kDefaultDeviceId) {
3699*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED,
3700*ec779b8eSAndroid Build Coastguard Worker "Cannot inject a virtual camera to replace an internal camera");
3701*ec779b8eSAndroid Build Coastguard Worker }
3702*ec779b8eSAndroid Build Coastguard Worker
3703*ec779b8eSAndroid Build Coastguard Worker ALOGV(
3704*ec779b8eSAndroid Build Coastguard Worker "%s: Package name = %s, Internal camera ID = %s, External camera ID = "
3705*ec779b8eSAndroid Build Coastguard Worker "%s",
3706*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, packageName.c_str(),
3707*ec779b8eSAndroid Build Coastguard Worker internalCamId.c_str(), externalCamId.c_str());
3708*ec779b8eSAndroid Build Coastguard Worker
3709*ec779b8eSAndroid Build Coastguard Worker {
3710*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mInjectionParametersLock);
3711*ec779b8eSAndroid Build Coastguard Worker mInjectionInternalCamId = internalCamId;
3712*ec779b8eSAndroid Build Coastguard Worker mInjectionExternalCamId = externalCamId;
3713*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->addListener(callback);
3714*ec779b8eSAndroid Build Coastguard Worker *cameraInjectionSession = new CameraInjectionSession(this);
3715*ec779b8eSAndroid Build Coastguard Worker status_t res = NO_ERROR;
3716*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId);
3717*ec779b8eSAndroid Build Coastguard Worker // If the client already exists, we can directly connect to the camera device through the
3718*ec779b8eSAndroid Build Coastguard Worker // client's injectCamera(), otherwise we need to wait until the client is established
3719*ec779b8eSAndroid Build Coastguard Worker // (execute connectHelper()) before injecting the camera to the camera device.
3720*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor != nullptr) {
3721*ec779b8eSAndroid Build Coastguard Worker mInjectionInitPending = false;
3722*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp = clientDescriptor->getValue();
3723*ec779b8eSAndroid Build Coastguard Worker res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp);
3724*ec779b8eSAndroid Build Coastguard Worker if(res != OK) {
3725*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
3726*ec779b8eSAndroid Build Coastguard Worker "No camera device with ID \"%s\" currently available",
3727*ec779b8eSAndroid Build Coastguard Worker mInjectionExternalCamId.c_str());
3728*ec779b8eSAndroid Build Coastguard Worker }
3729*ec779b8eSAndroid Build Coastguard Worker res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager);
3730*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
3731*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res);
3732*ec779b8eSAndroid Build Coastguard Worker }
3733*ec779b8eSAndroid Build Coastguard Worker } else {
3734*ec779b8eSAndroid Build Coastguard Worker mInjectionInitPending = true;
3735*ec779b8eSAndroid Build Coastguard Worker }
3736*ec779b8eSAndroid Build Coastguard Worker }
3737*ec779b8eSAndroid Build Coastguard Worker
3738*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
3739*ec779b8eSAndroid Build Coastguard Worker }
3740*ec779b8eSAndroid Build Coastguard Worker
reportExtensionSessionStats(const hardware::CameraExtensionSessionStats & stats,std::string * sessionKey)3741*ec779b8eSAndroid Build Coastguard Worker Status CameraService::reportExtensionSessionStats(
3742*ec779b8eSAndroid Build Coastguard Worker const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/) {
3743*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: reported %s", __FUNCTION__, stats.toString().c_str());
3744*ec779b8eSAndroid Build Coastguard Worker *sessionKey = mCameraServiceProxyWrapper->updateExtensionStats(stats);
3745*ec779b8eSAndroid Build Coastguard Worker return Status::ok();
3746*ec779b8eSAndroid Build Coastguard Worker }
3747*ec779b8eSAndroid Build Coastguard Worker
removeByClient(const BasicClient * client)3748*ec779b8eSAndroid Build Coastguard Worker void CameraService::removeByClient(const BasicClient* client) {
3749*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3750*ec779b8eSAndroid Build Coastguard Worker for (auto& i : mActiveClientManager.getAll()) {
3751*ec779b8eSAndroid Build Coastguard Worker auto clientSp = i->getValue();
3752*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() == client) {
3753*ec779b8eSAndroid Build Coastguard Worker cacheClientTagDumpIfNeeded(client->mCameraIdStr, clientSp.get());
3754*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.remove(i);
3755*ec779b8eSAndroid Build Coastguard Worker }
3756*ec779b8eSAndroid Build Coastguard Worker }
3757*ec779b8eSAndroid Build Coastguard Worker updateAudioRestrictionLocked();
3758*ec779b8eSAndroid Build Coastguard Worker }
3759*ec779b8eSAndroid Build Coastguard Worker
isOnlyClient(const BasicClient * client)3760*ec779b8eSAndroid Build Coastguard Worker bool CameraService::isOnlyClient(const BasicClient* client) {
3761*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
3762*ec779b8eSAndroid Build Coastguard Worker bool ret = true;
3763*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client()) {
3764*ec779b8eSAndroid Build Coastguard Worker return ret;
3765*ec779b8eSAndroid Build Coastguard Worker }
3766*ec779b8eSAndroid Build Coastguard Worker if (client != nullptr) {
3767*ec779b8eSAndroid Build Coastguard Worker std::string camId = client->mCameraIdStr;
3768*ec779b8eSAndroid Build Coastguard Worker for (const auto& i : mActiveClientManager.getAll()) {
3769*ec779b8eSAndroid Build Coastguard Worker auto clientSp = i->getValue();
3770*ec779b8eSAndroid Build Coastguard Worker auto curCamId = i->getKey();
3771*ec779b8eSAndroid Build Coastguard Worker if (!curCamId.compare(camId) && clientSp.get() != client) {
3772*ec779b8eSAndroid Build Coastguard Worker return false;
3773*ec779b8eSAndroid Build Coastguard Worker }
3774*ec779b8eSAndroid Build Coastguard Worker }
3775*ec779b8eSAndroid Build Coastguard Worker }
3776*ec779b8eSAndroid Build Coastguard Worker return ret;
3777*ec779b8eSAndroid Build Coastguard Worker }
3778*ec779b8eSAndroid Build Coastguard Worker
evictClientIdByRemote(const wp<IBinder> & remote)3779*ec779b8eSAndroid Build Coastguard Worker bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
3780*ec779b8eSAndroid Build Coastguard Worker bool ret = false;
3781*ec779b8eSAndroid Build Coastguard Worker {
3782*ec779b8eSAndroid Build Coastguard Worker // Acquire mServiceLock and prevent other clients from connecting
3783*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<AutoConditionLock> lock =
3784*ec779b8eSAndroid Build Coastguard Worker AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
3785*ec779b8eSAndroid Build Coastguard Worker
3786*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<BasicClient>> evicted;
3787*ec779b8eSAndroid Build Coastguard Worker for (auto& i : mActiveClientManager.getAll()) {
3788*ec779b8eSAndroid Build Coastguard Worker auto clientSp = i->getValue();
3789*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() == nullptr) {
3790*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
3791*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.remove(i);
3792*ec779b8eSAndroid Build Coastguard Worker continue;
3793*ec779b8eSAndroid Build Coastguard Worker }
3794*ec779b8eSAndroid Build Coastguard Worker if (remote == clientSp->getRemote()) {
3795*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.remove(i);
3796*ec779b8eSAndroid Build Coastguard Worker evicted.push_back(clientSp);
3797*ec779b8eSAndroid Build Coastguard Worker
3798*ec779b8eSAndroid Build Coastguard Worker // Notify the client of disconnection
3799*ec779b8eSAndroid Build Coastguard Worker clientSp->notifyError(
3800*ec779b8eSAndroid Build Coastguard Worker hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
3801*ec779b8eSAndroid Build Coastguard Worker CaptureResultExtras());
3802*ec779b8eSAndroid Build Coastguard Worker }
3803*ec779b8eSAndroid Build Coastguard Worker }
3804*ec779b8eSAndroid Build Coastguard Worker
3805*ec779b8eSAndroid Build Coastguard Worker // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
3806*ec779b8eSAndroid Build Coastguard Worker // other clients from connecting in mServiceLockWrapper if held
3807*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
3808*ec779b8eSAndroid Build Coastguard Worker
3809*ec779b8eSAndroid Build Coastguard Worker // Do not clear caller identity, remote caller should be client proccess
3810*ec779b8eSAndroid Build Coastguard Worker
3811*ec779b8eSAndroid Build Coastguard Worker for (auto& i : evicted) {
3812*ec779b8eSAndroid Build Coastguard Worker if (i.get() != nullptr) {
3813*ec779b8eSAndroid Build Coastguard Worker i->disconnect();
3814*ec779b8eSAndroid Build Coastguard Worker ret = true;
3815*ec779b8eSAndroid Build Coastguard Worker }
3816*ec779b8eSAndroid Build Coastguard Worker }
3817*ec779b8eSAndroid Build Coastguard Worker
3818*ec779b8eSAndroid Build Coastguard Worker // Reacquire mServiceLock
3819*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
3820*ec779b8eSAndroid Build Coastguard Worker
3821*ec779b8eSAndroid Build Coastguard Worker } // lock is destroyed, allow further connect calls
3822*ec779b8eSAndroid Build Coastguard Worker
3823*ec779b8eSAndroid Build Coastguard Worker return ret;
3824*ec779b8eSAndroid Build Coastguard Worker }
3825*ec779b8eSAndroid Build Coastguard Worker
getCameraState(const std::string & cameraId) const3826*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<CameraService::CameraState> CameraService::getCameraState(
3827*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId) const {
3828*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<CameraState> state;
3829*ec779b8eSAndroid Build Coastguard Worker {
3830*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mCameraStatesLock);
3831*ec779b8eSAndroid Build Coastguard Worker auto iter = mCameraStates.find(cameraId);
3832*ec779b8eSAndroid Build Coastguard Worker if (iter != mCameraStates.end()) {
3833*ec779b8eSAndroid Build Coastguard Worker state = iter->second;
3834*ec779b8eSAndroid Build Coastguard Worker }
3835*ec779b8eSAndroid Build Coastguard Worker }
3836*ec779b8eSAndroid Build Coastguard Worker return state;
3837*ec779b8eSAndroid Build Coastguard Worker }
3838*ec779b8eSAndroid Build Coastguard Worker
removeClientsLocked(const std::string & cameraId)3839*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<CameraService::BasicClient>> CameraService::removeClientsLocked(
3840*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId) {
3841*ec779b8eSAndroid Build Coastguard Worker // Remove from active clients list
3842*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<CameraService::BasicClient>> clients;
3843*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_multi_client()) {
3844*ec779b8eSAndroid Build Coastguard Worker std::vector<CameraService::DescriptorPtr> clientDescriptors;
3845*ec779b8eSAndroid Build Coastguard Worker clientDescriptors = mActiveClientManager.removeAll(cameraId);
3846*ec779b8eSAndroid Build Coastguard Worker for (const auto& clientDescriptorPtr : clientDescriptors) {
3847*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptorPtr != nullptr) {
3848*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = clientDescriptorPtr->getValue();
3849*ec779b8eSAndroid Build Coastguard Worker if (client.get() != nullptr) {
3850*ec779b8eSAndroid Build Coastguard Worker cacheClientTagDumpIfNeeded(clientDescriptorPtr->getKey(), client.get());
3851*ec779b8eSAndroid Build Coastguard Worker clients.push_back(client);
3852*ec779b8eSAndroid Build Coastguard Worker }
3853*ec779b8eSAndroid Build Coastguard Worker }
3854*ec779b8eSAndroid Build Coastguard Worker }
3855*ec779b8eSAndroid Build Coastguard Worker } else {
3856*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
3857*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptorPtr == nullptr) {
3858*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
3859*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
3860*ec779b8eSAndroid Build Coastguard Worker return clients;
3861*ec779b8eSAndroid Build Coastguard Worker }
3862*ec779b8eSAndroid Build Coastguard Worker
3863*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = clientDescriptorPtr->getValue();
3864*ec779b8eSAndroid Build Coastguard Worker if (client.get() != nullptr) {
3865*ec779b8eSAndroid Build Coastguard Worker cacheClientTagDumpIfNeeded(clientDescriptorPtr->getKey(), client.get());
3866*ec779b8eSAndroid Build Coastguard Worker clients.push_back(client);
3867*ec779b8eSAndroid Build Coastguard Worker }
3868*ec779b8eSAndroid Build Coastguard Worker }
3869*ec779b8eSAndroid Build Coastguard Worker return clients;
3870*ec779b8eSAndroid Build Coastguard Worker }
3871*ec779b8eSAndroid Build Coastguard Worker
doUserSwitch(const std::vector<int32_t> & newUserIds)3872*ec779b8eSAndroid Build Coastguard Worker void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) {
3873*ec779b8eSAndroid Build Coastguard Worker // Acquire mServiceLock and prevent other clients from connecting
3874*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<AutoConditionLock> lock =
3875*ec779b8eSAndroid Build Coastguard Worker AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
3876*ec779b8eSAndroid Build Coastguard Worker
3877*ec779b8eSAndroid Build Coastguard Worker std::set<userid_t> newAllowedUsers;
3878*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < newUserIds.size(); i++) {
3879*ec779b8eSAndroid Build Coastguard Worker if (newUserIds[i] < 0) {
3880*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Bad user ID %d given during user switch, ignoring.",
3881*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, newUserIds[i]);
3882*ec779b8eSAndroid Build Coastguard Worker return;
3883*ec779b8eSAndroid Build Coastguard Worker }
3884*ec779b8eSAndroid Build Coastguard Worker newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i]));
3885*ec779b8eSAndroid Build Coastguard Worker }
3886*ec779b8eSAndroid Build Coastguard Worker
3887*ec779b8eSAndroid Build Coastguard Worker
3888*ec779b8eSAndroid Build Coastguard Worker if (newAllowedUsers == mAllowedUsers) {
3889*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__);
3890*ec779b8eSAndroid Build Coastguard Worker return;
3891*ec779b8eSAndroid Build Coastguard Worker }
3892*ec779b8eSAndroid Build Coastguard Worker
3893*ec779b8eSAndroid Build Coastguard Worker logUserSwitch(mAllowedUsers, newAllowedUsers);
3894*ec779b8eSAndroid Build Coastguard Worker
3895*ec779b8eSAndroid Build Coastguard Worker mAllowedUsers = std::move(newAllowedUsers);
3896*ec779b8eSAndroid Build Coastguard Worker
3897*ec779b8eSAndroid Build Coastguard Worker // Current user has switched, evict all current clients.
3898*ec779b8eSAndroid Build Coastguard Worker std::vector<sp<BasicClient>> evicted;
3899*ec779b8eSAndroid Build Coastguard Worker for (auto& i : mActiveClientManager.getAll()) {
3900*ec779b8eSAndroid Build Coastguard Worker auto clientSp = i->getValue();
3901*ec779b8eSAndroid Build Coastguard Worker
3902*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() == nullptr) {
3903*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__);
3904*ec779b8eSAndroid Build Coastguard Worker continue;
3905*ec779b8eSAndroid Build Coastguard Worker }
3906*ec779b8eSAndroid Build Coastguard Worker
3907*ec779b8eSAndroid Build Coastguard Worker // Don't evict clients that are still allowed.
3908*ec779b8eSAndroid Build Coastguard Worker uid_t clientUid = clientSp->getClientUid();
3909*ec779b8eSAndroid Build Coastguard Worker userid_t clientUserId = multiuser_get_user_id(clientUid);
3910*ec779b8eSAndroid Build Coastguard Worker if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) {
3911*ec779b8eSAndroid Build Coastguard Worker continue;
3912*ec779b8eSAndroid Build Coastguard Worker }
3913*ec779b8eSAndroid Build Coastguard Worker
3914*ec779b8eSAndroid Build Coastguard Worker evicted.push_back(clientSp);
3915*ec779b8eSAndroid Build Coastguard Worker
3916*ec779b8eSAndroid Build Coastguard Worker ALOGE("Evicting conflicting client for camera ID %s due to user change",
3917*ec779b8eSAndroid Build Coastguard Worker i->getKey().c_str());
3918*ec779b8eSAndroid Build Coastguard Worker
3919*ec779b8eSAndroid Build Coastguard Worker // Log the clients evicted
3920*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID %"
3921*ec779b8eSAndroid Build Coastguard Worker PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted due"
3922*ec779b8eSAndroid Build Coastguard Worker " to user switch.", i->getKey().c_str(),
3923*ec779b8eSAndroid Build Coastguard Worker clientSp->getPackageName().c_str(),
3924*ec779b8eSAndroid Build Coastguard Worker i->getOwnerId(), i->getPriority().getScore(),
3925*ec779b8eSAndroid Build Coastguard Worker i->getPriority().getState()));
3926*ec779b8eSAndroid Build Coastguard Worker
3927*ec779b8eSAndroid Build Coastguard Worker }
3928*ec779b8eSAndroid Build Coastguard Worker
3929*ec779b8eSAndroid Build Coastguard Worker // Do not hold mServiceLock while disconnecting clients, but retain the condition
3930*ec779b8eSAndroid Build Coastguard Worker // blocking other clients from connecting in mServiceLockWrapper if held.
3931*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
3932*ec779b8eSAndroid Build Coastguard Worker
3933*ec779b8eSAndroid Build Coastguard Worker // Clear caller identity temporarily so client disconnect PID checks work correctly
3934*ec779b8eSAndroid Build Coastguard Worker int64_t token = clearCallingIdentity();
3935*ec779b8eSAndroid Build Coastguard Worker
3936*ec779b8eSAndroid Build Coastguard Worker for (auto& i : evicted) {
3937*ec779b8eSAndroid Build Coastguard Worker i->disconnect();
3938*ec779b8eSAndroid Build Coastguard Worker }
3939*ec779b8eSAndroid Build Coastguard Worker
3940*ec779b8eSAndroid Build Coastguard Worker restoreCallingIdentity(token);
3941*ec779b8eSAndroid Build Coastguard Worker
3942*ec779b8eSAndroid Build Coastguard Worker // Reacquire mServiceLock
3943*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
3944*ec779b8eSAndroid Build Coastguard Worker }
3945*ec779b8eSAndroid Build Coastguard Worker
logEvent(const std::string & event)3946*ec779b8eSAndroid Build Coastguard Worker void CameraService::logEvent(const std::string &event) {
3947*ec779b8eSAndroid Build Coastguard Worker std::string curTime = getFormattedCurrentTime();
3948*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mLogLock);
3949*ec779b8eSAndroid Build Coastguard Worker std::string msg = curTime + " : " + event;
3950*ec779b8eSAndroid Build Coastguard Worker // For service error events, print the msg only once.
3951*ec779b8eSAndroid Build Coastguard Worker if (msg.find("SERVICE ERROR") != std::string::npos) {
3952*ec779b8eSAndroid Build Coastguard Worker mEventLog.add(msg);
3953*ec779b8eSAndroid Build Coastguard Worker } else if(sServiceErrorEventSet.find(msg) == sServiceErrorEventSet.end()) {
3954*ec779b8eSAndroid Build Coastguard Worker // Error event not added to the dumpsys log before
3955*ec779b8eSAndroid Build Coastguard Worker mEventLog.add(msg);
3956*ec779b8eSAndroid Build Coastguard Worker sServiceErrorEventSet.insert(msg);
3957*ec779b8eSAndroid Build Coastguard Worker }
3958*ec779b8eSAndroid Build Coastguard Worker }
3959*ec779b8eSAndroid Build Coastguard Worker
logDisconnected(const std::string & cameraId,int clientPid,const std::string & clientPackage)3960*ec779b8eSAndroid Build Coastguard Worker void CameraService::logDisconnected(const std::string &cameraId, int clientPid,
3961*ec779b8eSAndroid Build Coastguard Worker const std::string &clientPackage) {
3962*ec779b8eSAndroid Build Coastguard Worker // Log the clients evicted
3963*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("DISCONNECT device %s client for package %s (PID %d)", cameraId.c_str(),
3964*ec779b8eSAndroid Build Coastguard Worker clientPackage.c_str(), clientPid));
3965*ec779b8eSAndroid Build Coastguard Worker }
3966*ec779b8eSAndroid Build Coastguard Worker
logDisconnectedOffline(const std::string & cameraId,int clientPid,const std::string & clientPackage)3967*ec779b8eSAndroid Build Coastguard Worker void CameraService::logDisconnectedOffline(const std::string &cameraId, int clientPid,
3968*ec779b8eSAndroid Build Coastguard Worker const std::string &clientPackage) {
3969*ec779b8eSAndroid Build Coastguard Worker // Log the clients evicted
3970*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("DISCONNECT offline device %s client for package %s (PID %d)",
3971*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), clientPackage.c_str(), clientPid));
3972*ec779b8eSAndroid Build Coastguard Worker }
3973*ec779b8eSAndroid Build Coastguard Worker
logConnected(const std::string & cameraId,int clientPid,const std::string & clientPackage)3974*ec779b8eSAndroid Build Coastguard Worker void CameraService::logConnected(const std::string &cameraId, int clientPid,
3975*ec779b8eSAndroid Build Coastguard Worker const std::string &clientPackage) {
3976*ec779b8eSAndroid Build Coastguard Worker // Log the clients evicted
3977*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("CONNECT device %s client for package %s (PID %d)", cameraId.c_str(),
3978*ec779b8eSAndroid Build Coastguard Worker clientPackage.c_str(), clientPid));
3979*ec779b8eSAndroid Build Coastguard Worker }
3980*ec779b8eSAndroid Build Coastguard Worker
logConnectedOffline(const std::string & cameraId,int clientPid,const std::string & clientPackage)3981*ec779b8eSAndroid Build Coastguard Worker void CameraService::logConnectedOffline(const std::string &cameraId, int clientPid,
3982*ec779b8eSAndroid Build Coastguard Worker const std::string &clientPackage) {
3983*ec779b8eSAndroid Build Coastguard Worker // Log the clients evicted
3984*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("CONNECT offline device %s client for package %s (PID %d)",
3985*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), clientPackage.c_str(), clientPid));
3986*ec779b8eSAndroid Build Coastguard Worker }
3987*ec779b8eSAndroid Build Coastguard Worker
logRejected(const std::string & cameraId,int clientPid,const std::string & clientPackage,const std::string & reason)3988*ec779b8eSAndroid Build Coastguard Worker void CameraService::logRejected(const std::string &cameraId, int clientPid,
3989*ec779b8eSAndroid Build Coastguard Worker const std::string &clientPackage, const std::string &reason) {
3990*ec779b8eSAndroid Build Coastguard Worker // Log the client rejected
3991*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("REJECT device %s client for package %s (PID %d), reason: (%s)",
3992*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), clientPackage.c_str(), clientPid, reason.c_str()));
3993*ec779b8eSAndroid Build Coastguard Worker }
3994*ec779b8eSAndroid Build Coastguard Worker
logTorchEvent(const std::string & cameraId,const std::string & torchState,int clientPid)3995*ec779b8eSAndroid Build Coastguard Worker void CameraService::logTorchEvent(const std::string &cameraId, const std::string &torchState,
3996*ec779b8eSAndroid Build Coastguard Worker int clientPid) {
3997*ec779b8eSAndroid Build Coastguard Worker // Log torch event
3998*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(),
3999*ec779b8eSAndroid Build Coastguard Worker torchState.c_str(), clientPid));
4000*ec779b8eSAndroid Build Coastguard Worker }
4001*ec779b8eSAndroid Build Coastguard Worker
logUserSwitch(const std::set<userid_t> & oldUserIds,const std::set<userid_t> & newUserIds)4002*ec779b8eSAndroid Build Coastguard Worker void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
4003*ec779b8eSAndroid Build Coastguard Worker const std::set<userid_t>& newUserIds) {
4004*ec779b8eSAndroid Build Coastguard Worker std::string newUsers = toString(newUserIds);
4005*ec779b8eSAndroid Build Coastguard Worker std::string oldUsers = toString(oldUserIds);
4006*ec779b8eSAndroid Build Coastguard Worker if (oldUsers.size() == 0) {
4007*ec779b8eSAndroid Build Coastguard Worker oldUsers = "<None>";
4008*ec779b8eSAndroid Build Coastguard Worker }
4009*ec779b8eSAndroid Build Coastguard Worker // Log the new and old users
4010*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s",
4011*ec779b8eSAndroid Build Coastguard Worker oldUsers.c_str(), newUsers.c_str()));
4012*ec779b8eSAndroid Build Coastguard Worker }
4013*ec779b8eSAndroid Build Coastguard Worker
logDeviceRemoved(const std::string & cameraId,const std::string & reason)4014*ec779b8eSAndroid Build Coastguard Worker void CameraService::logDeviceRemoved(const std::string &cameraId, const std::string &reason) {
4015*ec779b8eSAndroid Build Coastguard Worker // Log the device removal
4016*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("REMOVE device %s, reason: (%s)", cameraId.c_str(), reason.c_str()));
4017*ec779b8eSAndroid Build Coastguard Worker }
4018*ec779b8eSAndroid Build Coastguard Worker
logDeviceAdded(const std::string & cameraId,const std::string & reason)4019*ec779b8eSAndroid Build Coastguard Worker void CameraService::logDeviceAdded(const std::string &cameraId, const std::string &reason) {
4020*ec779b8eSAndroid Build Coastguard Worker // Log the device removal
4021*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("ADD device %s, reason: (%s)", cameraId.c_str(), reason.c_str()));
4022*ec779b8eSAndroid Build Coastguard Worker }
4023*ec779b8eSAndroid Build Coastguard Worker
logClientDied(int clientPid,const std::string & reason)4024*ec779b8eSAndroid Build Coastguard Worker void CameraService::logClientDied(int clientPid, const std::string &reason) {
4025*ec779b8eSAndroid Build Coastguard Worker // Log the device removal
4026*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("DIED client(s) with PID %d, reason: (%s)", clientPid, reason.c_str()));
4027*ec779b8eSAndroid Build Coastguard Worker }
4028*ec779b8eSAndroid Build Coastguard Worker
logServiceError(const std::string & msg,int errorCode)4029*ec779b8eSAndroid Build Coastguard Worker void CameraService::logServiceError(const std::string &msg, int errorCode) {
4030*ec779b8eSAndroid Build Coastguard Worker logEvent(fmt::sprintf("SERVICE ERROR: %s : %d (%s)", msg.c_str(), errorCode,
4031*ec779b8eSAndroid Build Coastguard Worker strerror(-errorCode)));
4032*ec779b8eSAndroid Build Coastguard Worker }
4033*ec779b8eSAndroid Build Coastguard Worker
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)4034*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
4035*ec779b8eSAndroid Build Coastguard Worker uint32_t flags) {
4036*ec779b8eSAndroid Build Coastguard Worker
4037*ec779b8eSAndroid Build Coastguard Worker // Permission checks
4038*ec779b8eSAndroid Build Coastguard Worker switch (code) {
4039*ec779b8eSAndroid Build Coastguard Worker case SHELL_COMMAND_TRANSACTION: {
4040*ec779b8eSAndroid Build Coastguard Worker int in = data.readFileDescriptor();
4041*ec779b8eSAndroid Build Coastguard Worker int out = data.readFileDescriptor();
4042*ec779b8eSAndroid Build Coastguard Worker int err = data.readFileDescriptor();
4043*ec779b8eSAndroid Build Coastguard Worker int argc = data.readInt32();
4044*ec779b8eSAndroid Build Coastguard Worker Vector<String16> args;
4045*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
4046*ec779b8eSAndroid Build Coastguard Worker args.add(data.readString16());
4047*ec779b8eSAndroid Build Coastguard Worker }
4048*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> unusedCallback;
4049*ec779b8eSAndroid Build Coastguard Worker sp<IResultReceiver> resultReceiver;
4050*ec779b8eSAndroid Build Coastguard Worker status_t status;
4051*ec779b8eSAndroid Build Coastguard Worker if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
4052*ec779b8eSAndroid Build Coastguard Worker return status;
4053*ec779b8eSAndroid Build Coastguard Worker }
4054*ec779b8eSAndroid Build Coastguard Worker if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
4055*ec779b8eSAndroid Build Coastguard Worker return status;
4056*ec779b8eSAndroid Build Coastguard Worker }
4057*ec779b8eSAndroid Build Coastguard Worker status = shellCommand(in, out, err, args);
4058*ec779b8eSAndroid Build Coastguard Worker if (resultReceiver != nullptr) {
4059*ec779b8eSAndroid Build Coastguard Worker resultReceiver->send(status);
4060*ec779b8eSAndroid Build Coastguard Worker }
4061*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
4062*ec779b8eSAndroid Build Coastguard Worker }
4063*ec779b8eSAndroid Build Coastguard Worker }
4064*ec779b8eSAndroid Build Coastguard Worker
4065*ec779b8eSAndroid Build Coastguard Worker return BnCameraService::onTransact(code, data, reply, flags);
4066*ec779b8eSAndroid Build Coastguard Worker }
4067*ec779b8eSAndroid Build Coastguard Worker
4068*ec779b8eSAndroid Build Coastguard Worker // We share the media players for shutter and recording sound for all clients.
4069*ec779b8eSAndroid Build Coastguard Worker // A reference count is kept to determine when we will actually release the
4070*ec779b8eSAndroid Build Coastguard Worker // media players.
newMediaPlayer(const char * file)4071*ec779b8eSAndroid Build Coastguard Worker sp<MediaPlayer> CameraService::newMediaPlayer(const char *file) {
4072*ec779b8eSAndroid Build Coastguard Worker sp<MediaPlayer> mp = new MediaPlayer();
4073*ec779b8eSAndroid Build Coastguard Worker status_t error;
4074*ec779b8eSAndroid Build Coastguard Worker if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) {
4075*ec779b8eSAndroid Build Coastguard Worker mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
4076*ec779b8eSAndroid Build Coastguard Worker error = mp->prepare();
4077*ec779b8eSAndroid Build Coastguard Worker }
4078*ec779b8eSAndroid Build Coastguard Worker if (error != NO_ERROR) {
4079*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to load CameraService sounds: %s", file);
4080*ec779b8eSAndroid Build Coastguard Worker mp->disconnect();
4081*ec779b8eSAndroid Build Coastguard Worker mp.clear();
4082*ec779b8eSAndroid Build Coastguard Worker return nullptr;
4083*ec779b8eSAndroid Build Coastguard Worker }
4084*ec779b8eSAndroid Build Coastguard Worker return mp;
4085*ec779b8eSAndroid Build Coastguard Worker }
4086*ec779b8eSAndroid Build Coastguard Worker
increaseSoundRef()4087*ec779b8eSAndroid Build Coastguard Worker void CameraService::increaseSoundRef() {
4088*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mSoundLock);
4089*ec779b8eSAndroid Build Coastguard Worker mSoundRef++;
4090*ec779b8eSAndroid Build Coastguard Worker }
4091*ec779b8eSAndroid Build Coastguard Worker
loadSoundLocked(sound_kind kind)4092*ec779b8eSAndroid Build Coastguard Worker void CameraService::loadSoundLocked(sound_kind kind) {
4093*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4094*ec779b8eSAndroid Build Coastguard Worker
4095*ec779b8eSAndroid Build Coastguard Worker LOG1("CameraService::loadSoundLocked ref=%d", mSoundRef);
4096*ec779b8eSAndroid Build Coastguard Worker if (SOUND_SHUTTER == kind && mSoundPlayer[SOUND_SHUTTER] == NULL) {
4097*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
4098*ec779b8eSAndroid Build Coastguard Worker if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
4099*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
4100*ec779b8eSAndroid Build Coastguard Worker }
4101*ec779b8eSAndroid Build Coastguard Worker } else if (SOUND_RECORDING_START == kind && mSoundPlayer[SOUND_RECORDING_START] == NULL) {
4102*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
4103*ec779b8eSAndroid Build Coastguard Worker if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
4104*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[SOUND_RECORDING_START] =
4105*ec779b8eSAndroid Build Coastguard Worker newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
4106*ec779b8eSAndroid Build Coastguard Worker }
4107*ec779b8eSAndroid Build Coastguard Worker } else if (SOUND_RECORDING_STOP == kind && mSoundPlayer[SOUND_RECORDING_STOP] == NULL) {
4108*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
4109*ec779b8eSAndroid Build Coastguard Worker if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
4110*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
4111*ec779b8eSAndroid Build Coastguard Worker }
4112*ec779b8eSAndroid Build Coastguard Worker }
4113*ec779b8eSAndroid Build Coastguard Worker }
4114*ec779b8eSAndroid Build Coastguard Worker
decreaseSoundRef()4115*ec779b8eSAndroid Build Coastguard Worker void CameraService::decreaseSoundRef() {
4116*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mSoundLock);
4117*ec779b8eSAndroid Build Coastguard Worker LOG1("CameraService::decreaseSoundRef ref=%d", mSoundRef);
4118*ec779b8eSAndroid Build Coastguard Worker if (--mSoundRef) return;
4119*ec779b8eSAndroid Build Coastguard Worker
4120*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < NUM_SOUNDS; i++) {
4121*ec779b8eSAndroid Build Coastguard Worker if (mSoundPlayer[i] != 0) {
4122*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[i]->disconnect();
4123*ec779b8eSAndroid Build Coastguard Worker mSoundPlayer[i].clear();
4124*ec779b8eSAndroid Build Coastguard Worker }
4125*ec779b8eSAndroid Build Coastguard Worker }
4126*ec779b8eSAndroid Build Coastguard Worker }
4127*ec779b8eSAndroid Build Coastguard Worker
playSound(sound_kind kind)4128*ec779b8eSAndroid Build Coastguard Worker void CameraService::playSound(sound_kind kind) {
4129*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4130*ec779b8eSAndroid Build Coastguard Worker
4131*ec779b8eSAndroid Build Coastguard Worker LOG1("playSound(%d)", kind);
4132*ec779b8eSAndroid Build Coastguard Worker if (kind < 0 || kind >= NUM_SOUNDS) {
4133*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid sound id requested: %d", __FUNCTION__, kind);
4134*ec779b8eSAndroid Build Coastguard Worker return;
4135*ec779b8eSAndroid Build Coastguard Worker }
4136*ec779b8eSAndroid Build Coastguard Worker
4137*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mSoundLock);
4138*ec779b8eSAndroid Build Coastguard Worker loadSoundLocked(kind);
4139*ec779b8eSAndroid Build Coastguard Worker sp<MediaPlayer> player = mSoundPlayer[kind];
4140*ec779b8eSAndroid Build Coastguard Worker if (player != 0) {
4141*ec779b8eSAndroid Build Coastguard Worker player->seekTo(0);
4142*ec779b8eSAndroid Build Coastguard Worker player->start();
4143*ec779b8eSAndroid Build Coastguard Worker }
4144*ec779b8eSAndroid Build Coastguard Worker }
4145*ec779b8eSAndroid Build Coastguard Worker
4146*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4147*ec779b8eSAndroid Build Coastguard Worker
Client(const sp<CameraService> & cameraService,const sp<ICameraClient> & cameraClient,std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,const AttributionSourceState & clientAttribution,int callingPid,bool systemNativeClient,const std::string & cameraIdStr,int api1CameraId,int cameraFacing,int sensorOrientation,int servicePid,int rotationOverride,bool sharedMode)4148*ec779b8eSAndroid Build Coastguard Worker CameraService::Client::Client(
4149*ec779b8eSAndroid Build Coastguard Worker const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient,
4150*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
4151*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int callingPid, bool systemNativeClient,
4152*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraIdStr, int api1CameraId, int cameraFacing, int sensorOrientation,
4153*ec779b8eSAndroid Build Coastguard Worker int servicePid, int rotationOverride, bool sharedMode)
4154*ec779b8eSAndroid Build Coastguard Worker : CameraService::BasicClient(cameraService, IInterface::asBinder(cameraClient),
4155*ec779b8eSAndroid Build Coastguard Worker attributionAndPermissionUtils, clientAttribution, callingPid,
4156*ec779b8eSAndroid Build Coastguard Worker systemNativeClient, cameraIdStr, cameraFacing, sensorOrientation,
4157*ec779b8eSAndroid Build Coastguard Worker servicePid, rotationOverride, sharedMode),
4158*ec779b8eSAndroid Build Coastguard Worker mCameraId(api1CameraId) {
4159*ec779b8eSAndroid Build Coastguard Worker LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
4160*ec779b8eSAndroid Build Coastguard Worker
4161*ec779b8eSAndroid Build Coastguard Worker mRemoteCallback = cameraClient;
4162*ec779b8eSAndroid Build Coastguard Worker
4163*ec779b8eSAndroid Build Coastguard Worker cameraService->increaseSoundRef();
4164*ec779b8eSAndroid Build Coastguard Worker
4165*ec779b8eSAndroid Build Coastguard Worker LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
4166*ec779b8eSAndroid Build Coastguard Worker }
4167*ec779b8eSAndroid Build Coastguard Worker
4168*ec779b8eSAndroid Build Coastguard Worker // tear down the client
~Client()4169*ec779b8eSAndroid Build Coastguard Worker CameraService::Client::~Client() {
4170*ec779b8eSAndroid Build Coastguard Worker ALOGV("~Client");
4171*ec779b8eSAndroid Build Coastguard Worker mDestructionStarted = true;
4172*ec779b8eSAndroid Build Coastguard Worker
4173*ec779b8eSAndroid Build Coastguard Worker sCameraService->decreaseSoundRef();
4174*ec779b8eSAndroid Build Coastguard Worker // unconditionally disconnect. function is idempotent
4175*ec779b8eSAndroid Build Coastguard Worker Client::disconnect();
4176*ec779b8eSAndroid Build Coastguard Worker }
4177*ec779b8eSAndroid Build Coastguard Worker
4178*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> CameraService::BasicClient::BasicClient::sCameraService;
4179*ec779b8eSAndroid Build Coastguard Worker
BasicClient(const sp<CameraService> & cameraService,const sp<IBinder> & remoteCallback,std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,const AttributionSourceState & clientAttribution,int callingPid,bool nativeClient,const std::string & cameraIdStr,int cameraFacing,int sensorOrientation,int servicePid,int rotationOverride,bool sharedMode)4180*ec779b8eSAndroid Build Coastguard Worker CameraService::BasicClient::BasicClient(
4181*ec779b8eSAndroid Build Coastguard Worker const sp<CameraService>& cameraService, const sp<IBinder>& remoteCallback,
4182*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
4183*ec779b8eSAndroid Build Coastguard Worker const AttributionSourceState& clientAttribution, int callingPid, bool nativeClient,
4184*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraIdStr, int cameraFacing, int sensorOrientation, int servicePid,
4185*ec779b8eSAndroid Build Coastguard Worker int rotationOverride, bool sharedMode)
4186*ec779b8eSAndroid Build Coastguard Worker : AttributionAndPermissionUtilsEncapsulator(attributionAndPermissionUtils),
4187*ec779b8eSAndroid Build Coastguard Worker mDestructionStarted(false),
4188*ec779b8eSAndroid Build Coastguard Worker mCameraIdStr(cameraIdStr),
4189*ec779b8eSAndroid Build Coastguard Worker mCameraFacing(cameraFacing),
4190*ec779b8eSAndroid Build Coastguard Worker mOrientation(sensorOrientation),
4191*ec779b8eSAndroid Build Coastguard Worker mClientAttribution(clientAttribution),
4192*ec779b8eSAndroid Build Coastguard Worker mCallingPid(callingPid),
4193*ec779b8eSAndroid Build Coastguard Worker mSystemNativeClient(nativeClient),
4194*ec779b8eSAndroid Build Coastguard Worker mServicePid(servicePid),
4195*ec779b8eSAndroid Build Coastguard Worker mDisconnected(false),
4196*ec779b8eSAndroid Build Coastguard Worker mUidIsTrusted(false),
4197*ec779b8eSAndroid Build Coastguard Worker mRotationOverride(rotationOverride), mSharedMode(sharedMode),
4198*ec779b8eSAndroid Build Coastguard Worker mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE),
4199*ec779b8eSAndroid Build Coastguard Worker mRemoteBinder(remoteCallback),
4200*ec779b8eSAndroid Build Coastguard Worker mCameraOpen(false),
4201*ec779b8eSAndroid Build Coastguard Worker mCameraStreaming(false) {
4202*ec779b8eSAndroid Build Coastguard Worker if (sCameraService == nullptr) {
4203*ec779b8eSAndroid Build Coastguard Worker sCameraService = cameraService;
4204*ec779b8eSAndroid Build Coastguard Worker }
4205*ec779b8eSAndroid Build Coastguard Worker
4206*ec779b8eSAndroid Build Coastguard Worker // There are 2 scenarios in which a client won't have AppOps operations
4207*ec779b8eSAndroid Build Coastguard Worker // (both scenarios : native clients)
4208*ec779b8eSAndroid Build Coastguard Worker // 1) It's an system native client*, the package name will be empty
4209*ec779b8eSAndroid Build Coastguard Worker // and it will return from this function in the previous if condition
4210*ec779b8eSAndroid Build Coastguard Worker // (This is the same as the previously existing behavior).
4211*ec779b8eSAndroid Build Coastguard Worker // 2) It is a system native client, but its package name has been
4212*ec779b8eSAndroid Build Coastguard Worker // modified for debugging, however it still must not use AppOps since
4213*ec779b8eSAndroid Build Coastguard Worker // the package name is not a real one.
4214*ec779b8eSAndroid Build Coastguard Worker //
4215*ec779b8eSAndroid Build Coastguard Worker // * system native client - native client with UID < AID_APP_START. It
4216*ec779b8eSAndroid Build Coastguard Worker // doesn't exclude clients not on the system partition.
4217*ec779b8eSAndroid Build Coastguard Worker if (!mSystemNativeClient) {
4218*ec779b8eSAndroid Build Coastguard Worker mAppOpsManager = std::make_unique<AppOpsManager>();
4219*ec779b8eSAndroid Build Coastguard Worker }
4220*ec779b8eSAndroid Build Coastguard Worker
4221*ec779b8eSAndroid Build Coastguard Worker mUidIsTrusted = isTrustedCallingUid(mClientAttribution.uid);
4222*ec779b8eSAndroid Build Coastguard Worker }
4223*ec779b8eSAndroid Build Coastguard Worker
~BasicClient()4224*ec779b8eSAndroid Build Coastguard Worker CameraService::BasicClient::~BasicClient() {
4225*ec779b8eSAndroid Build Coastguard Worker ALOGV("~BasicClient");
4226*ec779b8eSAndroid Build Coastguard Worker mDestructionStarted = true;
4227*ec779b8eSAndroid Build Coastguard Worker }
4228*ec779b8eSAndroid Build Coastguard Worker
disconnect()4229*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraService::BasicClient::disconnect() {
4230*ec779b8eSAndroid Build Coastguard Worker binder::Status res = Status::ok();
4231*ec779b8eSAndroid Build Coastguard Worker if (mDisconnected) {
4232*ec779b8eSAndroid Build Coastguard Worker return res;
4233*ec779b8eSAndroid Build Coastguard Worker }
4234*ec779b8eSAndroid Build Coastguard Worker mDisconnected = true;
4235*ec779b8eSAndroid Build Coastguard Worker
4236*ec779b8eSAndroid Build Coastguard Worker sCameraService->removeByClient(this);
4237*ec779b8eSAndroid Build Coastguard Worker sCameraService->logDisconnected(mCameraIdStr, mCallingPid, getPackageName());
4238*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client() || !mSharedMode || (mSharedMode &&
4239*ec779b8eSAndroid Build Coastguard Worker sCameraService->isOnlyClient(this))) {
4240*ec779b8eSAndroid Build Coastguard Worker // Remove the HAL reference for the camera in either of the following scenarios :
4241*ec779b8eSAndroid Build Coastguard Worker // 1) Camera was opened in non-shared mode.
4242*ec779b8eSAndroid Build Coastguard Worker // 2) Camera was opened in shared mode and this is the last client using
4243*ec779b8eSAndroid Build Coastguard Worker // the camera which is being disconnected
4244*ec779b8eSAndroid Build Coastguard Worker sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
4245*ec779b8eSAndroid Build Coastguard Worker mCameraIdStr);
4246*ec779b8eSAndroid Build Coastguard Worker }
4247*ec779b8eSAndroid Build Coastguard Worker
4248*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> remote = getRemote();
4249*ec779b8eSAndroid Build Coastguard Worker if (remote != nullptr) {
4250*ec779b8eSAndroid Build Coastguard Worker remote->unlinkToDeath(sCameraService);
4251*ec779b8eSAndroid Build Coastguard Worker }
4252*ec779b8eSAndroid Build Coastguard Worker
4253*ec779b8eSAndroid Build Coastguard Worker notifyCameraClosing();
4254*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client() || !mSharedMode || (mSharedMode &&
4255*ec779b8eSAndroid Build Coastguard Worker sCameraService->isOnlyClient(this))) {
4256*ec779b8eSAndroid Build Coastguard Worker // Notify flashlight that a camera device is closed.
4257*ec779b8eSAndroid Build Coastguard Worker sCameraService->mFlashlight->deviceClosed(mCameraIdStr);
4258*ec779b8eSAndroid Build Coastguard Worker }
4259*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.c_str(),
4260*ec779b8eSAndroid Build Coastguard Worker mCallingPid);
4261*ec779b8eSAndroid Build Coastguard Worker
4262*ec779b8eSAndroid Build Coastguard Worker // client shouldn't be able to call into us anymore
4263*ec779b8eSAndroid Build Coastguard Worker mCallingPid = 0;
4264*ec779b8eSAndroid Build Coastguard Worker
4265*ec779b8eSAndroid Build Coastguard Worker const auto& mActivityManager = getActivityManager();
4266*ec779b8eSAndroid Build Coastguard Worker if (mActivityManager) {
4267*ec779b8eSAndroid Build Coastguard Worker mActivityManager->logFgsApiEnd(LOG_FGS_CAMERA_API,
4268*ec779b8eSAndroid Build Coastguard Worker getCallingUid(),
4269*ec779b8eSAndroid Build Coastguard Worker getCallingPid());
4270*ec779b8eSAndroid Build Coastguard Worker }
4271*ec779b8eSAndroid Build Coastguard Worker
4272*ec779b8eSAndroid Build Coastguard Worker return res;
4273*ec779b8eSAndroid Build Coastguard Worker }
4274*ec779b8eSAndroid Build Coastguard Worker
dump(int,const Vector<String16> &)4275*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::dump(int, const Vector<String16>&) {
4276*ec779b8eSAndroid Build Coastguard Worker // No dumping of clients directly over Binder,
4277*ec779b8eSAndroid Build Coastguard Worker // must go through CameraService::dump
4278*ec779b8eSAndroid Build Coastguard Worker android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403",
4279*ec779b8eSAndroid Build Coastguard Worker getCallingUid(), NULL, 0);
4280*ec779b8eSAndroid Build Coastguard Worker return OK;
4281*ec779b8eSAndroid Build Coastguard Worker }
4282*ec779b8eSAndroid Build Coastguard Worker
startWatchingTags(const std::string &,int)4283*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::startWatchingTags(const std::string&, int) {
4284*ec779b8eSAndroid Build Coastguard Worker // Can't watch tags directly, must go through CameraService::startWatchingTags
4285*ec779b8eSAndroid Build Coastguard Worker return OK;
4286*ec779b8eSAndroid Build Coastguard Worker }
4287*ec779b8eSAndroid Build Coastguard Worker
stopWatchingTags(int)4288*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::stopWatchingTags(int) {
4289*ec779b8eSAndroid Build Coastguard Worker // Can't watch tags directly, must go through CameraService::stopWatchingTags
4290*ec779b8eSAndroid Build Coastguard Worker return OK;
4291*ec779b8eSAndroid Build Coastguard Worker }
4292*ec779b8eSAndroid Build Coastguard Worker
dumpWatchedEventsToVector(std::vector<std::string> &)4293*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::dumpWatchedEventsToVector(std::vector<std::string> &) {
4294*ec779b8eSAndroid Build Coastguard Worker // Can't watch tags directly, must go through CameraService::dumpWatchedEventsToVector
4295*ec779b8eSAndroid Build Coastguard Worker return OK;
4296*ec779b8eSAndroid Build Coastguard Worker }
4297*ec779b8eSAndroid Build Coastguard Worker
getPackageName() const4298*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::BasicClient::getPackageName() const {
4299*ec779b8eSAndroid Build Coastguard Worker return mClientAttribution.packageName.value_or(kUnknownPackageName);
4300*ec779b8eSAndroid Build Coastguard Worker }
4301*ec779b8eSAndroid Build Coastguard Worker
getCameraFacing() const4302*ec779b8eSAndroid Build Coastguard Worker int CameraService::BasicClient::getCameraFacing() const {
4303*ec779b8eSAndroid Build Coastguard Worker return mCameraFacing;
4304*ec779b8eSAndroid Build Coastguard Worker }
4305*ec779b8eSAndroid Build Coastguard Worker
getCameraOrientation() const4306*ec779b8eSAndroid Build Coastguard Worker int CameraService::BasicClient::getCameraOrientation() const {
4307*ec779b8eSAndroid Build Coastguard Worker return mOrientation;
4308*ec779b8eSAndroid Build Coastguard Worker }
4309*ec779b8eSAndroid Build Coastguard Worker
getClientCallingPid() const4310*ec779b8eSAndroid Build Coastguard Worker int CameraService::BasicClient::getClientCallingPid() const {
4311*ec779b8eSAndroid Build Coastguard Worker return mCallingPid;
4312*ec779b8eSAndroid Build Coastguard Worker }
4313*ec779b8eSAndroid Build Coastguard Worker
getClientUid() const4314*ec779b8eSAndroid Build Coastguard Worker uid_t CameraService::BasicClient::getClientUid() const {
4315*ec779b8eSAndroid Build Coastguard Worker return mClientAttribution.uid;
4316*ec779b8eSAndroid Build Coastguard Worker }
4317*ec779b8eSAndroid Build Coastguard Worker
getClientAttributionTag() const4318*ec779b8eSAndroid Build Coastguard Worker const std::optional<std::string>& CameraService::BasicClient::getClientAttributionTag() const {
4319*ec779b8eSAndroid Build Coastguard Worker return mClientAttribution.attributionTag;
4320*ec779b8eSAndroid Build Coastguard Worker }
4321*ec779b8eSAndroid Build Coastguard Worker
canCastToApiClient(apiLevel level) const4322*ec779b8eSAndroid Build Coastguard Worker bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
4323*ec779b8eSAndroid Build Coastguard Worker // Defaults to API2.
4324*ec779b8eSAndroid Build Coastguard Worker return level == API_2;
4325*ec779b8eSAndroid Build Coastguard Worker }
4326*ec779b8eSAndroid Build Coastguard Worker
setAudioRestriction(int32_t mode)4327*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::setAudioRestriction(int32_t mode) {
4328*ec779b8eSAndroid Build Coastguard Worker {
4329*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mAudioRestrictionLock);
4330*ec779b8eSAndroid Build Coastguard Worker mAudioRestriction = mode;
4331*ec779b8eSAndroid Build Coastguard Worker }
4332*ec779b8eSAndroid Build Coastguard Worker sCameraService->updateAudioRestriction();
4333*ec779b8eSAndroid Build Coastguard Worker return OK;
4334*ec779b8eSAndroid Build Coastguard Worker }
4335*ec779b8eSAndroid Build Coastguard Worker
getServiceAudioRestriction() const4336*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::BasicClient::getServiceAudioRestriction() const {
4337*ec779b8eSAndroid Build Coastguard Worker return sCameraService->updateAudioRestriction();
4338*ec779b8eSAndroid Build Coastguard Worker }
4339*ec779b8eSAndroid Build Coastguard Worker
getAudioRestriction() const4340*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::BasicClient::getAudioRestriction() const {
4341*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mAudioRestrictionLock);
4342*ec779b8eSAndroid Build Coastguard Worker return mAudioRestriction;
4343*ec779b8eSAndroid Build Coastguard Worker }
4344*ec779b8eSAndroid Build Coastguard Worker
isValidAudioRestriction(int32_t mode)4345*ec779b8eSAndroid Build Coastguard Worker bool CameraService::BasicClient::isValidAudioRestriction(int32_t mode) {
4346*ec779b8eSAndroid Build Coastguard Worker switch (mode) {
4347*ec779b8eSAndroid Build Coastguard Worker case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE:
4348*ec779b8eSAndroid Build Coastguard Worker case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_VIBRATION:
4349*ec779b8eSAndroid Build Coastguard Worker case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_VIBRATION_SOUND:
4350*ec779b8eSAndroid Build Coastguard Worker return true;
4351*ec779b8eSAndroid Build Coastguard Worker default:
4352*ec779b8eSAndroid Build Coastguard Worker return false;
4353*ec779b8eSAndroid Build Coastguard Worker }
4354*ec779b8eSAndroid Build Coastguard Worker }
4355*ec779b8eSAndroid Build Coastguard Worker
handlePermissionResult(PermissionChecker::PermissionResult result)4356*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::handlePermissionResult(
4357*ec779b8eSAndroid Build Coastguard Worker PermissionChecker::PermissionResult result) {
4358*ec779b8eSAndroid Build Coastguard Worker if (result == PermissionChecker::PERMISSION_HARD_DENIED) {
4359*ec779b8eSAndroid Build Coastguard Worker ALOGI("Camera %s: Access for \"%s\" has been revoked", mCameraIdStr.c_str(),
4360*ec779b8eSAndroid Build Coastguard Worker getPackageName().c_str());
4361*ec779b8eSAndroid Build Coastguard Worker return PERMISSION_DENIED;
4362*ec779b8eSAndroid Build Coastguard Worker } else if (!mUidIsTrusted && result == PermissionChecker::PERMISSION_SOFT_DENIED) {
4363*ec779b8eSAndroid Build Coastguard Worker // If the calling Uid is trusted (a native service), the AppOpsManager/PermissionChecker
4364*ec779b8eSAndroid Build Coastguard Worker // could return MODE_IGNORED/PERMISSION_SOFT_DENIED. Do not treat such case as error.
4365*ec779b8eSAndroid Build Coastguard Worker bool isUidActive =
4366*ec779b8eSAndroid Build Coastguard Worker sCameraService->mUidPolicy->isUidActive(getClientUid(), getPackageName());
4367*ec779b8eSAndroid Build Coastguard Worker
4368*ec779b8eSAndroid Build Coastguard Worker bool isCameraPrivacyEnabled;
4369*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_privacy_allowlist()) {
4370*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled(
4371*ec779b8eSAndroid Build Coastguard Worker toString16(getPackageName()), std::string(), mCallingPid, getClientUid());
4372*ec779b8eSAndroid Build Coastguard Worker } else {
4373*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled =
4374*ec779b8eSAndroid Build Coastguard Worker sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled();
4375*ec779b8eSAndroid Build Coastguard Worker }
4376*ec779b8eSAndroid Build Coastguard Worker // We don't want to return EACCESS if the CameraPrivacy is enabled.
4377*ec779b8eSAndroid Build Coastguard Worker // We prefer to successfully open the camera and perform camera muting
4378*ec779b8eSAndroid Build Coastguard Worker // or blocking in connectHelper as handleAppOpMode can be called before the
4379*ec779b8eSAndroid Build Coastguard Worker // connection has been fully established and at that time camera muting
4380*ec779b8eSAndroid Build Coastguard Worker // capabilities are unknown.
4381*ec779b8eSAndroid Build Coastguard Worker if (!isUidActive || !isCameraPrivacyEnabled) {
4382*ec779b8eSAndroid Build Coastguard Worker ALOGI("Camera %s: Access for \"%s\" has been restricted."
4383*ec779b8eSAndroid Build Coastguard Worker "uid active: %s, privacy enabled: %s",
4384*ec779b8eSAndroid Build Coastguard Worker mCameraIdStr.c_str(), getPackageName().c_str(), isUidActive ? "true" : "false",
4385*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled ? "true" : "false");
4386*ec779b8eSAndroid Build Coastguard Worker // Return the same error as for device policy manager rejection
4387*ec779b8eSAndroid Build Coastguard Worker return -EACCES;
4388*ec779b8eSAndroid Build Coastguard Worker }
4389*ec779b8eSAndroid Build Coastguard Worker }
4390*ec779b8eSAndroid Build Coastguard Worker return OK;
4391*ec779b8eSAndroid Build Coastguard Worker }
4392*ec779b8eSAndroid Build Coastguard Worker
handleAppOpMode(int32_t mode)4393*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) {
4394*ec779b8eSAndroid Build Coastguard Worker return handlePermissionResult(appOpModeToPermissionResult(mode));
4395*ec779b8eSAndroid Build Coastguard Worker }
4396*ec779b8eSAndroid Build Coastguard Worker
notifyCameraOpening()4397*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::notifyCameraOpening() {
4398*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4399*ec779b8eSAndroid Build Coastguard Worker
4400*ec779b8eSAndroid Build Coastguard Worker // Don't start watching until we're streaming when using permissionChecker for data delivery
4401*ec779b8eSAndroid Build Coastguard Worker if (!flags::data_delivery_permission_checks()) {
4402*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: Start camera ops, package name = %s, client UID = %d", __FUNCTION__,
4403*ec779b8eSAndroid Build Coastguard Worker getPackageName().c_str(), getClientUid());
4404*ec779b8eSAndroid Build Coastguard Worker
4405*ec779b8eSAndroid Build Coastguard Worker if (mAppOpsManager != nullptr) {
4406*ec779b8eSAndroid Build Coastguard Worker // Notify app ops that the camera is not available
4407*ec779b8eSAndroid Build Coastguard Worker mOpsCallback = new OpsCallback(this);
4408*ec779b8eSAndroid Build Coastguard Worker
4409*ec779b8eSAndroid Build Coastguard Worker mAppOpsManager->startWatchingMode(
4410*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::OP_CAMERA, toString16(getPackageName()),
4411*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::WATCH_FOREGROUND_CHANGES, mOpsCallback);
4412*ec779b8eSAndroid Build Coastguard Worker
4413*ec779b8eSAndroid Build Coastguard Worker // Just check for camera access here on open - delay startOp until
4414*ec779b8eSAndroid Build Coastguard Worker // camera frames start streaming in startCameraStreamingOps
4415*ec779b8eSAndroid Build Coastguard Worker int32_t mode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, getClientUid(),
4416*ec779b8eSAndroid Build Coastguard Worker toString16(getPackageName()));
4417*ec779b8eSAndroid Build Coastguard Worker status_t res = handleAppOpMode(mode);
4418*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
4419*ec779b8eSAndroid Build Coastguard Worker return res;
4420*ec779b8eSAndroid Build Coastguard Worker }
4421*ec779b8eSAndroid Build Coastguard Worker }
4422*ec779b8eSAndroid Build Coastguard Worker } else {
4423*ec779b8eSAndroid Build Coastguard Worker // TODO: Remove when removing the data_delivery_permission_checks flag
4424*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: Bypassing checkOp for uid %d", __FUNCTION__, getClientUid());
4425*ec779b8eSAndroid Build Coastguard Worker }
4426*ec779b8eSAndroid Build Coastguard Worker
4427*ec779b8eSAndroid Build Coastguard Worker mCameraOpen = true;
4428*ec779b8eSAndroid Build Coastguard Worker
4429*ec779b8eSAndroid Build Coastguard Worker // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
4430*ec779b8eSAndroid Build Coastguard Worker sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
4431*ec779b8eSAndroid Build Coastguard Worker
4432*ec779b8eSAndroid Build Coastguard Worker sCameraService->mUidPolicy->registerMonitorUid(getClientUid(), /*openCamera*/ true);
4433*ec779b8eSAndroid Build Coastguard Worker
4434*ec779b8eSAndroid Build Coastguard Worker // Notify listeners of camera open/close status
4435*ec779b8eSAndroid Build Coastguard Worker sCameraService->updateOpenCloseStatus(mCameraIdStr, true /*open*/, getPackageName(),
4436*ec779b8eSAndroid Build Coastguard Worker mSharedMode);
4437*ec779b8eSAndroid Build Coastguard Worker
4438*ec779b8eSAndroid Build Coastguard Worker return OK;
4439*ec779b8eSAndroid Build Coastguard Worker }
4440*ec779b8eSAndroid Build Coastguard Worker
startCameraStreamingOps()4441*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::startCameraStreamingOps() {
4442*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4443*ec779b8eSAndroid Build Coastguard Worker
4444*ec779b8eSAndroid Build Coastguard Worker if (!mCameraOpen) {
4445*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__);
4446*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
4447*ec779b8eSAndroid Build Coastguard Worker }
4448*ec779b8eSAndroid Build Coastguard Worker
4449*ec779b8eSAndroid Build Coastguard Worker if (mCameraStreaming) {
4450*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Streaming already active!", __FUNCTION__);
4451*ec779b8eSAndroid Build Coastguard Worker return OK;
4452*ec779b8eSAndroid Build Coastguard Worker }
4453*ec779b8eSAndroid Build Coastguard Worker
4454*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Start camera streaming ops, package name = %s, client UID = %d", __FUNCTION__,
4455*ec779b8eSAndroid Build Coastguard Worker getPackageName().c_str(), getClientUid());
4456*ec779b8eSAndroid Build Coastguard Worker
4457*ec779b8eSAndroid Build Coastguard Worker if (mAppOpsManager != nullptr) {
4458*ec779b8eSAndroid Build Coastguard Worker if (flags::data_delivery_permission_checks()) {
4459*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: Start data delivery for uid %d", __FUNCTION__, getClientUid());
4460*ec779b8eSAndroid Build Coastguard Worker
4461*ec779b8eSAndroid Build Coastguard Worker const PermissionChecker::PermissionResult result =
4462*ec779b8eSAndroid Build Coastguard Worker checkPermissionsForCameraForStartDataDelivery(mCameraIdStr, mClientAttribution);
4463*ec779b8eSAndroid Build Coastguard Worker status_t res = handlePermissionResult(result);
4464*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
4465*ec779b8eSAndroid Build Coastguard Worker return res;
4466*ec779b8eSAndroid Build Coastguard Worker }
4467*ec779b8eSAndroid Build Coastguard Worker
4468*ec779b8eSAndroid Build Coastguard Worker mOpsCallback = new OpsCallback(this);
4469*ec779b8eSAndroid Build Coastguard Worker std::for_each(AttrSourceItr{mClientAttribution}, AttrSourceItr::end(),
4470*ec779b8eSAndroid Build Coastguard Worker [&](const auto& attr) {
4471*ec779b8eSAndroid Build Coastguard Worker mAppOpsManager->startWatchingMode(
4472*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::OP_CAMERA,
4473*ec779b8eSAndroid Build Coastguard Worker toString16(attr.packageName.value_or("")),
4474*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::WATCH_FOREGROUND_CHANGES, mOpsCallback);
4475*ec779b8eSAndroid Build Coastguard Worker });
4476*ec779b8eSAndroid Build Coastguard Worker } else {
4477*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: startOp for uid %d", __FUNCTION__, getClientUid());
4478*ec779b8eSAndroid Build Coastguard Worker int32_t mode = mAppOpsManager->startOpNoThrow(
4479*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::OP_CAMERA, getClientUid(), toString16(getPackageName()),
4480*ec779b8eSAndroid Build Coastguard Worker /*startIfModeDefault*/ false, toString16(getClientAttributionTag()),
4481*ec779b8eSAndroid Build Coastguard Worker toString16("start camera ") + toString16(mCameraIdStr));
4482*ec779b8eSAndroid Build Coastguard Worker status_t res = handleAppOpMode(mode);
4483*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
4484*ec779b8eSAndroid Build Coastguard Worker return res;
4485*ec779b8eSAndroid Build Coastguard Worker }
4486*ec779b8eSAndroid Build Coastguard Worker }
4487*ec779b8eSAndroid Build Coastguard Worker }
4488*ec779b8eSAndroid Build Coastguard Worker
4489*ec779b8eSAndroid Build Coastguard Worker mCameraStreaming = true;
4490*ec779b8eSAndroid Build Coastguard Worker
4491*ec779b8eSAndroid Build Coastguard Worker return OK;
4492*ec779b8eSAndroid Build Coastguard Worker }
4493*ec779b8eSAndroid Build Coastguard Worker
noteAppOp()4494*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::noteAppOp() {
4495*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4496*ec779b8eSAndroid Build Coastguard Worker
4497*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Start camera noteAppOp, package name = %s, client UID = %d", __FUNCTION__,
4498*ec779b8eSAndroid Build Coastguard Worker getPackageName().c_str(), getClientUid());
4499*ec779b8eSAndroid Build Coastguard Worker
4500*ec779b8eSAndroid Build Coastguard Worker // noteAppOp is only used for when camera mute is not supported, in order
4501*ec779b8eSAndroid Build Coastguard Worker // to trigger the sensor privacy "Unblock" dialog
4502*ec779b8eSAndroid Build Coastguard Worker if (flags::data_delivery_permission_checks()) {
4503*ec779b8eSAndroid Build Coastguard Worker // Ignore the result, since we're only triggering the dialog
4504*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: Check data delivery permissions for uid %d", __FUNCTION__, getClientUid());
4505*ec779b8eSAndroid Build Coastguard Worker hasPermissionsForCameraForDataDelivery(std::string(), mClientAttribution);
4506*ec779b8eSAndroid Build Coastguard Worker } else if (mAppOpsManager != nullptr) {
4507*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: noteOp for uid %d", __FUNCTION__, getClientUid());
4508*ec779b8eSAndroid Build Coastguard Worker int32_t mode = mAppOpsManager->noteOp(
4509*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::OP_CAMERA, getClientUid(), toString16(getPackageName()),
4510*ec779b8eSAndroid Build Coastguard Worker toString16(getClientAttributionTag()),
4511*ec779b8eSAndroid Build Coastguard Worker toString16("start camera ") + toString16(mCameraIdStr));
4512*ec779b8eSAndroid Build Coastguard Worker status_t res = handleAppOpMode(mode);
4513*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
4514*ec779b8eSAndroid Build Coastguard Worker return res;
4515*ec779b8eSAndroid Build Coastguard Worker }
4516*ec779b8eSAndroid Build Coastguard Worker }
4517*ec779b8eSAndroid Build Coastguard Worker
4518*ec779b8eSAndroid Build Coastguard Worker return OK;
4519*ec779b8eSAndroid Build Coastguard Worker }
4520*ec779b8eSAndroid Build Coastguard Worker
finishCameraStreamingOps()4521*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::finishCameraStreamingOps() {
4522*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4523*ec779b8eSAndroid Build Coastguard Worker
4524*ec779b8eSAndroid Build Coastguard Worker if (!mCameraOpen) {
4525*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__);
4526*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
4527*ec779b8eSAndroid Build Coastguard Worker }
4528*ec779b8eSAndroid Build Coastguard Worker if (!mCameraStreaming) {
4529*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Streaming not active!", __FUNCTION__);
4530*ec779b8eSAndroid Build Coastguard Worker return OK;
4531*ec779b8eSAndroid Build Coastguard Worker }
4532*ec779b8eSAndroid Build Coastguard Worker
4533*ec779b8eSAndroid Build Coastguard Worker if (mAppOpsManager != nullptr) {
4534*ec779b8eSAndroid Build Coastguard Worker if (flags::data_delivery_permission_checks()) {
4535*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: finishDataDelivery for uid %d", __FUNCTION__, getClientUid());
4536*ec779b8eSAndroid Build Coastguard Worker finishDataDelivery(mClientAttribution);
4537*ec779b8eSAndroid Build Coastguard Worker
4538*ec779b8eSAndroid Build Coastguard Worker // Stop watching app op changes after stop streaming
4539*ec779b8eSAndroid Build Coastguard Worker if (mOpsCallback != nullptr) {
4540*ec779b8eSAndroid Build Coastguard Worker mAppOpsManager->stopWatchingMode(mOpsCallback);
4541*ec779b8eSAndroid Build Coastguard Worker mOpsCallback.clear();
4542*ec779b8eSAndroid Build Coastguard Worker }
4543*ec779b8eSAndroid Build Coastguard Worker } else {
4544*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: finishOp for uid %d", __FUNCTION__, getClientUid());
4545*ec779b8eSAndroid Build Coastguard Worker mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, getClientUid(),
4546*ec779b8eSAndroid Build Coastguard Worker toString16(getPackageName()),
4547*ec779b8eSAndroid Build Coastguard Worker toString16(getClientAttributionTag()));
4548*ec779b8eSAndroid Build Coastguard Worker }
4549*ec779b8eSAndroid Build Coastguard Worker mCameraStreaming = false;
4550*ec779b8eSAndroid Build Coastguard Worker }
4551*ec779b8eSAndroid Build Coastguard Worker
4552*ec779b8eSAndroid Build Coastguard Worker return OK;
4553*ec779b8eSAndroid Build Coastguard Worker }
4554*ec779b8eSAndroid Build Coastguard Worker
notifyCameraClosing()4555*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::notifyCameraClosing() {
4556*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4557*ec779b8eSAndroid Build Coastguard Worker
4558*ec779b8eSAndroid Build Coastguard Worker if (mCameraStreaming) {
4559*ec779b8eSAndroid Build Coastguard Worker // Make sure we've notified everyone about camera stopping
4560*ec779b8eSAndroid Build Coastguard Worker finishCameraStreamingOps();
4561*ec779b8eSAndroid Build Coastguard Worker }
4562*ec779b8eSAndroid Build Coastguard Worker
4563*ec779b8eSAndroid Build Coastguard Worker // Check if notifyCameraOpening succeeded, and if so, finish the camera op if necessary
4564*ec779b8eSAndroid Build Coastguard Worker if (mCameraOpen) {
4565*ec779b8eSAndroid Build Coastguard Worker mCameraOpen = false;
4566*ec779b8eSAndroid Build Coastguard Worker
4567*ec779b8eSAndroid Build Coastguard Worker // This function is called when a client disconnects. This should
4568*ec779b8eSAndroid Build Coastguard Worker // release the camera, but actually only if it was in a proper
4569*ec779b8eSAndroid Build Coastguard Worker // functional state, i.e. with status NOT_AVAILABLE
4570*ec779b8eSAndroid Build Coastguard Worker std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
4571*ec779b8eSAndroid Build Coastguard Worker StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
4572*ec779b8eSAndroid Build Coastguard Worker
4573*ec779b8eSAndroid Build Coastguard Worker // Transition to PRESENT if the camera is not in either of the rejected states
4574*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client() || !mSharedMode || (mSharedMode
4575*ec779b8eSAndroid Build Coastguard Worker && sCameraService->isOnlyClient(this))) {
4576*ec779b8eSAndroid Build Coastguard Worker sCameraService->updateStatus(StatusInternal::PRESENT,
4577*ec779b8eSAndroid Build Coastguard Worker mCameraIdStr, rejected);
4578*ec779b8eSAndroid Build Coastguard Worker }
4579*ec779b8eSAndroid Build Coastguard Worker }
4580*ec779b8eSAndroid Build Coastguard Worker
4581*ec779b8eSAndroid Build Coastguard Worker // When using the data delivery permission checks, the open state does not involve AppOps
4582*ec779b8eSAndroid Build Coastguard Worker if (!flags::data_delivery_permission_checks()) {
4583*ec779b8eSAndroid Build Coastguard Worker // Always stop watching, even if no camera op is active
4584*ec779b8eSAndroid Build Coastguard Worker if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
4585*ec779b8eSAndroid Build Coastguard Worker mAppOpsManager->stopWatchingMode(mOpsCallback);
4586*ec779b8eSAndroid Build Coastguard Worker }
4587*ec779b8eSAndroid Build Coastguard Worker mOpsCallback.clear();
4588*ec779b8eSAndroid Build Coastguard Worker }
4589*ec779b8eSAndroid Build Coastguard Worker
4590*ec779b8eSAndroid Build Coastguard Worker sCameraService->mUidPolicy->unregisterMonitorUid(getClientUid(), /*closeCamera*/ true);
4591*ec779b8eSAndroid Build Coastguard Worker
4592*ec779b8eSAndroid Build Coastguard Worker // Notify listeners of camera open/close status
4593*ec779b8eSAndroid Build Coastguard Worker sCameraService->updateOpenCloseStatus(mCameraIdStr, false /*open*/, getPackageName(),
4594*ec779b8eSAndroid Build Coastguard Worker mSharedMode);
4595*ec779b8eSAndroid Build Coastguard Worker
4596*ec779b8eSAndroid Build Coastguard Worker return OK;
4597*ec779b8eSAndroid Build Coastguard Worker }
4598*ec779b8eSAndroid Build Coastguard Worker
getUidProcessState(int32_t uid)4599*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::getUidProcessState(int32_t uid) {
4600*ec779b8eSAndroid Build Coastguard Worker const auto& activityManager = getActivityManager();
4601*ec779b8eSAndroid Build Coastguard Worker int32_t procState = ActivityManager::PROCESS_STATE_NONEXISTENT;
4602*ec779b8eSAndroid Build Coastguard Worker if (activityManager != nullptr) {
4603*ec779b8eSAndroid Build Coastguard Worker procState = activityManager->getUidProcessState(uid, toString16(kServiceName));
4604*ec779b8eSAndroid Build Coastguard Worker } else {
4605*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: getActivityManager returned nullptr.", __FUNCTION__);
4606*ec779b8eSAndroid Build Coastguard Worker }
4607*ec779b8eSAndroid Build Coastguard Worker return procState;
4608*ec779b8eSAndroid Build Coastguard Worker }
4609*ec779b8eSAndroid Build Coastguard Worker
opChanged(int32_t op,const String16 &)4610*ec779b8eSAndroid Build Coastguard Worker void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
4611*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4612*ec779b8eSAndroid Build Coastguard Worker if (mAppOpsManager == nullptr) {
4613*ec779b8eSAndroid Build Coastguard Worker return;
4614*ec779b8eSAndroid Build Coastguard Worker }
4615*ec779b8eSAndroid Build Coastguard Worker // TODO : add offline camera session case
4616*ec779b8eSAndroid Build Coastguard Worker if (op != AppOpsManager::OP_CAMERA) {
4617*ec779b8eSAndroid Build Coastguard Worker ALOGW("Unexpected app ops notification received: %d", op);
4618*ec779b8eSAndroid Build Coastguard Worker return;
4619*ec779b8eSAndroid Build Coastguard Worker }
4620*ec779b8eSAndroid Build Coastguard Worker
4621*ec779b8eSAndroid Build Coastguard Worker PermissionChecker::PermissionResult res;
4622*ec779b8eSAndroid Build Coastguard Worker if (flags::data_delivery_permission_checks()) {
4623*ec779b8eSAndroid Build Coastguard Worker int32_t appOpMode = AppOpsManager::MODE_ALLOWED;
4624*ec779b8eSAndroid Build Coastguard Worker std::for_each(AttrSourceItr{mClientAttribution}, AttrSourceItr::end(),
4625*ec779b8eSAndroid Build Coastguard Worker [&](const auto& attr) {
4626*ec779b8eSAndroid Build Coastguard Worker appOpMode = std::max(appOpMode, mAppOpsManager->checkOp(
4627*ec779b8eSAndroid Build Coastguard Worker AppOpsManager::OP_CAMERA, attr.uid,
4628*ec779b8eSAndroid Build Coastguard Worker toString16(attr.packageName.value_or(""))));
4629*ec779b8eSAndroid Build Coastguard Worker });
4630*ec779b8eSAndroid Build Coastguard Worker ALOGV("checkOp returns: %d, %s ", res,
4631*ec779b8eSAndroid Build Coastguard Worker appOpMode == AppOpsManager::MODE_ALLOWED ? "ALLOWED"
4632*ec779b8eSAndroid Build Coastguard Worker : appOpMode == AppOpsManager::MODE_IGNORED ? "IGNORED"
4633*ec779b8eSAndroid Build Coastguard Worker : appOpMode == AppOpsManager::MODE_ERRORED ? "ERRORED"
4634*ec779b8eSAndroid Build Coastguard Worker : "UNKNOWN");
4635*ec779b8eSAndroid Build Coastguard Worker res = appOpModeToPermissionResult(appOpMode);
4636*ec779b8eSAndroid Build Coastguard Worker } else {
4637*ec779b8eSAndroid Build Coastguard Worker int32_t appOpMode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, getClientUid(),
4638*ec779b8eSAndroid Build Coastguard Worker toString16(getPackageName()));
4639*ec779b8eSAndroid Build Coastguard Worker ALOGV("checkOp returns: %d, %s ", res,
4640*ec779b8eSAndroid Build Coastguard Worker appOpMode == AppOpsManager::MODE_ALLOWED ? "ALLOWED"
4641*ec779b8eSAndroid Build Coastguard Worker : appOpMode == AppOpsManager::MODE_IGNORED ? "IGNORED"
4642*ec779b8eSAndroid Build Coastguard Worker : appOpMode == AppOpsManager::MODE_ERRORED ? "ERRORED"
4643*ec779b8eSAndroid Build Coastguard Worker : "UNKNOWN");
4644*ec779b8eSAndroid Build Coastguard Worker res = appOpModeToPermissionResult(appOpMode);
4645*ec779b8eSAndroid Build Coastguard Worker }
4646*ec779b8eSAndroid Build Coastguard Worker
4647*ec779b8eSAndroid Build Coastguard Worker if (res == PermissionChecker::PERMISSION_HARD_DENIED) {
4648*ec779b8eSAndroid Build Coastguard Worker ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.c_str(),
4649*ec779b8eSAndroid Build Coastguard Worker getPackageName().c_str());
4650*ec779b8eSAndroid Build Coastguard Worker block();
4651*ec779b8eSAndroid Build Coastguard Worker } else if (res == PermissionChecker::PERMISSION_SOFT_DENIED) {
4652*ec779b8eSAndroid Build Coastguard Worker bool isUidActive =
4653*ec779b8eSAndroid Build Coastguard Worker sCameraService->mUidPolicy->isUidActive(getClientUid(), getPackageName());
4654*ec779b8eSAndroid Build Coastguard Worker
4655*ec779b8eSAndroid Build Coastguard Worker // Uid may be active, but not visible to the user (e.g. PROCESS_STATE_FOREGROUND_SERVICE).
4656*ec779b8eSAndroid Build Coastguard Worker // If not visible, but still active, then we want to block instead of muting the camera.
4657*ec779b8eSAndroid Build Coastguard Worker int32_t procState = ActivityManager::PROCESS_STATE_NONEXISTENT;
4658*ec779b8eSAndroid Build Coastguard Worker if (flags::data_delivery_permission_checks()) {
4659*ec779b8eSAndroid Build Coastguard Worker // Use the proc state of the last uid in the chain (ultimately receiving the data)
4660*ec779b8eSAndroid Build Coastguard Worker // when determining whether to mute or block
4661*ec779b8eSAndroid Build Coastguard Worker int32_t uid = -1;
4662*ec779b8eSAndroid Build Coastguard Worker std::for_each(AttrSourceItr{mClientAttribution}, AttrSourceItr::end(),
4663*ec779b8eSAndroid Build Coastguard Worker [&](const auto& attr) {
4664*ec779b8eSAndroid Build Coastguard Worker uid = static_cast<uid_t>(attr.uid);
4665*ec779b8eSAndroid Build Coastguard Worker });
4666*ec779b8eSAndroid Build Coastguard Worker procState = getUidProcessState(uid);
4667*ec779b8eSAndroid Build Coastguard Worker } else if (flags::query_process_state()) {
4668*ec779b8eSAndroid Build Coastguard Worker procState = getUidProcessState(getClientUid());
4669*ec779b8eSAndroid Build Coastguard Worker } else {
4670*ec779b8eSAndroid Build Coastguard Worker procState = sCameraService->mUidPolicy->getProcState(getClientUid());
4671*ec779b8eSAndroid Build Coastguard Worker }
4672*ec779b8eSAndroid Build Coastguard Worker bool isUidVisible = (procState <= ActivityManager::PROCESS_STATE_BOUND_TOP);
4673*ec779b8eSAndroid Build Coastguard Worker
4674*ec779b8eSAndroid Build Coastguard Worker bool isCameraPrivacyEnabled;
4675*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_privacy_allowlist()) {
4676*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled(
4677*ec779b8eSAndroid Build Coastguard Worker toString16(getPackageName()), std::string(), mCallingPid, getClientUid());
4678*ec779b8eSAndroid Build Coastguard Worker } else {
4679*ec779b8eSAndroid Build Coastguard Worker isCameraPrivacyEnabled =
4680*ec779b8eSAndroid Build Coastguard Worker sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled();
4681*ec779b8eSAndroid Build Coastguard Worker }
4682*ec779b8eSAndroid Build Coastguard Worker
4683*ec779b8eSAndroid Build Coastguard Worker ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d"
4684*ec779b8eSAndroid Build Coastguard Worker " isUidVisible %d, isCameraPrivacyEnabled %d procState %d",
4685*ec779b8eSAndroid Build Coastguard Worker mCameraIdStr.c_str(), getPackageName().c_str(), mUidIsTrusted, isUidActive,
4686*ec779b8eSAndroid Build Coastguard Worker isUidVisible, isCameraPrivacyEnabled, procState);
4687*ec779b8eSAndroid Build Coastguard Worker // If the calling Uid is trusted (a native service), or the client Uid is active / visible
4688*ec779b8eSAndroid Build Coastguard Worker // (WAR for b/175320666)the AppOpsManager could return MODE_IGNORED. Do not treat such
4689*ec779b8eSAndroid Build Coastguard Worker // cases as error.
4690*ec779b8eSAndroid Build Coastguard Worker if (!mUidIsTrusted) {
4691*ec779b8eSAndroid Build Coastguard Worker if (isUidVisible && isCameraPrivacyEnabled && supportsCameraMute()) {
4692*ec779b8eSAndroid Build Coastguard Worker setCameraMute(true);
4693*ec779b8eSAndroid Build Coastguard Worker } else {
4694*ec779b8eSAndroid Build Coastguard Worker block();
4695*ec779b8eSAndroid Build Coastguard Worker }
4696*ec779b8eSAndroid Build Coastguard Worker }
4697*ec779b8eSAndroid Build Coastguard Worker } else if (res == PermissionChecker::PERMISSION_GRANTED) {
4698*ec779b8eSAndroid Build Coastguard Worker setCameraMute(sCameraService->mOverrideCameraMuteMode);
4699*ec779b8eSAndroid Build Coastguard Worker }
4700*ec779b8eSAndroid Build Coastguard Worker }
4701*ec779b8eSAndroid Build Coastguard Worker
block()4702*ec779b8eSAndroid Build Coastguard Worker void CameraService::BasicClient::block() {
4703*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4704*ec779b8eSAndroid Build Coastguard Worker
4705*ec779b8eSAndroid Build Coastguard Worker // Reset the client PID to allow server-initiated disconnect,
4706*ec779b8eSAndroid Build Coastguard Worker // and to prevent further calls by client.
4707*ec779b8eSAndroid Build Coastguard Worker mCallingPid = getCallingPid();
4708*ec779b8eSAndroid Build Coastguard Worker CaptureResultExtras resultExtras; // a dummy result (invalid)
4709*ec779b8eSAndroid Build Coastguard Worker notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras);
4710*ec779b8eSAndroid Build Coastguard Worker disconnect();
4711*ec779b8eSAndroid Build Coastguard Worker }
4712*ec779b8eSAndroid Build Coastguard Worker
isPrimaryClient(bool * isPrimary)4713*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::isPrimaryClient(bool* isPrimary) {
4714*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4715*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client()) {
4716*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
4717*ec779b8eSAndroid Build Coastguard Worker }
4718*ec779b8eSAndroid Build Coastguard Worker
4719*ec779b8eSAndroid Build Coastguard Worker if (!mSharedMode) {
4720*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Invalid operation when camera is not opened in shared mode", __FUNCTION__);
4721*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
4722*ec779b8eSAndroid Build Coastguard Worker }
4723*ec779b8eSAndroid Build Coastguard Worker *isPrimary = mIsPrimaryClient;
4724*ec779b8eSAndroid Build Coastguard Worker return OK;
4725*ec779b8eSAndroid Build Coastguard Worker }
4726*ec779b8eSAndroid Build Coastguard Worker
setPrimaryClient(bool isPrimary)4727*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::BasicClient::setPrimaryClient(bool isPrimary) {
4728*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
4729*ec779b8eSAndroid Build Coastguard Worker
4730*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client()) {
4731*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
4732*ec779b8eSAndroid Build Coastguard Worker }
4733*ec779b8eSAndroid Build Coastguard Worker
4734*ec779b8eSAndroid Build Coastguard Worker if (!mSharedMode) {
4735*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s:Invalid operation when camera is not opened in shared mode", __FUNCTION__);
4736*ec779b8eSAndroid Build Coastguard Worker return INVALID_OPERATION;
4737*ec779b8eSAndroid Build Coastguard Worker }
4738*ec779b8eSAndroid Build Coastguard Worker mIsPrimaryClient = isPrimary;
4739*ec779b8eSAndroid Build Coastguard Worker return OK;
4740*ec779b8eSAndroid Build Coastguard Worker }
4741*ec779b8eSAndroid Build Coastguard Worker
4742*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4743*ec779b8eSAndroid Build Coastguard Worker
notifyError(int32_t errorCode,const CaptureResultExtras & resultExtras)4744*ec779b8eSAndroid Build Coastguard Worker void CameraService::Client::notifyError(int32_t errorCode,
4745*ec779b8eSAndroid Build Coastguard Worker [[maybe_unused]] const CaptureResultExtras& resultExtras) {
4746*ec779b8eSAndroid Build Coastguard Worker if (mRemoteCallback != NULL) {
4747*ec779b8eSAndroid Build Coastguard Worker int32_t api1ErrorCode = CAMERA_ERROR_RELEASED;
4748*ec779b8eSAndroid Build Coastguard Worker if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED) {
4749*ec779b8eSAndroid Build Coastguard Worker api1ErrorCode = CAMERA_ERROR_DISABLED;
4750*ec779b8eSAndroid Build Coastguard Worker }
4751*ec779b8eSAndroid Build Coastguard Worker mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, api1ErrorCode, 0);
4752*ec779b8eSAndroid Build Coastguard Worker } else {
4753*ec779b8eSAndroid Build Coastguard Worker ALOGE("mRemoteCallback is NULL!!");
4754*ec779b8eSAndroid Build Coastguard Worker }
4755*ec779b8eSAndroid Build Coastguard Worker }
4756*ec779b8eSAndroid Build Coastguard Worker
4757*ec779b8eSAndroid Build Coastguard Worker // NOTE: function is idempotent
disconnect()4758*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraService::Client::disconnect() {
4759*ec779b8eSAndroid Build Coastguard Worker ALOGV("Client::disconnect");
4760*ec779b8eSAndroid Build Coastguard Worker return BasicClient::disconnect();
4761*ec779b8eSAndroid Build Coastguard Worker }
4762*ec779b8eSAndroid Build Coastguard Worker
canCastToApiClient(apiLevel level) const4763*ec779b8eSAndroid Build Coastguard Worker bool CameraService::Client::canCastToApiClient(apiLevel level) const {
4764*ec779b8eSAndroid Build Coastguard Worker return level == API_1;
4765*ec779b8eSAndroid Build Coastguard Worker }
4766*ec779b8eSAndroid Build Coastguard Worker
OpsCallback(wp<BasicClient> client)4767*ec779b8eSAndroid Build Coastguard Worker CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
4768*ec779b8eSAndroid Build Coastguard Worker mClient(client) {
4769*ec779b8eSAndroid Build Coastguard Worker }
4770*ec779b8eSAndroid Build Coastguard Worker
opChanged(int32_t op,const String16 & packageName)4771*ec779b8eSAndroid Build Coastguard Worker void CameraService::Client::OpsCallback::opChanged(int32_t op,
4772*ec779b8eSAndroid Build Coastguard Worker const String16& packageName) {
4773*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = mClient.promote();
4774*ec779b8eSAndroid Build Coastguard Worker if (client != NULL) {
4775*ec779b8eSAndroid Build Coastguard Worker client->opChanged(op, packageName);
4776*ec779b8eSAndroid Build Coastguard Worker }
4777*ec779b8eSAndroid Build Coastguard Worker }
4778*ec779b8eSAndroid Build Coastguard Worker
4779*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4780*ec779b8eSAndroid Build Coastguard Worker // UidPolicy
4781*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4782*ec779b8eSAndroid Build Coastguard Worker
registerWithActivityManager()4783*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::registerWithActivityManager() {
4784*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4785*ec779b8eSAndroid Build Coastguard Worker int32_t emptyUidArray[] = { };
4786*ec779b8eSAndroid Build Coastguard Worker
4787*ec779b8eSAndroid Build Coastguard Worker if (mRegistered) return;
4788*ec779b8eSAndroid Build Coastguard Worker status_t res = mAm.linkToDeath(this);
4789*ec779b8eSAndroid Build Coastguard Worker mAm.registerUidObserverForUids(this, ActivityManager::UID_OBSERVER_GONE
4790*ec779b8eSAndroid Build Coastguard Worker | ActivityManager::UID_OBSERVER_IDLE
4791*ec779b8eSAndroid Build Coastguard Worker | ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE
4792*ec779b8eSAndroid Build Coastguard Worker | ActivityManager::UID_OBSERVER_PROC_OOM_ADJ,
4793*ec779b8eSAndroid Build Coastguard Worker ActivityManager::PROCESS_STATE_UNKNOWN,
4794*ec779b8eSAndroid Build Coastguard Worker toString16(kServiceName), emptyUidArray, 0, mObserverToken);
4795*ec779b8eSAndroid Build Coastguard Worker if (res == OK) {
4796*ec779b8eSAndroid Build Coastguard Worker mRegistered = true;
4797*ec779b8eSAndroid Build Coastguard Worker ALOGV("UidPolicy: Registered with ActivityManager");
4798*ec779b8eSAndroid Build Coastguard Worker } else {
4799*ec779b8eSAndroid Build Coastguard Worker ALOGE("UidPolicy: Failed to register with ActivityManager: 0x%08x", res);
4800*ec779b8eSAndroid Build Coastguard Worker }
4801*ec779b8eSAndroid Build Coastguard Worker }
4802*ec779b8eSAndroid Build Coastguard Worker
onServiceRegistration(const String16 & name,const sp<IBinder> &)4803*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::onServiceRegistration(const String16& name, const sp<IBinder>&) {
4804*ec779b8eSAndroid Build Coastguard Worker if (name != toString16(kActivityServiceName)) {
4805*ec779b8eSAndroid Build Coastguard Worker return;
4806*ec779b8eSAndroid Build Coastguard Worker }
4807*ec779b8eSAndroid Build Coastguard Worker
4808*ec779b8eSAndroid Build Coastguard Worker registerWithActivityManager();
4809*ec779b8eSAndroid Build Coastguard Worker }
4810*ec779b8eSAndroid Build Coastguard Worker
registerSelf()4811*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::registerSelf() {
4812*ec779b8eSAndroid Build Coastguard Worker // Use check service to see if the activity service is available
4813*ec779b8eSAndroid Build Coastguard Worker // If not available then register for notifications, instead of blocking
4814*ec779b8eSAndroid Build Coastguard Worker // till the service is ready
4815*ec779b8eSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
4816*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = sm->checkService(toString16(kActivityServiceName));
4817*ec779b8eSAndroid Build Coastguard Worker if (!binder) {
4818*ec779b8eSAndroid Build Coastguard Worker sm->registerForNotifications(toString16(kActivityServiceName), this);
4819*ec779b8eSAndroid Build Coastguard Worker } else {
4820*ec779b8eSAndroid Build Coastguard Worker registerWithActivityManager();
4821*ec779b8eSAndroid Build Coastguard Worker }
4822*ec779b8eSAndroid Build Coastguard Worker }
4823*ec779b8eSAndroid Build Coastguard Worker
unregisterSelf()4824*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::unregisterSelf() {
4825*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4826*ec779b8eSAndroid Build Coastguard Worker
4827*ec779b8eSAndroid Build Coastguard Worker mAm.unregisterUidObserver(this);
4828*ec779b8eSAndroid Build Coastguard Worker mAm.unlinkToDeath(this);
4829*ec779b8eSAndroid Build Coastguard Worker mRegistered = false;
4830*ec779b8eSAndroid Build Coastguard Worker mActiveUids.clear();
4831*ec779b8eSAndroid Build Coastguard Worker ALOGV("UidPolicy: Unregistered with ActivityManager");
4832*ec779b8eSAndroid Build Coastguard Worker }
4833*ec779b8eSAndroid Build Coastguard Worker
onUidGone(uid_t uid,bool disabled)4834*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) {
4835*ec779b8eSAndroid Build Coastguard Worker onUidIdle(uid, disabled);
4836*ec779b8eSAndroid Build Coastguard Worker }
4837*ec779b8eSAndroid Build Coastguard Worker
onUidActive(uid_t uid)4838*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::onUidActive(uid_t uid) {
4839*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4840*ec779b8eSAndroid Build Coastguard Worker mActiveUids.insert(uid);
4841*ec779b8eSAndroid Build Coastguard Worker }
4842*ec779b8eSAndroid Build Coastguard Worker
onUidIdle(uid_t uid,bool)4843*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
4844*ec779b8eSAndroid Build Coastguard Worker bool deleted = false;
4845*ec779b8eSAndroid Build Coastguard Worker {
4846*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4847*ec779b8eSAndroid Build Coastguard Worker if (mActiveUids.erase(uid) > 0) {
4848*ec779b8eSAndroid Build Coastguard Worker deleted = true;
4849*ec779b8eSAndroid Build Coastguard Worker }
4850*ec779b8eSAndroid Build Coastguard Worker }
4851*ec779b8eSAndroid Build Coastguard Worker if (deleted) {
4852*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> service = mService.promote();
4853*ec779b8eSAndroid Build Coastguard Worker if (service != nullptr) {
4854*ec779b8eSAndroid Build Coastguard Worker service->blockClientsForUid(uid);
4855*ec779b8eSAndroid Build Coastguard Worker }
4856*ec779b8eSAndroid Build Coastguard Worker }
4857*ec779b8eSAndroid Build Coastguard Worker }
4858*ec779b8eSAndroid Build Coastguard Worker
onUidStateChanged(uid_t uid,int32_t procState,int64_t procStateSeq __unused,int32_t capability __unused)4859*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::onUidStateChanged(uid_t uid, int32_t procState,
4860*ec779b8eSAndroid Build Coastguard Worker int64_t procStateSeq __unused, int32_t capability __unused) {
4861*ec779b8eSAndroid Build Coastguard Worker bool procStateChange = false;
4862*ec779b8eSAndroid Build Coastguard Worker {
4863*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4864*ec779b8eSAndroid Build Coastguard Worker if (mMonitoredUids.find(uid) != mMonitoredUids.end() &&
4865*ec779b8eSAndroid Build Coastguard Worker mMonitoredUids[uid].procState != procState) {
4866*ec779b8eSAndroid Build Coastguard Worker mMonitoredUids[uid].procState = procState;
4867*ec779b8eSAndroid Build Coastguard Worker procStateChange = true;
4868*ec779b8eSAndroid Build Coastguard Worker }
4869*ec779b8eSAndroid Build Coastguard Worker }
4870*ec779b8eSAndroid Build Coastguard Worker
4871*ec779b8eSAndroid Build Coastguard Worker if (procStateChange) {
4872*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> service = mService.promote();
4873*ec779b8eSAndroid Build Coastguard Worker if (service != nullptr) {
4874*ec779b8eSAndroid Build Coastguard Worker service->notifyMonitoredUids();
4875*ec779b8eSAndroid Build Coastguard Worker }
4876*ec779b8eSAndroid Build Coastguard Worker }
4877*ec779b8eSAndroid Build Coastguard Worker }
4878*ec779b8eSAndroid Build Coastguard Worker
4879*ec779b8eSAndroid Build Coastguard Worker /**
4880*ec779b8eSAndroid Build Coastguard Worker * When the OOM adj of the uid owning the camera changes, a different uid waiting on camera
4881*ec779b8eSAndroid Build Coastguard Worker * privileges may take precedence if the owner's new OOM adj is greater than the waiting package.
4882*ec779b8eSAndroid Build Coastguard Worker * Here, we track which monitoredUid has the camera, and track its adj relative to other
4883*ec779b8eSAndroid Build Coastguard Worker * monitoredUids. If it is revised above some other monitoredUid, signal
4884*ec779b8eSAndroid Build Coastguard Worker * onCameraAccessPrioritiesChanged. This only needs to capture the case where there are two
4885*ec779b8eSAndroid Build Coastguard Worker * foreground apps in split screen - state changes will capture all other cases.
4886*ec779b8eSAndroid Build Coastguard Worker */
onUidProcAdjChanged(uid_t uid,int32_t adj)4887*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::onUidProcAdjChanged(uid_t uid, int32_t adj) {
4888*ec779b8eSAndroid Build Coastguard Worker std::unordered_set<uid_t> notifyUidSet;
4889*ec779b8eSAndroid Build Coastguard Worker {
4890*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4891*ec779b8eSAndroid Build Coastguard Worker auto it = mMonitoredUids.find(uid);
4892*ec779b8eSAndroid Build Coastguard Worker
4893*ec779b8eSAndroid Build Coastguard Worker if (it != mMonitoredUids.end()) {
4894*ec779b8eSAndroid Build Coastguard Worker if (it->second.hasCamera) {
4895*ec779b8eSAndroid Build Coastguard Worker for (auto &monitoredUid : mMonitoredUids) {
4896*ec779b8eSAndroid Build Coastguard Worker if (monitoredUid.first != uid && adj > monitoredUid.second.procAdj) {
4897*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: notify uid %d", __FUNCTION__, monitoredUid.first);
4898*ec779b8eSAndroid Build Coastguard Worker notifyUidSet.emplace(monitoredUid.first);
4899*ec779b8eSAndroid Build Coastguard Worker }
4900*ec779b8eSAndroid Build Coastguard Worker }
4901*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: notify uid %d", __FUNCTION__, uid);
4902*ec779b8eSAndroid Build Coastguard Worker notifyUidSet.emplace(uid);
4903*ec779b8eSAndroid Build Coastguard Worker } else {
4904*ec779b8eSAndroid Build Coastguard Worker for (auto &monitoredUid : mMonitoredUids) {
4905*ec779b8eSAndroid Build Coastguard Worker if (monitoredUid.second.hasCamera && adj < monitoredUid.second.procAdj) {
4906*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: notify uid %d", __FUNCTION__, uid);
4907*ec779b8eSAndroid Build Coastguard Worker notifyUidSet.emplace(uid);
4908*ec779b8eSAndroid Build Coastguard Worker }
4909*ec779b8eSAndroid Build Coastguard Worker }
4910*ec779b8eSAndroid Build Coastguard Worker }
4911*ec779b8eSAndroid Build Coastguard Worker it->second.procAdj = adj;
4912*ec779b8eSAndroid Build Coastguard Worker }
4913*ec779b8eSAndroid Build Coastguard Worker }
4914*ec779b8eSAndroid Build Coastguard Worker
4915*ec779b8eSAndroid Build Coastguard Worker if (notifyUidSet.size() > 0) {
4916*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> service = mService.promote();
4917*ec779b8eSAndroid Build Coastguard Worker if (service != nullptr) {
4918*ec779b8eSAndroid Build Coastguard Worker service->notifyMonitoredUids(notifyUidSet);
4919*ec779b8eSAndroid Build Coastguard Worker }
4920*ec779b8eSAndroid Build Coastguard Worker }
4921*ec779b8eSAndroid Build Coastguard Worker }
4922*ec779b8eSAndroid Build Coastguard Worker
4923*ec779b8eSAndroid Build Coastguard Worker /**
4924*ec779b8eSAndroid Build Coastguard Worker * Register a uid for monitoring, and note whether it owns a camera.
4925*ec779b8eSAndroid Build Coastguard Worker */
registerMonitorUid(uid_t uid,bool openCamera)4926*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::registerMonitorUid(uid_t uid, bool openCamera) {
4927*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4928*ec779b8eSAndroid Build Coastguard Worker auto it = mMonitoredUids.find(uid);
4929*ec779b8eSAndroid Build Coastguard Worker if (it != mMonitoredUids.end()) {
4930*ec779b8eSAndroid Build Coastguard Worker it->second.refCount++;
4931*ec779b8eSAndroid Build Coastguard Worker } else {
4932*ec779b8eSAndroid Build Coastguard Worker MonitoredUid monitoredUid;
4933*ec779b8eSAndroid Build Coastguard Worker monitoredUid.procState = ActivityManager::PROCESS_STATE_NONEXISTENT;
4934*ec779b8eSAndroid Build Coastguard Worker monitoredUid.procAdj = resource_policy::UNKNOWN_ADJ;
4935*ec779b8eSAndroid Build Coastguard Worker monitoredUid.refCount = 1;
4936*ec779b8eSAndroid Build Coastguard Worker it = mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid)).first;
4937*ec779b8eSAndroid Build Coastguard Worker status_t res = mAm.addUidToObserver(mObserverToken, toString16(kServiceName), uid);
4938*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
4939*ec779b8eSAndroid Build Coastguard Worker ALOGE("UidPolicy: Failed to add uid to observer: 0x%08x", res);
4940*ec779b8eSAndroid Build Coastguard Worker }
4941*ec779b8eSAndroid Build Coastguard Worker }
4942*ec779b8eSAndroid Build Coastguard Worker
4943*ec779b8eSAndroid Build Coastguard Worker if (openCamera) {
4944*ec779b8eSAndroid Build Coastguard Worker it->second.hasCamera = true;
4945*ec779b8eSAndroid Build Coastguard Worker }
4946*ec779b8eSAndroid Build Coastguard Worker }
4947*ec779b8eSAndroid Build Coastguard Worker
4948*ec779b8eSAndroid Build Coastguard Worker /**
4949*ec779b8eSAndroid Build Coastguard Worker * Unregister a uid for monitoring, and note whether it lost ownership of a camera.
4950*ec779b8eSAndroid Build Coastguard Worker */
unregisterMonitorUid(uid_t uid,bool closeCamera)4951*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::unregisterMonitorUid(uid_t uid, bool closeCamera) {
4952*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4953*ec779b8eSAndroid Build Coastguard Worker auto it = mMonitoredUids.find(uid);
4954*ec779b8eSAndroid Build Coastguard Worker if (it != mMonitoredUids.end()) {
4955*ec779b8eSAndroid Build Coastguard Worker it->second.refCount--;
4956*ec779b8eSAndroid Build Coastguard Worker if (it->second.refCount == 0) {
4957*ec779b8eSAndroid Build Coastguard Worker mMonitoredUids.erase(it);
4958*ec779b8eSAndroid Build Coastguard Worker status_t res = mAm.removeUidFromObserver(mObserverToken, toString16(kServiceName), uid);
4959*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
4960*ec779b8eSAndroid Build Coastguard Worker ALOGE("UidPolicy: Failed to remove uid from observer: 0x%08x", res);
4961*ec779b8eSAndroid Build Coastguard Worker }
4962*ec779b8eSAndroid Build Coastguard Worker } else if (closeCamera) {
4963*ec779b8eSAndroid Build Coastguard Worker it->second.hasCamera = false;
4964*ec779b8eSAndroid Build Coastguard Worker }
4965*ec779b8eSAndroid Build Coastguard Worker } else {
4966*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Trying to unregister uid: %d which is not monitored!", __FUNCTION__, uid);
4967*ec779b8eSAndroid Build Coastguard Worker }
4968*ec779b8eSAndroid Build Coastguard Worker }
4969*ec779b8eSAndroid Build Coastguard Worker
isUidActive(uid_t uid,const std::string & callingPackage)4970*ec779b8eSAndroid Build Coastguard Worker bool CameraService::UidPolicy::isUidActive(uid_t uid, const std::string &callingPackage) {
4971*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
4972*ec779b8eSAndroid Build Coastguard Worker return isUidActiveLocked(uid, callingPackage);
4973*ec779b8eSAndroid Build Coastguard Worker }
4974*ec779b8eSAndroid Build Coastguard Worker
4975*ec779b8eSAndroid Build Coastguard Worker static const int64_t kPollUidActiveTimeoutTotalMillis = 300;
4976*ec779b8eSAndroid Build Coastguard Worker static const int64_t kPollUidActiveTimeoutMillis = 50;
4977*ec779b8eSAndroid Build Coastguard Worker
isUidActiveLocked(uid_t uid,const std::string & callingPackage)4978*ec779b8eSAndroid Build Coastguard Worker bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, const std::string &callingPackage) {
4979*ec779b8eSAndroid Build Coastguard Worker // Non-app UIDs are considered always active
4980*ec779b8eSAndroid Build Coastguard Worker // If activity manager is unreachable, assume everything is active
4981*ec779b8eSAndroid Build Coastguard Worker if (uid < FIRST_APPLICATION_UID || !mRegistered) {
4982*ec779b8eSAndroid Build Coastguard Worker return true;
4983*ec779b8eSAndroid Build Coastguard Worker }
4984*ec779b8eSAndroid Build Coastguard Worker auto it = mOverrideUids.find(uid);
4985*ec779b8eSAndroid Build Coastguard Worker if (it != mOverrideUids.end()) {
4986*ec779b8eSAndroid Build Coastguard Worker return it->second;
4987*ec779b8eSAndroid Build Coastguard Worker }
4988*ec779b8eSAndroid Build Coastguard Worker bool active = mActiveUids.find(uid) != mActiveUids.end();
4989*ec779b8eSAndroid Build Coastguard Worker if (!active) {
4990*ec779b8eSAndroid Build Coastguard Worker // We want active UIDs to always access camera with their first attempt since
4991*ec779b8eSAndroid Build Coastguard Worker // there is no guarantee the app is robustly written and would retry getting
4992*ec779b8eSAndroid Build Coastguard Worker // the camera on failure. The inverse case is not a problem as we would take
4993*ec779b8eSAndroid Build Coastguard Worker // camera away soon once we get the callback that the uid is no longer active.
4994*ec779b8eSAndroid Build Coastguard Worker ActivityManager am;
4995*ec779b8eSAndroid Build Coastguard Worker // Okay to access with a lock held as UID changes are dispatched without
4996*ec779b8eSAndroid Build Coastguard Worker // a lock and we are a higher level component.
4997*ec779b8eSAndroid Build Coastguard Worker int64_t startTimeMillis = 0;
4998*ec779b8eSAndroid Build Coastguard Worker do {
4999*ec779b8eSAndroid Build Coastguard Worker // TODO: Fix this b/109950150!
5000*ec779b8eSAndroid Build Coastguard Worker // Okay this is a hack. There is a race between the UID turning active and
5001*ec779b8eSAndroid Build Coastguard Worker // activity being resumed. The proper fix is very risky, so we temporary add
5002*ec779b8eSAndroid Build Coastguard Worker // some polling which should happen pretty rarely anyway as the race is hard
5003*ec779b8eSAndroid Build Coastguard Worker // to hit.
5004*ec779b8eSAndroid Build Coastguard Worker active = mActiveUids.find(uid) != mActiveUids.end();
5005*ec779b8eSAndroid Build Coastguard Worker if (!active) active = am.isUidActive(uid, toString16(callingPackage));
5006*ec779b8eSAndroid Build Coastguard Worker if (active) {
5007*ec779b8eSAndroid Build Coastguard Worker break;
5008*ec779b8eSAndroid Build Coastguard Worker }
5009*ec779b8eSAndroid Build Coastguard Worker if (startTimeMillis <= 0) {
5010*ec779b8eSAndroid Build Coastguard Worker startTimeMillis = uptimeMillis();
5011*ec779b8eSAndroid Build Coastguard Worker }
5012*ec779b8eSAndroid Build Coastguard Worker int64_t ellapsedTimeMillis = uptimeMillis() - startTimeMillis;
5013*ec779b8eSAndroid Build Coastguard Worker int64_t remainingTimeMillis = kPollUidActiveTimeoutTotalMillis - ellapsedTimeMillis;
5014*ec779b8eSAndroid Build Coastguard Worker if (remainingTimeMillis <= 0) {
5015*ec779b8eSAndroid Build Coastguard Worker break;
5016*ec779b8eSAndroid Build Coastguard Worker }
5017*ec779b8eSAndroid Build Coastguard Worker remainingTimeMillis = std::min(kPollUidActiveTimeoutMillis, remainingTimeMillis);
5018*ec779b8eSAndroid Build Coastguard Worker
5019*ec779b8eSAndroid Build Coastguard Worker mUidLock.unlock();
5020*ec779b8eSAndroid Build Coastguard Worker usleep(remainingTimeMillis * 1000);
5021*ec779b8eSAndroid Build Coastguard Worker mUidLock.lock();
5022*ec779b8eSAndroid Build Coastguard Worker } while (true);
5023*ec779b8eSAndroid Build Coastguard Worker
5024*ec779b8eSAndroid Build Coastguard Worker if (active) {
5025*ec779b8eSAndroid Build Coastguard Worker // Now that we found out the UID is actually active, cache that
5026*ec779b8eSAndroid Build Coastguard Worker mActiveUids.insert(uid);
5027*ec779b8eSAndroid Build Coastguard Worker }
5028*ec779b8eSAndroid Build Coastguard Worker }
5029*ec779b8eSAndroid Build Coastguard Worker return active;
5030*ec779b8eSAndroid Build Coastguard Worker }
5031*ec779b8eSAndroid Build Coastguard Worker
getProcState(uid_t uid)5032*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::UidPolicy::getProcState(uid_t uid) {
5033*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
5034*ec779b8eSAndroid Build Coastguard Worker return getProcStateLocked(uid);
5035*ec779b8eSAndroid Build Coastguard Worker }
5036*ec779b8eSAndroid Build Coastguard Worker
getProcStateLocked(uid_t uid)5037*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::UidPolicy::getProcStateLocked(uid_t uid) {
5038*ec779b8eSAndroid Build Coastguard Worker int32_t procState = ActivityManager::PROCESS_STATE_UNKNOWN;
5039*ec779b8eSAndroid Build Coastguard Worker if (mMonitoredUids.find(uid) != mMonitoredUids.end()) {
5040*ec779b8eSAndroid Build Coastguard Worker procState = mMonitoredUids[uid].procState;
5041*ec779b8eSAndroid Build Coastguard Worker }
5042*ec779b8eSAndroid Build Coastguard Worker return procState;
5043*ec779b8eSAndroid Build Coastguard Worker }
5044*ec779b8eSAndroid Build Coastguard Worker
addOverrideUid(uid_t uid,const std::string & callingPackage,bool active)5045*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::addOverrideUid(uid_t uid,
5046*ec779b8eSAndroid Build Coastguard Worker const std::string &callingPackage, bool active) {
5047*ec779b8eSAndroid Build Coastguard Worker updateOverrideUid(uid, callingPackage, active, true);
5048*ec779b8eSAndroid Build Coastguard Worker }
5049*ec779b8eSAndroid Build Coastguard Worker
removeOverrideUid(uid_t uid,const std::string & callingPackage)5050*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::removeOverrideUid(uid_t uid, const std::string &callingPackage) {
5051*ec779b8eSAndroid Build Coastguard Worker updateOverrideUid(uid, callingPackage, false, false);
5052*ec779b8eSAndroid Build Coastguard Worker }
5053*ec779b8eSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> &)5054*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
5055*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
5056*ec779b8eSAndroid Build Coastguard Worker ALOGV("UidPolicy: ActivityManager has died");
5057*ec779b8eSAndroid Build Coastguard Worker mRegistered = false;
5058*ec779b8eSAndroid Build Coastguard Worker mActiveUids.clear();
5059*ec779b8eSAndroid Build Coastguard Worker }
5060*ec779b8eSAndroid Build Coastguard Worker
updateOverrideUid(uid_t uid,const std::string & callingPackage,bool active,bool insert)5061*ec779b8eSAndroid Build Coastguard Worker void CameraService::UidPolicy::updateOverrideUid(uid_t uid, const std::string &callingPackage,
5062*ec779b8eSAndroid Build Coastguard Worker bool active, bool insert) {
5063*ec779b8eSAndroid Build Coastguard Worker bool wasActive = false;
5064*ec779b8eSAndroid Build Coastguard Worker bool isActive = false;
5065*ec779b8eSAndroid Build Coastguard Worker {
5066*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mUidLock);
5067*ec779b8eSAndroid Build Coastguard Worker wasActive = isUidActiveLocked(uid, callingPackage);
5068*ec779b8eSAndroid Build Coastguard Worker mOverrideUids.erase(uid);
5069*ec779b8eSAndroid Build Coastguard Worker if (insert) {
5070*ec779b8eSAndroid Build Coastguard Worker mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
5071*ec779b8eSAndroid Build Coastguard Worker }
5072*ec779b8eSAndroid Build Coastguard Worker isActive = isUidActiveLocked(uid, callingPackage);
5073*ec779b8eSAndroid Build Coastguard Worker }
5074*ec779b8eSAndroid Build Coastguard Worker if (wasActive != isActive && !isActive) {
5075*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> service = mService.promote();
5076*ec779b8eSAndroid Build Coastguard Worker if (service != nullptr) {
5077*ec779b8eSAndroid Build Coastguard Worker service->blockClientsForUid(uid);
5078*ec779b8eSAndroid Build Coastguard Worker }
5079*ec779b8eSAndroid Build Coastguard Worker }
5080*ec779b8eSAndroid Build Coastguard Worker }
5081*ec779b8eSAndroid Build Coastguard Worker
5082*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5083*ec779b8eSAndroid Build Coastguard Worker // SensorPrivacyPolicy
5084*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5085*ec779b8eSAndroid Build Coastguard Worker
registerWithSensorPrivacyManager()5086*ec779b8eSAndroid Build Coastguard Worker void CameraService::SensorPrivacyPolicy::registerWithSensorPrivacyManager()
5087*ec779b8eSAndroid Build Coastguard Worker {
5088*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5089*ec779b8eSAndroid Build Coastguard Worker if (mRegistered) {
5090*ec779b8eSAndroid Build Coastguard Worker return;
5091*ec779b8eSAndroid Build Coastguard Worker }
5092*ec779b8eSAndroid Build Coastguard Worker hasCameraPrivacyFeature(); // Called so the result is cached
5093*ec779b8eSAndroid Build Coastguard Worker mSpm.addSensorPrivacyListener(this);
5094*ec779b8eSAndroid Build Coastguard Worker if (isAutomotiveDevice()) {
5095*ec779b8eSAndroid Build Coastguard Worker mSpm.addToggleSensorPrivacyListener(this);
5096*ec779b8eSAndroid Build Coastguard Worker }
5097*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled();
5098*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_privacy_allowlist()) {
5099*ec779b8eSAndroid Build Coastguard Worker mCameraPrivacyState = mSpm.getToggleSensorPrivacyState(
5100*ec779b8eSAndroid Build Coastguard Worker SensorPrivacyManager::TOGGLE_TYPE_SOFTWARE,
5101*ec779b8eSAndroid Build Coastguard Worker SensorPrivacyManager::TOGGLE_SENSOR_CAMERA);
5102*ec779b8eSAndroid Build Coastguard Worker }
5103*ec779b8eSAndroid Build Coastguard Worker status_t res = mSpm.linkToDeath(this);
5104*ec779b8eSAndroid Build Coastguard Worker if (res == OK) {
5105*ec779b8eSAndroid Build Coastguard Worker mRegistered = true;
5106*ec779b8eSAndroid Build Coastguard Worker ALOGV("SensorPrivacyPolicy: Registered with SensorPrivacyManager");
5107*ec779b8eSAndroid Build Coastguard Worker }
5108*ec779b8eSAndroid Build Coastguard Worker }
5109*ec779b8eSAndroid Build Coastguard Worker
onServiceRegistration(const String16 & name,const sp<IBinder> &)5110*ec779b8eSAndroid Build Coastguard Worker void CameraService::SensorPrivacyPolicy::onServiceRegistration(const String16& name,
5111*ec779b8eSAndroid Build Coastguard Worker const sp<IBinder>&) {
5112*ec779b8eSAndroid Build Coastguard Worker if (name != toString16(kSensorPrivacyServiceName)) {
5113*ec779b8eSAndroid Build Coastguard Worker return;
5114*ec779b8eSAndroid Build Coastguard Worker }
5115*ec779b8eSAndroid Build Coastguard Worker
5116*ec779b8eSAndroid Build Coastguard Worker registerWithSensorPrivacyManager();
5117*ec779b8eSAndroid Build Coastguard Worker }
5118*ec779b8eSAndroid Build Coastguard Worker
registerSelf()5119*ec779b8eSAndroid Build Coastguard Worker void CameraService::SensorPrivacyPolicy::registerSelf() {
5120*ec779b8eSAndroid Build Coastguard Worker // Use checkservice to see if the sensor_privacy service is available
5121*ec779b8eSAndroid Build Coastguard Worker // If service is not available then register for notification
5122*ec779b8eSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
5123*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = sm->checkService(toString16(kSensorPrivacyServiceName));
5124*ec779b8eSAndroid Build Coastguard Worker if (!binder) {
5125*ec779b8eSAndroid Build Coastguard Worker sm->registerForNotifications(toString16(kSensorPrivacyServiceName),this);
5126*ec779b8eSAndroid Build Coastguard Worker } else {
5127*ec779b8eSAndroid Build Coastguard Worker registerWithSensorPrivacyManager();
5128*ec779b8eSAndroid Build Coastguard Worker }
5129*ec779b8eSAndroid Build Coastguard Worker }
5130*ec779b8eSAndroid Build Coastguard Worker
unregisterSelf()5131*ec779b8eSAndroid Build Coastguard Worker void CameraService::SensorPrivacyPolicy::unregisterSelf() {
5132*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5133*ec779b8eSAndroid Build Coastguard Worker mSpm.removeSensorPrivacyListener(this);
5134*ec779b8eSAndroid Build Coastguard Worker if (isAutomotiveDevice()) {
5135*ec779b8eSAndroid Build Coastguard Worker mSpm.removeToggleSensorPrivacyListener(this);
5136*ec779b8eSAndroid Build Coastguard Worker }
5137*ec779b8eSAndroid Build Coastguard Worker mSpm.unlinkToDeath(this);
5138*ec779b8eSAndroid Build Coastguard Worker mRegistered = false;
5139*ec779b8eSAndroid Build Coastguard Worker ALOGV("SensorPrivacyPolicy: Unregistered with SensorPrivacyManager");
5140*ec779b8eSAndroid Build Coastguard Worker }
5141*ec779b8eSAndroid Build Coastguard Worker
isSensorPrivacyEnabled()5142*ec779b8eSAndroid Build Coastguard Worker bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
5143*ec779b8eSAndroid Build Coastguard Worker if (!mRegistered) {
5144*ec779b8eSAndroid Build Coastguard Worker registerWithSensorPrivacyManager();
5145*ec779b8eSAndroid Build Coastguard Worker }
5146*ec779b8eSAndroid Build Coastguard Worker
5147*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5148*ec779b8eSAndroid Build Coastguard Worker return mSensorPrivacyEnabled;
5149*ec779b8eSAndroid Build Coastguard Worker }
5150*ec779b8eSAndroid Build Coastguard Worker
getCameraPrivacyState()5151*ec779b8eSAndroid Build Coastguard Worker int CameraService::SensorPrivacyPolicy::getCameraPrivacyState() {
5152*ec779b8eSAndroid Build Coastguard Worker if (!mRegistered) {
5153*ec779b8eSAndroid Build Coastguard Worker registerWithSensorPrivacyManager();
5154*ec779b8eSAndroid Build Coastguard Worker }
5155*ec779b8eSAndroid Build Coastguard Worker
5156*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5157*ec779b8eSAndroid Build Coastguard Worker return mCameraPrivacyState;
5158*ec779b8eSAndroid Build Coastguard Worker }
5159*ec779b8eSAndroid Build Coastguard Worker
isCameraPrivacyEnabled()5160*ec779b8eSAndroid Build Coastguard Worker bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled() {
5161*ec779b8eSAndroid Build Coastguard Worker if (!hasCameraPrivacyFeature()) {
5162*ec779b8eSAndroid Build Coastguard Worker return false;
5163*ec779b8eSAndroid Build Coastguard Worker }
5164*ec779b8eSAndroid Build Coastguard Worker return mSpm.isToggleSensorPrivacyEnabled(SensorPrivacyManager::TOGGLE_SENSOR_CAMERA);
5165*ec779b8eSAndroid Build Coastguard Worker }
5166*ec779b8eSAndroid Build Coastguard Worker
isCameraPrivacyEnabled(const String16 & packageName)5167*ec779b8eSAndroid Build Coastguard Worker bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled(const String16& packageName) {
5168*ec779b8eSAndroid Build Coastguard Worker if (!hasCameraPrivacyFeature()) {
5169*ec779b8eSAndroid Build Coastguard Worker return false;
5170*ec779b8eSAndroid Build Coastguard Worker }
5171*ec779b8eSAndroid Build Coastguard Worker return mSpm.isCameraPrivacyEnabled(packageName);
5172*ec779b8eSAndroid Build Coastguard Worker }
5173*ec779b8eSAndroid Build Coastguard Worker
onSensorPrivacyChanged(int toggleType,int sensor,bool enabled)5174*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged(
5175*ec779b8eSAndroid Build Coastguard Worker int toggleType, int sensor, bool enabled) {
5176*ec779b8eSAndroid Build Coastguard Worker if ((toggleType == SensorPrivacyManager::TOGGLE_TYPE_UNKNOWN)
5177*ec779b8eSAndroid Build Coastguard Worker && (sensor == SensorPrivacyManager::TOGGLE_SENSOR_UNKNOWN)) {
5178*ec779b8eSAndroid Build Coastguard Worker {
5179*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5180*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyEnabled = enabled;
5181*ec779b8eSAndroid Build Coastguard Worker }
5182*ec779b8eSAndroid Build Coastguard Worker // if sensor privacy is enabled then block all clients from accessing the camera
5183*ec779b8eSAndroid Build Coastguard Worker if (enabled) {
5184*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> service = mService.promote();
5185*ec779b8eSAndroid Build Coastguard Worker if (service != nullptr) {
5186*ec779b8eSAndroid Build Coastguard Worker service->blockAllClients();
5187*ec779b8eSAndroid Build Coastguard Worker }
5188*ec779b8eSAndroid Build Coastguard Worker }
5189*ec779b8eSAndroid Build Coastguard Worker }
5190*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
5191*ec779b8eSAndroid Build Coastguard Worker }
5192*ec779b8eSAndroid Build Coastguard Worker
onSensorPrivacyStateChanged(int,int sensor,int state)5193*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyStateChanged(
5194*ec779b8eSAndroid Build Coastguard Worker int, int sensor, int state) {
5195*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_privacy_allowlist()
5196*ec779b8eSAndroid Build Coastguard Worker || (sensor != SensorPrivacyManager::TOGGLE_SENSOR_CAMERA)) {
5197*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
5198*ec779b8eSAndroid Build Coastguard Worker }
5199*ec779b8eSAndroid Build Coastguard Worker {
5200*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5201*ec779b8eSAndroid Build Coastguard Worker mCameraPrivacyState = state;
5202*ec779b8eSAndroid Build Coastguard Worker }
5203*ec779b8eSAndroid Build Coastguard Worker sp<CameraService> service = mService.promote();
5204*ec779b8eSAndroid Build Coastguard Worker if (!service) {
5205*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
5206*ec779b8eSAndroid Build Coastguard Worker }
5207*ec779b8eSAndroid Build Coastguard Worker // if sensor privacy is enabled then block all clients from accessing the camera
5208*ec779b8eSAndroid Build Coastguard Worker if (state == SensorPrivacyManager::ENABLED) {
5209*ec779b8eSAndroid Build Coastguard Worker service->blockAllClients();
5210*ec779b8eSAndroid Build Coastguard Worker } else if (state == SensorPrivacyManager::ENABLED_EXCEPT_ALLOWLISTED_APPS) {
5211*ec779b8eSAndroid Build Coastguard Worker service->blockPrivacyEnabledClients();
5212*ec779b8eSAndroid Build Coastguard Worker }
5213*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
5214*ec779b8eSAndroid Build Coastguard Worker }
5215*ec779b8eSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> &)5216*ec779b8eSAndroid Build Coastguard Worker void CameraService::SensorPrivacyPolicy::binderDied(const wp<IBinder>& /*who*/) {
5217*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock _l(mSensorPrivacyLock);
5218*ec779b8eSAndroid Build Coastguard Worker ALOGV("SensorPrivacyPolicy: SensorPrivacyManager has died");
5219*ec779b8eSAndroid Build Coastguard Worker mRegistered = false;
5220*ec779b8eSAndroid Build Coastguard Worker }
5221*ec779b8eSAndroid Build Coastguard Worker
hasCameraPrivacyFeature()5222*ec779b8eSAndroid Build Coastguard Worker bool CameraService::SensorPrivacyPolicy::hasCameraPrivacyFeature() {
5223*ec779b8eSAndroid Build Coastguard Worker bool supportsSoftwareToggle = mSpm.supportsSensorToggle(
5224*ec779b8eSAndroid Build Coastguard Worker SensorPrivacyManager::TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager::TOGGLE_SENSOR_CAMERA);
5225*ec779b8eSAndroid Build Coastguard Worker bool supportsHardwareToggle = mSpm.supportsSensorToggle(
5226*ec779b8eSAndroid Build Coastguard Worker SensorPrivacyManager::TOGGLE_TYPE_HARDWARE, SensorPrivacyManager::TOGGLE_SENSOR_CAMERA);
5227*ec779b8eSAndroid Build Coastguard Worker return supportsSoftwareToggle || supportsHardwareToggle;
5228*ec779b8eSAndroid Build Coastguard Worker }
5229*ec779b8eSAndroid Build Coastguard Worker
5230*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5231*ec779b8eSAndroid Build Coastguard Worker // CameraState
5232*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5233*ec779b8eSAndroid Build Coastguard Worker
CameraState(const std::string & id,int cost,const std::set<std::string> & conflicting,SystemCameraKind systemCameraKind,const std::vector<std::string> & physicalCameras)5234*ec779b8eSAndroid Build Coastguard Worker CameraService::CameraState::CameraState(const std::string& id, int cost,
5235*ec779b8eSAndroid Build Coastguard Worker const std::set<std::string>& conflicting, SystemCameraKind systemCameraKind,
5236*ec779b8eSAndroid Build Coastguard Worker const std::vector<std::string>& physicalCameras) : mId(id),
5237*ec779b8eSAndroid Build Coastguard Worker mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting),
5238*ec779b8eSAndroid Build Coastguard Worker mSystemCameraKind(systemCameraKind), mPhysicalCameras(physicalCameras) {}
5239*ec779b8eSAndroid Build Coastguard Worker
~CameraState()5240*ec779b8eSAndroid Build Coastguard Worker CameraService::CameraState::~CameraState() {}
5241*ec779b8eSAndroid Build Coastguard Worker
getStatus() const5242*ec779b8eSAndroid Build Coastguard Worker CameraService::StatusInternal CameraService::CameraState::getStatus() const {
5243*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5244*ec779b8eSAndroid Build Coastguard Worker return mStatus;
5245*ec779b8eSAndroid Build Coastguard Worker }
5246*ec779b8eSAndroid Build Coastguard Worker
getUnavailablePhysicalIds() const5247*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> CameraService::CameraState::getUnavailablePhysicalIds() const {
5248*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5249*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end());
5250*ec779b8eSAndroid Build Coastguard Worker return res;
5251*ec779b8eSAndroid Build Coastguard Worker }
5252*ec779b8eSAndroid Build Coastguard Worker
getShimParams() const5253*ec779b8eSAndroid Build Coastguard Worker CameraParameters CameraService::CameraState::getShimParams() const {
5254*ec779b8eSAndroid Build Coastguard Worker return mShimParams;
5255*ec779b8eSAndroid Build Coastguard Worker }
5256*ec779b8eSAndroid Build Coastguard Worker
setShimParams(const CameraParameters & params)5257*ec779b8eSAndroid Build Coastguard Worker void CameraService::CameraState::setShimParams(const CameraParameters& params) {
5258*ec779b8eSAndroid Build Coastguard Worker mShimParams = params;
5259*ec779b8eSAndroid Build Coastguard Worker }
5260*ec779b8eSAndroid Build Coastguard Worker
getCost() const5261*ec779b8eSAndroid Build Coastguard Worker int CameraService::CameraState::getCost() const {
5262*ec779b8eSAndroid Build Coastguard Worker return mCost;
5263*ec779b8eSAndroid Build Coastguard Worker }
5264*ec779b8eSAndroid Build Coastguard Worker
getConflicting() const5265*ec779b8eSAndroid Build Coastguard Worker std::set<std::string> CameraService::CameraState::getConflicting() const {
5266*ec779b8eSAndroid Build Coastguard Worker return mConflicting;
5267*ec779b8eSAndroid Build Coastguard Worker }
5268*ec779b8eSAndroid Build Coastguard Worker
getSystemCameraKind() const5269*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind CameraService::CameraState::getSystemCameraKind() const {
5270*ec779b8eSAndroid Build Coastguard Worker return mSystemCameraKind;
5271*ec779b8eSAndroid Build Coastguard Worker }
5272*ec779b8eSAndroid Build Coastguard Worker
containsPhysicalCamera(const std::string & physicalCameraId) const5273*ec779b8eSAndroid Build Coastguard Worker bool CameraService::CameraState::containsPhysicalCamera(const std::string& physicalCameraId) const {
5274*ec779b8eSAndroid Build Coastguard Worker return std::find(mPhysicalCameras.begin(), mPhysicalCameras.end(), physicalCameraId)
5275*ec779b8eSAndroid Build Coastguard Worker != mPhysicalCameras.end();
5276*ec779b8eSAndroid Build Coastguard Worker }
5277*ec779b8eSAndroid Build Coastguard Worker
addUnavailablePhysicalId(const std::string & physicalId)5278*ec779b8eSAndroid Build Coastguard Worker bool CameraService::CameraState::addUnavailablePhysicalId(const std::string& physicalId) {
5279*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5280*ec779b8eSAndroid Build Coastguard Worker auto result = mUnavailablePhysicalIds.insert(physicalId);
5281*ec779b8eSAndroid Build Coastguard Worker return result.second;
5282*ec779b8eSAndroid Build Coastguard Worker }
5283*ec779b8eSAndroid Build Coastguard Worker
removeUnavailablePhysicalId(const std::string & physicalId)5284*ec779b8eSAndroid Build Coastguard Worker bool CameraService::CameraState::removeUnavailablePhysicalId(const std::string& physicalId) {
5285*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5286*ec779b8eSAndroid Build Coastguard Worker auto count = mUnavailablePhysicalIds.erase(physicalId);
5287*ec779b8eSAndroid Build Coastguard Worker return count > 0;
5288*ec779b8eSAndroid Build Coastguard Worker }
5289*ec779b8eSAndroid Build Coastguard Worker
setClientPackage(const std::string & clientPackage)5290*ec779b8eSAndroid Build Coastguard Worker void CameraService::CameraState::setClientPackage(const std::string& clientPackage) {
5291*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5292*ec779b8eSAndroid Build Coastguard Worker mClientPackages.clear();
5293*ec779b8eSAndroid Build Coastguard Worker mClientPackages.insert(clientPackage);
5294*ec779b8eSAndroid Build Coastguard Worker }
5295*ec779b8eSAndroid Build Coastguard Worker
getClientPackage() const5296*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::CameraState::getClientPackage() const {
5297*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5298*ec779b8eSAndroid Build Coastguard Worker if (!mClientPackages.empty()) {
5299*ec779b8eSAndroid Build Coastguard Worker std::set<std::string>::iterator it = mClientPackages.begin();
5300*ec779b8eSAndroid Build Coastguard Worker return *it;
5301*ec779b8eSAndroid Build Coastguard Worker }
5302*ec779b8eSAndroid Build Coastguard Worker return std::string();
5303*ec779b8eSAndroid Build Coastguard Worker }
5304*ec779b8eSAndroid Build Coastguard Worker
addClientPackage(const std::string & clientPackage)5305*ec779b8eSAndroid Build Coastguard Worker void CameraService::CameraState::addClientPackage(const std::string& clientPackage) {
5306*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5307*ec779b8eSAndroid Build Coastguard Worker mClientPackages.insert(clientPackage);
5308*ec779b8eSAndroid Build Coastguard Worker }
5309*ec779b8eSAndroid Build Coastguard Worker
removeClientPackage(const std::string & clientPackage)5310*ec779b8eSAndroid Build Coastguard Worker void CameraService::CameraState::removeClientPackage(const std::string& clientPackage) {
5311*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
5312*ec779b8eSAndroid Build Coastguard Worker mClientPackages.erase(clientPackage);
5313*ec779b8eSAndroid Build Coastguard Worker }
5314*ec779b8eSAndroid Build Coastguard Worker
5315*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5316*ec779b8eSAndroid Build Coastguard Worker // ClientEventListener
5317*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5318*ec779b8eSAndroid Build Coastguard Worker
onClientAdded(const resource_policy::ClientDescriptor<std::string,sp<CameraService::BasicClient>> & descriptor)5319*ec779b8eSAndroid Build Coastguard Worker void CameraService::ClientEventListener::onClientAdded(
5320*ec779b8eSAndroid Build Coastguard Worker const resource_policy::ClientDescriptor<std::string,
5321*ec779b8eSAndroid Build Coastguard Worker sp<CameraService::BasicClient>>& descriptor) {
5322*ec779b8eSAndroid Build Coastguard Worker const auto& basicClient = descriptor.getValue();
5323*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
5324*ec779b8eSAndroid Build Coastguard Worker BatteryNotifier& notifier(BatteryNotifier::getInstance());
5325*ec779b8eSAndroid Build Coastguard Worker notifier.noteStartCamera(toString8(descriptor.getKey()),
5326*ec779b8eSAndroid Build Coastguard Worker static_cast<int>(basicClient->getClientUid()));
5327*ec779b8eSAndroid Build Coastguard Worker }
5328*ec779b8eSAndroid Build Coastguard Worker }
5329*ec779b8eSAndroid Build Coastguard Worker
onClientRemoved(const resource_policy::ClientDescriptor<std::string,sp<CameraService::BasicClient>> & descriptor)5330*ec779b8eSAndroid Build Coastguard Worker void CameraService::ClientEventListener::onClientRemoved(
5331*ec779b8eSAndroid Build Coastguard Worker const resource_policy::ClientDescriptor<std::string,
5332*ec779b8eSAndroid Build Coastguard Worker sp<CameraService::BasicClient>>& descriptor) {
5333*ec779b8eSAndroid Build Coastguard Worker const auto& basicClient = descriptor.getValue();
5334*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
5335*ec779b8eSAndroid Build Coastguard Worker BatteryNotifier& notifier(BatteryNotifier::getInstance());
5336*ec779b8eSAndroid Build Coastguard Worker notifier.noteStopCamera(toString8(descriptor.getKey()),
5337*ec779b8eSAndroid Build Coastguard Worker static_cast<int>(basicClient->getClientUid()));
5338*ec779b8eSAndroid Build Coastguard Worker }
5339*ec779b8eSAndroid Build Coastguard Worker }
5340*ec779b8eSAndroid Build Coastguard Worker
5341*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5342*ec779b8eSAndroid Build Coastguard Worker // CameraClientManager
5343*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5344*ec779b8eSAndroid Build Coastguard Worker
CameraClientManager()5345*ec779b8eSAndroid Build Coastguard Worker CameraService::CameraClientManager::CameraClientManager() {
5346*ec779b8eSAndroid Build Coastguard Worker setListener(std::make_shared<ClientEventListener>());
5347*ec779b8eSAndroid Build Coastguard Worker }
5348*ec779b8eSAndroid Build Coastguard Worker
~CameraClientManager()5349*ec779b8eSAndroid Build Coastguard Worker CameraService::CameraClientManager::~CameraClientManager() {}
5350*ec779b8eSAndroid Build Coastguard Worker
getCameraClient(const std::string & id) const5351*ec779b8eSAndroid Build Coastguard Worker sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient(
5352*ec779b8eSAndroid Build Coastguard Worker const std::string& id) const {
5353*ec779b8eSAndroid Build Coastguard Worker auto descriptor = get(id);
5354*ec779b8eSAndroid Build Coastguard Worker if (descriptor == nullptr) {
5355*ec779b8eSAndroid Build Coastguard Worker return sp<BasicClient>{nullptr};
5356*ec779b8eSAndroid Build Coastguard Worker }
5357*ec779b8eSAndroid Build Coastguard Worker return descriptor->getValue();
5358*ec779b8eSAndroid Build Coastguard Worker }
5359*ec779b8eSAndroid Build Coastguard Worker
remove(const CameraService::DescriptorPtr & value)5360*ec779b8eSAndroid Build Coastguard Worker void CameraService::CameraClientManager::remove(const CameraService::DescriptorPtr& value) {
5361*ec779b8eSAndroid Build Coastguard Worker ClientManager::remove(value);
5362*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client()) {
5363*ec779b8eSAndroid Build Coastguard Worker return;
5364*ec779b8eSAndroid Build Coastguard Worker }
5365*ec779b8eSAndroid Build Coastguard Worker auto clientToRemove = value->getValue();
5366*ec779b8eSAndroid Build Coastguard Worker if ((clientToRemove.get() != nullptr) && clientToRemove->mSharedMode) {
5367*ec779b8eSAndroid Build Coastguard Worker bool primaryClient = false;
5368*ec779b8eSAndroid Build Coastguard Worker status_t ret = clientToRemove->isPrimaryClient(&primaryClient);
5369*ec779b8eSAndroid Build Coastguard Worker if ((ret == OK) && primaryClient) {
5370*ec779b8eSAndroid Build Coastguard Worker // Primary client is being removed. Find the next higher priority
5371*ec779b8eSAndroid Build Coastguard Worker // client to become primary client.
5372*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = get(value->getKey());
5373*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor == nullptr) {
5374*ec779b8eSAndroid Build Coastguard Worker ALOGV("CameraService::CameraClientManager::no other clients are using same camera");
5375*ec779b8eSAndroid Build Coastguard Worker return;
5376*ec779b8eSAndroid Build Coastguard Worker }
5377*ec779b8eSAndroid Build Coastguard Worker resource_policy::ClientPriority highestPriority = clientDescriptor->getPriority();
5378*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> highestPriorityClient = clientDescriptor->getValue();
5379*ec779b8eSAndroid Build Coastguard Worker if (highestPriorityClient.get() != nullptr) {
5380*ec779b8eSAndroid Build Coastguard Worker for (auto& i : getAll()) {
5381*ec779b8eSAndroid Build Coastguard Worker if ((i->getKey() == value->getKey()) && (i->getPriority() < highestPriority)) {
5382*ec779b8eSAndroid Build Coastguard Worker highestPriority = i->getPriority();
5383*ec779b8eSAndroid Build Coastguard Worker highestPriorityClient = i->getValue();
5384*ec779b8eSAndroid Build Coastguard Worker }
5385*ec779b8eSAndroid Build Coastguard Worker }
5386*ec779b8eSAndroid Build Coastguard Worker highestPriorityClient->setPrimaryClient(true);
5387*ec779b8eSAndroid Build Coastguard Worker highestPriorityClient->notifyClientSharedAccessPriorityChanged(true);
5388*ec779b8eSAndroid Build Coastguard Worker }
5389*ec779b8eSAndroid Build Coastguard Worker }
5390*ec779b8eSAndroid Build Coastguard Worker }
5391*ec779b8eSAndroid Build Coastguard Worker }
5392*ec779b8eSAndroid Build Coastguard Worker
toString() const5393*ec779b8eSAndroid Build Coastguard Worker std::string CameraService::CameraClientManager::toString() const {
5394*ec779b8eSAndroid Build Coastguard Worker auto all = getAll();
5395*ec779b8eSAndroid Build Coastguard Worker std::ostringstream ret;
5396*ec779b8eSAndroid Build Coastguard Worker ret << "[";
5397*ec779b8eSAndroid Build Coastguard Worker bool hasAny = false;
5398*ec779b8eSAndroid Build Coastguard Worker for (auto& i : all) {
5399*ec779b8eSAndroid Build Coastguard Worker hasAny = true;
5400*ec779b8eSAndroid Build Coastguard Worker std::string key = i->getKey();
5401*ec779b8eSAndroid Build Coastguard Worker int32_t cost = i->getCost();
5402*ec779b8eSAndroid Build Coastguard Worker int32_t pid = i->getOwnerId();
5403*ec779b8eSAndroid Build Coastguard Worker int32_t score = i->getPriority().getScore();
5404*ec779b8eSAndroid Build Coastguard Worker int32_t state = i->getPriority().getState();
5405*ec779b8eSAndroid Build Coastguard Worker auto conflicting = i->getConflicting();
5406*ec779b8eSAndroid Build Coastguard Worker auto clientSp = i->getValue();
5407*ec779b8eSAndroid Build Coastguard Worker std::string packageName;
5408*ec779b8eSAndroid Build Coastguard Worker userid_t clientUserId = 0;
5409*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() != nullptr) {
5410*ec779b8eSAndroid Build Coastguard Worker packageName = clientSp->getPackageName();
5411*ec779b8eSAndroid Build Coastguard Worker uid_t clientUid = clientSp->getClientUid();
5412*ec779b8eSAndroid Build Coastguard Worker clientUserId = multiuser_get_user_id(clientUid);
5413*ec779b8eSAndroid Build Coastguard Worker }
5414*ec779b8eSAndroid Build Coastguard Worker ret << fmt::sprintf("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %"
5415*ec779b8eSAndroid Build Coastguard Worker PRId32 ", State: %" PRId32, key.c_str(), cost, pid, score, state);
5416*ec779b8eSAndroid Build Coastguard Worker
5417*ec779b8eSAndroid Build Coastguard Worker if (clientSp.get() != nullptr) {
5418*ec779b8eSAndroid Build Coastguard Worker ret << fmt::sprintf("User Id: %d, ", clientUserId);
5419*ec779b8eSAndroid Build Coastguard Worker }
5420*ec779b8eSAndroid Build Coastguard Worker if (packageName.size() != 0) {
5421*ec779b8eSAndroid Build Coastguard Worker ret << fmt::sprintf("Client Package Name: %s", packageName.c_str());
5422*ec779b8eSAndroid Build Coastguard Worker }
5423*ec779b8eSAndroid Build Coastguard Worker
5424*ec779b8eSAndroid Build Coastguard Worker ret << ", Conflicting Client Devices: {";
5425*ec779b8eSAndroid Build Coastguard Worker for (auto& j : conflicting) {
5426*ec779b8eSAndroid Build Coastguard Worker ret << fmt::sprintf("%s, ", j.c_str());
5427*ec779b8eSAndroid Build Coastguard Worker }
5428*ec779b8eSAndroid Build Coastguard Worker ret << "})";
5429*ec779b8eSAndroid Build Coastguard Worker }
5430*ec779b8eSAndroid Build Coastguard Worker if (hasAny) ret << "\n";
5431*ec779b8eSAndroid Build Coastguard Worker ret << "]\n";
5432*ec779b8eSAndroid Build Coastguard Worker return ret.str();
5433*ec779b8eSAndroid Build Coastguard Worker }
5434*ec779b8eSAndroid Build Coastguard Worker
makeClientDescriptor(const std::string & key,const sp<BasicClient> & value,int32_t cost,const std::set<std::string> & conflictingKeys,int32_t score,int32_t ownerId,int32_t state,int32_t oomScoreOffset,bool systemNativeClient,bool sharedMode)5435*ec779b8eSAndroid Build Coastguard Worker CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
5436*ec779b8eSAndroid Build Coastguard Worker const std::string& key, const sp<BasicClient>& value, int32_t cost,
5437*ec779b8eSAndroid Build Coastguard Worker const std::set<std::string>& conflictingKeys, int32_t score, int32_t ownerId,
5438*ec779b8eSAndroid Build Coastguard Worker int32_t state, int32_t oomScoreOffset, bool systemNativeClient, bool sharedMode) {
5439*ec779b8eSAndroid Build Coastguard Worker
5440*ec779b8eSAndroid Build Coastguard Worker int32_t score_adj = systemNativeClient ? kSystemNativeClientScore : score;
5441*ec779b8eSAndroid Build Coastguard Worker int32_t state_adj = systemNativeClient ? kSystemNativeClientState : state;
5442*ec779b8eSAndroid Build Coastguard Worker
5443*ec779b8eSAndroid Build Coastguard Worker return std::make_shared<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>(
5444*ec779b8eSAndroid Build Coastguard Worker key, value, cost, conflictingKeys, score_adj, ownerId, state_adj,
5445*ec779b8eSAndroid Build Coastguard Worker systemNativeClient, oomScoreOffset, sharedMode);
5446*ec779b8eSAndroid Build Coastguard Worker }
5447*ec779b8eSAndroid Build Coastguard Worker
makeClientDescriptor(const sp<BasicClient> & value,const CameraService::DescriptorPtr & partial,int32_t oomScoreOffset,bool systemNativeClient)5448*ec779b8eSAndroid Build Coastguard Worker CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
5449*ec779b8eSAndroid Build Coastguard Worker const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial,
5450*ec779b8eSAndroid Build Coastguard Worker int32_t oomScoreOffset, bool systemNativeClient) {
5451*ec779b8eSAndroid Build Coastguard Worker return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
5452*ec779b8eSAndroid Build Coastguard Worker partial->getConflicting(), partial->getPriority().getScore(),
5453*ec779b8eSAndroid Build Coastguard Worker partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset,
5454*ec779b8eSAndroid Build Coastguard Worker systemNativeClient, partial->getSharedMode());
5455*ec779b8eSAndroid Build Coastguard Worker }
5456*ec779b8eSAndroid Build Coastguard Worker
5457*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5458*ec779b8eSAndroid Build Coastguard Worker // InjectionStatusListener
5459*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5460*ec779b8eSAndroid Build Coastguard Worker
addListener(const sp<ICameraInjectionCallback> & callback)5461*ec779b8eSAndroid Build Coastguard Worker void CameraService::InjectionStatusListener::addListener(
5462*ec779b8eSAndroid Build Coastguard Worker const sp<ICameraInjectionCallback>& callback) {
5463*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mListenerLock);
5464*ec779b8eSAndroid Build Coastguard Worker if (mCameraInjectionCallback) return;
5465*ec779b8eSAndroid Build Coastguard Worker status_t res = IInterface::asBinder(callback)->linkToDeath(this);
5466*ec779b8eSAndroid Build Coastguard Worker if (res == OK) {
5467*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback = callback;
5468*ec779b8eSAndroid Build Coastguard Worker }
5469*ec779b8eSAndroid Build Coastguard Worker }
5470*ec779b8eSAndroid Build Coastguard Worker
removeListener()5471*ec779b8eSAndroid Build Coastguard Worker void CameraService::InjectionStatusListener::removeListener() {
5472*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mListenerLock);
5473*ec779b8eSAndroid Build Coastguard Worker if (mCameraInjectionCallback == nullptr) {
5474*ec779b8eSAndroid Build Coastguard Worker ALOGW("InjectionStatusListener: mCameraInjectionCallback == nullptr");
5475*ec779b8eSAndroid Build Coastguard Worker return;
5476*ec779b8eSAndroid Build Coastguard Worker }
5477*ec779b8eSAndroid Build Coastguard Worker IInterface::asBinder(mCameraInjectionCallback)->unlinkToDeath(this);
5478*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback = nullptr;
5479*ec779b8eSAndroid Build Coastguard Worker }
5480*ec779b8eSAndroid Build Coastguard Worker
notifyInjectionError(const std::string & injectedCamId,status_t err)5481*ec779b8eSAndroid Build Coastguard Worker void CameraService::InjectionStatusListener::notifyInjectionError(
5482*ec779b8eSAndroid Build Coastguard Worker const std::string &injectedCamId, status_t err) {
5483*ec779b8eSAndroid Build Coastguard Worker if (mCameraInjectionCallback == nullptr) {
5484*ec779b8eSAndroid Build Coastguard Worker ALOGW("InjectionStatusListener: mCameraInjectionCallback == nullptr");
5485*ec779b8eSAndroid Build Coastguard Worker return;
5486*ec779b8eSAndroid Build Coastguard Worker }
5487*ec779b8eSAndroid Build Coastguard Worker
5488*ec779b8eSAndroid Build Coastguard Worker switch (err) {
5489*ec779b8eSAndroid Build Coastguard Worker case -ENODEV:
5490*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback->onInjectionError(
5491*ec779b8eSAndroid Build Coastguard Worker ICameraInjectionCallback::ERROR_INJECTION_SESSION);
5492*ec779b8eSAndroid Build Coastguard Worker ALOGE("No camera device with ID \"%s\" currently available!",
5493*ec779b8eSAndroid Build Coastguard Worker injectedCamId.c_str());
5494*ec779b8eSAndroid Build Coastguard Worker break;
5495*ec779b8eSAndroid Build Coastguard Worker case -EBUSY:
5496*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback->onInjectionError(
5497*ec779b8eSAndroid Build Coastguard Worker ICameraInjectionCallback::ERROR_INJECTION_SESSION);
5498*ec779b8eSAndroid Build Coastguard Worker ALOGE("Higher-priority client using camera, ID \"%s\" currently unavailable!",
5499*ec779b8eSAndroid Build Coastguard Worker injectedCamId.c_str());
5500*ec779b8eSAndroid Build Coastguard Worker break;
5501*ec779b8eSAndroid Build Coastguard Worker case DEAD_OBJECT:
5502*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback->onInjectionError(
5503*ec779b8eSAndroid Build Coastguard Worker ICameraInjectionCallback::ERROR_INJECTION_SESSION);
5504*ec779b8eSAndroid Build Coastguard Worker ALOGE("Camera ID \"%s\" object is dead!",
5505*ec779b8eSAndroid Build Coastguard Worker injectedCamId.c_str());
5506*ec779b8eSAndroid Build Coastguard Worker break;
5507*ec779b8eSAndroid Build Coastguard Worker case INVALID_OPERATION:
5508*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback->onInjectionError(
5509*ec779b8eSAndroid Build Coastguard Worker ICameraInjectionCallback::ERROR_INJECTION_SESSION);
5510*ec779b8eSAndroid Build Coastguard Worker ALOGE("Camera ID \"%s\" encountered an operating or internal error!",
5511*ec779b8eSAndroid Build Coastguard Worker injectedCamId.c_str());
5512*ec779b8eSAndroid Build Coastguard Worker break;
5513*ec779b8eSAndroid Build Coastguard Worker case UNKNOWN_TRANSACTION:
5514*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback->onInjectionError(
5515*ec779b8eSAndroid Build Coastguard Worker ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED);
5516*ec779b8eSAndroid Build Coastguard Worker ALOGE("Camera ID \"%s\" method doesn't support!",
5517*ec779b8eSAndroid Build Coastguard Worker injectedCamId.c_str());
5518*ec779b8eSAndroid Build Coastguard Worker break;
5519*ec779b8eSAndroid Build Coastguard Worker default:
5520*ec779b8eSAndroid Build Coastguard Worker mCameraInjectionCallback->onInjectionError(
5521*ec779b8eSAndroid Build Coastguard Worker ICameraInjectionCallback::ERROR_INJECTION_INVALID_ERROR);
5522*ec779b8eSAndroid Build Coastguard Worker ALOGE("Unexpected error %s (%d) opening camera \"%s\"!",
5523*ec779b8eSAndroid Build Coastguard Worker strerror(-err), err, injectedCamId.c_str());
5524*ec779b8eSAndroid Build Coastguard Worker }
5525*ec779b8eSAndroid Build Coastguard Worker }
5526*ec779b8eSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> &)5527*ec779b8eSAndroid Build Coastguard Worker void CameraService::InjectionStatusListener::binderDied(
5528*ec779b8eSAndroid Build Coastguard Worker const wp<IBinder>& /*who*/) {
5529*ec779b8eSAndroid Build Coastguard Worker ALOGV("InjectionStatusListener: ICameraInjectionCallback has died");
5530*ec779b8eSAndroid Build Coastguard Worker auto parent = mParent.promote();
5531*ec779b8eSAndroid Build Coastguard Worker if (parent != nullptr) {
5532*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = parent->mActiveClientManager.get(parent->mInjectionInternalCamId);
5533*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor != nullptr) {
5534*ec779b8eSAndroid Build Coastguard Worker BasicClient* baseClientPtr = clientDescriptor->getValue().get();
5535*ec779b8eSAndroid Build Coastguard Worker baseClientPtr->stopInjection();
5536*ec779b8eSAndroid Build Coastguard Worker }
5537*ec779b8eSAndroid Build Coastguard Worker parent->clearInjectionParameters();
5538*ec779b8eSAndroid Build Coastguard Worker }
5539*ec779b8eSAndroid Build Coastguard Worker }
5540*ec779b8eSAndroid Build Coastguard Worker
5541*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5542*ec779b8eSAndroid Build Coastguard Worker // CameraInjectionSession
5543*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5544*ec779b8eSAndroid Build Coastguard Worker
stopInjection()5545*ec779b8eSAndroid Build Coastguard Worker binder::Status CameraService::CameraInjectionSession::stopInjection() {
5546*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mInjectionSessionLock);
5547*ec779b8eSAndroid Build Coastguard Worker auto parent = mParent.promote();
5548*ec779b8eSAndroid Build Coastguard Worker if (parent == nullptr) {
5549*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraInjectionSession: Parent is gone");
5550*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_SERVICE,
5551*ec779b8eSAndroid Build Coastguard Worker "Camera service encountered error");
5552*ec779b8eSAndroid Build Coastguard Worker }
5553*ec779b8eSAndroid Build Coastguard Worker
5554*ec779b8eSAndroid Build Coastguard Worker status_t res = NO_ERROR;
5555*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = parent->mActiveClientManager.get(parent->mInjectionInternalCamId);
5556*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor != nullptr) {
5557*ec779b8eSAndroid Build Coastguard Worker BasicClient* baseClientPtr = clientDescriptor->getValue().get();
5558*ec779b8eSAndroid Build Coastguard Worker res = baseClientPtr->stopInjection();
5559*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
5560*ec779b8eSAndroid Build Coastguard Worker ALOGE("CameraInjectionSession: Failed to stop the injection camera!"
5561*ec779b8eSAndroid Build Coastguard Worker " ret != NO_ERROR: %d", res);
5562*ec779b8eSAndroid Build Coastguard Worker return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_SESSION,
5563*ec779b8eSAndroid Build Coastguard Worker "Camera session encountered error");
5564*ec779b8eSAndroid Build Coastguard Worker }
5565*ec779b8eSAndroid Build Coastguard Worker }
5566*ec779b8eSAndroid Build Coastguard Worker parent->clearInjectionParameters();
5567*ec779b8eSAndroid Build Coastguard Worker return binder::Status::ok();
5568*ec779b8eSAndroid Build Coastguard Worker }
5569*ec779b8eSAndroid Build Coastguard Worker
5570*ec779b8eSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
5571*ec779b8eSAndroid Build Coastguard Worker
5572*ec779b8eSAndroid Build Coastguard Worker static const int kDumpLockRetries = 50;
5573*ec779b8eSAndroid Build Coastguard Worker static const int kDumpLockSleep = 60000;
5574*ec779b8eSAndroid Build Coastguard Worker
tryLock(Mutex & mutex)5575*ec779b8eSAndroid Build Coastguard Worker static bool tryLock(Mutex& mutex)
5576*ec779b8eSAndroid Build Coastguard Worker {
5577*ec779b8eSAndroid Build Coastguard Worker bool locked = false;
5578*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < kDumpLockRetries; ++i) {
5579*ec779b8eSAndroid Build Coastguard Worker if (mutex.tryLock() == NO_ERROR) {
5580*ec779b8eSAndroid Build Coastguard Worker locked = true;
5581*ec779b8eSAndroid Build Coastguard Worker break;
5582*ec779b8eSAndroid Build Coastguard Worker }
5583*ec779b8eSAndroid Build Coastguard Worker usleep(kDumpLockSleep);
5584*ec779b8eSAndroid Build Coastguard Worker }
5585*ec779b8eSAndroid Build Coastguard Worker return locked;
5586*ec779b8eSAndroid Build Coastguard Worker }
5587*ec779b8eSAndroid Build Coastguard Worker
cacheDump()5588*ec779b8eSAndroid Build Coastguard Worker void CameraService::cacheDump() {
5589*ec779b8eSAndroid Build Coastguard Worker if (mMemFd != -1) {
5590*ec779b8eSAndroid Build Coastguard Worker const Vector<String16> args;
5591*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
5592*ec779b8eSAndroid Build Coastguard Worker // Acquiring service lock here will avoid the deadlock since
5593*ec779b8eSAndroid Build Coastguard Worker // cacheDump will not be called during the second disconnect.
5594*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
5595*ec779b8eSAndroid Build Coastguard Worker
5596*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mCameraStatesLock);
5597*ec779b8eSAndroid Build Coastguard Worker // Start collecting the info for open sessions and store it in temp file.
5598*ec779b8eSAndroid Build Coastguard Worker for (const auto& state : mCameraStates) {
5599*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = state.first;
5600*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = mActiveClientManager.get(cameraId);
5601*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor != nullptr) {
5602*ec779b8eSAndroid Build Coastguard Worker dprintf(mMemFd, "== Camera device %s dynamic info: ==\n", cameraId.c_str());
5603*ec779b8eSAndroid Build Coastguard Worker // Log the current open session info before device is disconnected.
5604*ec779b8eSAndroid Build Coastguard Worker dumpOpenSessionClientLogs(mMemFd, args, cameraId);
5605*ec779b8eSAndroid Build Coastguard Worker }
5606*ec779b8eSAndroid Build Coastguard Worker }
5607*ec779b8eSAndroid Build Coastguard Worker }
5608*ec779b8eSAndroid Build Coastguard Worker }
5609*ec779b8eSAndroid Build Coastguard Worker
dump(int fd,const Vector<String16> & args)5610*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::dump(int fd, const Vector<String16>& args) {
5611*ec779b8eSAndroid Build Coastguard Worker ATRACE_CALL();
5612*ec779b8eSAndroid Build Coastguard Worker
5613*ec779b8eSAndroid Build Coastguard Worker if (checkCallingPermission(toString16(sDumpPermission)) == false) {
5614*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n",
5615*ec779b8eSAndroid Build Coastguard Worker getCallingPid(),
5616*ec779b8eSAndroid Build Coastguard Worker getCallingUid());
5617*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
5618*ec779b8eSAndroid Build Coastguard Worker }
5619*ec779b8eSAndroid Build Coastguard Worker bool locked = tryLock(mServiceLock);
5620*ec779b8eSAndroid Build Coastguard Worker // failed to lock - CameraService is probably deadlocked
5621*ec779b8eSAndroid Build Coastguard Worker if (!locked) {
5622*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "!! CameraService may be deadlocked !!\n");
5623*ec779b8eSAndroid Build Coastguard Worker }
5624*ec779b8eSAndroid Build Coastguard Worker
5625*ec779b8eSAndroid Build Coastguard Worker if (!mInitialized) {
5626*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "!! No camera HAL available !!\n");
5627*ec779b8eSAndroid Build Coastguard Worker
5628*ec779b8eSAndroid Build Coastguard Worker // Dump event log for error information
5629*ec779b8eSAndroid Build Coastguard Worker dumpEventLog(fd);
5630*ec779b8eSAndroid Build Coastguard Worker
5631*ec779b8eSAndroid Build Coastguard Worker if (locked) mServiceLock.unlock();
5632*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
5633*ec779b8eSAndroid Build Coastguard Worker }
5634*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n== Service global info: ==\n\n");
5635*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
5636*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
5637*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Number of public camera devices visible to API1: %zu\n",
5638*ec779b8eSAndroid Build Coastguard Worker mNormalDeviceIdsWithoutSystemCamera.size());
5639*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
5640*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
5641*ec779b8eSAndroid Build Coastguard Worker }
5642*ec779b8eSAndroid Build Coastguard Worker std::string activeClientString = mActiveClientManager.toString();
5643*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Active Camera Clients:\n%s", activeClientString.c_str());
5644*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).c_str());
5645*ec779b8eSAndroid Build Coastguard Worker if (mStreamUseCaseOverrides.size() > 0) {
5646*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "Active stream use case overrides:");
5647*ec779b8eSAndroid Build Coastguard Worker for (int64_t useCaseOverride : mStreamUseCaseOverrides) {
5648*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " %" PRId64, useCaseOverride);
5649*ec779b8eSAndroid Build Coastguard Worker }
5650*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n");
5651*ec779b8eSAndroid Build Coastguard Worker }
5652*ec779b8eSAndroid Build Coastguard Worker
5653*ec779b8eSAndroid Build Coastguard Worker dumpEventLog(fd);
5654*ec779b8eSAndroid Build Coastguard Worker
5655*ec779b8eSAndroid Build Coastguard Worker bool stateLocked = tryLock(mCameraStatesLock);
5656*ec779b8eSAndroid Build Coastguard Worker if (!stateLocked) {
5657*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "CameraStates in use, may be deadlocked\n");
5658*ec779b8eSAndroid Build Coastguard Worker }
5659*ec779b8eSAndroid Build Coastguard Worker
5660*ec779b8eSAndroid Build Coastguard Worker int argSize = args.size();
5661*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < argSize; i++) {
5662*ec779b8eSAndroid Build Coastguard Worker if (args[i] == toString16(TagMonitor::kMonitorOption)) {
5663*ec779b8eSAndroid Build Coastguard Worker if (i + 1 < argSize) {
5664*ec779b8eSAndroid Build Coastguard Worker mMonitorTags = toStdString(args[i + 1]);
5665*ec779b8eSAndroid Build Coastguard Worker }
5666*ec779b8eSAndroid Build Coastguard Worker break;
5667*ec779b8eSAndroid Build Coastguard Worker }
5668*ec779b8eSAndroid Build Coastguard Worker }
5669*ec779b8eSAndroid Build Coastguard Worker
5670*ec779b8eSAndroid Build Coastguard Worker for (auto& state : mCameraStates) {
5671*ec779b8eSAndroid Build Coastguard Worker const std::string &cameraId = state.first;
5672*ec779b8eSAndroid Build Coastguard Worker
5673*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.c_str());
5674*ec779b8eSAndroid Build Coastguard Worker
5675*ec779b8eSAndroid Build Coastguard Worker CameraParameters p = state.second->getShimParams();
5676*ec779b8eSAndroid Build Coastguard Worker if (!p.isEmpty()) {
5677*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " Camera1 API shim is using parameters:\n ");
5678*ec779b8eSAndroid Build Coastguard Worker p.dump(fd, args);
5679*ec779b8eSAndroid Build Coastguard Worker }
5680*ec779b8eSAndroid Build Coastguard Worker
5681*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = mActiveClientManager.get(cameraId);
5682*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor != nullptr) {
5683*ec779b8eSAndroid Build Coastguard Worker // log the current open session info
5684*ec779b8eSAndroid Build Coastguard Worker dumpOpenSessionClientLogs(fd, args, cameraId);
5685*ec779b8eSAndroid Build Coastguard Worker } else {
5686*ec779b8eSAndroid Build Coastguard Worker dumpClosedSessionClientLogs(fd, cameraId);
5687*ec779b8eSAndroid Build Coastguard Worker }
5688*ec779b8eSAndroid Build Coastguard Worker
5689*ec779b8eSAndroid Build Coastguard Worker }
5690*ec779b8eSAndroid Build Coastguard Worker
5691*ec779b8eSAndroid Build Coastguard Worker if (stateLocked) mCameraStatesLock.unlock();
5692*ec779b8eSAndroid Build Coastguard Worker
5693*ec779b8eSAndroid Build Coastguard Worker if (locked) mServiceLock.unlock();
5694*ec779b8eSAndroid Build Coastguard Worker
5695*ec779b8eSAndroid Build Coastguard Worker mCameraProviderManager->dump(fd, args);
5696*ec779b8eSAndroid Build Coastguard Worker
5697*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n== Vendor tags: ==\n\n");
5698*ec779b8eSAndroid Build Coastguard Worker
5699*ec779b8eSAndroid Build Coastguard Worker sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
5700*ec779b8eSAndroid Build Coastguard Worker if (desc == NULL) {
5701*ec779b8eSAndroid Build Coastguard Worker sp<VendorTagDescriptorCache> cache =
5702*ec779b8eSAndroid Build Coastguard Worker VendorTagDescriptorCache::getGlobalVendorTagCache();
5703*ec779b8eSAndroid Build Coastguard Worker if (cache == NULL) {
5704*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "No vendor tags.\n");
5705*ec779b8eSAndroid Build Coastguard Worker } else {
5706*ec779b8eSAndroid Build Coastguard Worker cache->dump(fd, /*verbosity*/2, /*indentation*/2);
5707*ec779b8eSAndroid Build Coastguard Worker }
5708*ec779b8eSAndroid Build Coastguard Worker } else {
5709*ec779b8eSAndroid Build Coastguard Worker desc->dump(fd, /*verbosity*/2, /*indentation*/2);
5710*ec779b8eSAndroid Build Coastguard Worker }
5711*ec779b8eSAndroid Build Coastguard Worker
5712*ec779b8eSAndroid Build Coastguard Worker // Dump camera traces if there were any
5713*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n");
5714*ec779b8eSAndroid Build Coastguard Worker camera3::CameraTraces::dump(fd);
5715*ec779b8eSAndroid Build Coastguard Worker
5716*ec779b8eSAndroid Build Coastguard Worker // Process dump arguments, if any
5717*ec779b8eSAndroid Build Coastguard Worker int n = args.size();
5718*ec779b8eSAndroid Build Coastguard Worker String16 verboseOption("-v");
5719*ec779b8eSAndroid Build Coastguard Worker String16 unreachableOption("--unreachable");
5720*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) {
5721*ec779b8eSAndroid Build Coastguard Worker if (args[i] == verboseOption) {
5722*ec779b8eSAndroid Build Coastguard Worker // change logging level
5723*ec779b8eSAndroid Build Coastguard Worker if (i + 1 >= n) continue;
5724*ec779b8eSAndroid Build Coastguard Worker std::string levelStr = toStdString(args[i+1]);
5725*ec779b8eSAndroid Build Coastguard Worker int level = atoi(levelStr.c_str());
5726*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\nSetting log level to %d.\n", level);
5727*ec779b8eSAndroid Build Coastguard Worker setLogLevel(level);
5728*ec779b8eSAndroid Build Coastguard Worker } else if (args[i] == unreachableOption) {
5729*ec779b8eSAndroid Build Coastguard Worker // Dump memory analysis
5730*ec779b8eSAndroid Build Coastguard Worker // TODO - should limit be an argument parameter?
5731*ec779b8eSAndroid Build Coastguard Worker UnreachableMemoryInfo info;
5732*ec779b8eSAndroid Build Coastguard Worker bool success = GetUnreachableMemory(info, /*limit*/ 10000);
5733*ec779b8eSAndroid Build Coastguard Worker if (!success) {
5734*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n== Unable to dump unreachable memory. "
5735*ec779b8eSAndroid Build Coastguard Worker "Try disabling SELinux enforcement. ==\n");
5736*ec779b8eSAndroid Build Coastguard Worker } else {
5737*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n== Dumping unreachable memory: ==\n");
5738*ec779b8eSAndroid Build Coastguard Worker std::string s = info.ToString(/*log_contents*/ true);
5739*ec779b8eSAndroid Build Coastguard Worker write(fd, s.c_str(), s.size());
5740*ec779b8eSAndroid Build Coastguard Worker }
5741*ec779b8eSAndroid Build Coastguard Worker }
5742*ec779b8eSAndroid Build Coastguard Worker }
5743*ec779b8eSAndroid Build Coastguard Worker
5744*ec779b8eSAndroid Build Coastguard Worker bool serviceLocked = tryLock(mServiceLock);
5745*ec779b8eSAndroid Build Coastguard Worker
5746*ec779b8eSAndroid Build Coastguard Worker // Dump info from previous open sessions.
5747*ec779b8eSAndroid Build Coastguard Worker // Reposition the offset to beginning of the file before reading
5748*ec779b8eSAndroid Build Coastguard Worker
5749*ec779b8eSAndroid Build Coastguard Worker if ((mMemFd >= 0) && (lseek(mMemFd, 0, SEEK_SET) != -1)) {
5750*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n**********Dumpsys from previous open session**********\n");
5751*ec779b8eSAndroid Build Coastguard Worker ssize_t size_read;
5752*ec779b8eSAndroid Build Coastguard Worker char buf[4096];
5753*ec779b8eSAndroid Build Coastguard Worker while ((size_read = read(mMemFd, buf, (sizeof(buf) - 1))) > 0) {
5754*ec779b8eSAndroid Build Coastguard Worker // Read data from file to a small buffer and write it to fd.
5755*ec779b8eSAndroid Build Coastguard Worker write(fd, buf, size_read);
5756*ec779b8eSAndroid Build Coastguard Worker if (size_read == -1) {
5757*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error during reading the file: %s", __FUNCTION__, sFileName);
5758*ec779b8eSAndroid Build Coastguard Worker break;
5759*ec779b8eSAndroid Build Coastguard Worker }
5760*ec779b8eSAndroid Build Coastguard Worker }
5761*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n**********End of Dumpsys from previous open session**********\n");
5762*ec779b8eSAndroid Build Coastguard Worker } else {
5763*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Error during reading the file: %s", __FUNCTION__, sFileName);
5764*ec779b8eSAndroid Build Coastguard Worker }
5765*ec779b8eSAndroid Build Coastguard Worker
5766*ec779b8eSAndroid Build Coastguard Worker if (serviceLocked) mServiceLock.unlock();
5767*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
5768*ec779b8eSAndroid Build Coastguard Worker }
5769*ec779b8eSAndroid Build Coastguard Worker
dumpOpenSessionClientLogs(int fd,const Vector<String16> & args,const std::string & cameraId)5770*ec779b8eSAndroid Build Coastguard Worker void CameraService::dumpOpenSessionClientLogs(int fd,
5771*ec779b8eSAndroid Build Coastguard Worker const Vector<String16>& args, const std::string& cameraId) {
5772*ec779b8eSAndroid Build Coastguard Worker auto clientDescriptor = mActiveClientManager.get(cameraId);
5773*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " %s : Device %s is open. Client instance dump:\n",
5774*ec779b8eSAndroid Build Coastguard Worker getFormattedCurrentTime().c_str(),
5775*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
5776*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " Client priority score: %d state: %d\n",
5777*ec779b8eSAndroid Build Coastguard Worker clientDescriptor->getPriority().getScore(),
5778*ec779b8eSAndroid Build Coastguard Worker clientDescriptor->getPriority().getState());
5779*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId());
5780*ec779b8eSAndroid Build Coastguard Worker
5781*ec779b8eSAndroid Build Coastguard Worker auto client = clientDescriptor->getValue();
5782*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " Client package: %s\n",
5783*ec779b8eSAndroid Build Coastguard Worker client->getPackageName().c_str());
5784*ec779b8eSAndroid Build Coastguard Worker
5785*ec779b8eSAndroid Build Coastguard Worker client->dumpClient(fd, args);
5786*ec779b8eSAndroid Build Coastguard Worker }
5787*ec779b8eSAndroid Build Coastguard Worker
dumpClosedSessionClientLogs(int fd,const std::string & cameraId)5788*ec779b8eSAndroid Build Coastguard Worker void CameraService::dumpClosedSessionClientLogs(int fd, const std::string& cameraId) {
5789*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " Device %s is closed, no client instance\n",
5790*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
5791*ec779b8eSAndroid Build Coastguard Worker }
5792*ec779b8eSAndroid Build Coastguard Worker
dumpEventLog(int fd)5793*ec779b8eSAndroid Build Coastguard Worker void CameraService::dumpEventLog(int fd) {
5794*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n== Camera service events log (most recent at top): ==\n");
5795*ec779b8eSAndroid Build Coastguard Worker
5796*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock l(mLogLock);
5797*ec779b8eSAndroid Build Coastguard Worker for (const auto& msg : mEventLog) {
5798*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " %s\n", msg.c_str());
5799*ec779b8eSAndroid Build Coastguard Worker }
5800*ec779b8eSAndroid Build Coastguard Worker
5801*ec779b8eSAndroid Build Coastguard Worker if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) {
5802*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " ...\n");
5803*ec779b8eSAndroid Build Coastguard Worker } else if (mEventLog.size() == 0) {
5804*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, " [no events yet]\n");
5805*ec779b8eSAndroid Build Coastguard Worker }
5806*ec779b8eSAndroid Build Coastguard Worker dprintf(fd, "\n");
5807*ec779b8eSAndroid Build Coastguard Worker }
5808*ec779b8eSAndroid Build Coastguard Worker
cacheClientTagDumpIfNeeded(const std::string & cameraId,BasicClient * client)5809*ec779b8eSAndroid Build Coastguard Worker void CameraService::cacheClientTagDumpIfNeeded(const std::string &cameraId, BasicClient* client) {
5810*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mLogLock);
5811*ec779b8eSAndroid Build Coastguard Worker if (!isClientWatchedLocked(client)) { return; }
5812*ec779b8eSAndroid Build Coastguard Worker
5813*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> dumpVector;
5814*ec779b8eSAndroid Build Coastguard Worker client->dumpWatchedEventsToVector(dumpVector);
5815*ec779b8eSAndroid Build Coastguard Worker
5816*ec779b8eSAndroid Build Coastguard Worker if (dumpVector.empty()) { return; }
5817*ec779b8eSAndroid Build Coastguard Worker
5818*ec779b8eSAndroid Build Coastguard Worker std::ostringstream dumpString;
5819*ec779b8eSAndroid Build Coastguard Worker
5820*ec779b8eSAndroid Build Coastguard Worker std::string currentTime = getFormattedCurrentTime();
5821*ec779b8eSAndroid Build Coastguard Worker dumpString << "Cached @ ";
5822*ec779b8eSAndroid Build Coastguard Worker dumpString << currentTime;
5823*ec779b8eSAndroid Build Coastguard Worker dumpString << "\n"; // First line is the timestamp of when client is cached.
5824*ec779b8eSAndroid Build Coastguard Worker
5825*ec779b8eSAndroid Build Coastguard Worker size_t i = dumpVector.size();
5826*ec779b8eSAndroid Build Coastguard Worker
5827*ec779b8eSAndroid Build Coastguard Worker // Store the string in reverse order (latest last)
5828*ec779b8eSAndroid Build Coastguard Worker while (i > 0) {
5829*ec779b8eSAndroid Build Coastguard Worker i--;
5830*ec779b8eSAndroid Build Coastguard Worker dumpString << cameraId;
5831*ec779b8eSAndroid Build Coastguard Worker dumpString << ":";
5832*ec779b8eSAndroid Build Coastguard Worker dumpString << client->getPackageName();
5833*ec779b8eSAndroid Build Coastguard Worker dumpString << " ";
5834*ec779b8eSAndroid Build Coastguard Worker dumpString << dumpVector[i]; // implicitly ends with '\n'
5835*ec779b8eSAndroid Build Coastguard Worker }
5836*ec779b8eSAndroid Build Coastguard Worker
5837*ec779b8eSAndroid Build Coastguard Worker mWatchedClientsDumpCache[client->getPackageName()] = dumpString.str();
5838*ec779b8eSAndroid Build Coastguard Worker }
5839*ec779b8eSAndroid Build Coastguard Worker
handleTorchClientBinderDied(const wp<IBinder> & who)5840*ec779b8eSAndroid Build Coastguard Worker void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) {
5841*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchClientMapMutex);
5842*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < mTorchClientMap.size(); i++) {
5843*ec779b8eSAndroid Build Coastguard Worker if (mTorchClientMap[i] == who) {
5844*ec779b8eSAndroid Build Coastguard Worker // turn off the torch mode that was turned on by dead client
5845*ec779b8eSAndroid Build Coastguard Worker std::string cameraId = mTorchClientMap.keyAt(i);
5846*ec779b8eSAndroid Build Coastguard Worker status_t res = mFlashlight->setTorchMode(cameraId, false);
5847*ec779b8eSAndroid Build Coastguard Worker if (res) {
5848*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: torch client died but couldn't turn off torch: "
5849*ec779b8eSAndroid Build Coastguard Worker "%s (%d)", __FUNCTION__, strerror(-res), res);
5850*ec779b8eSAndroid Build Coastguard Worker return;
5851*ec779b8eSAndroid Build Coastguard Worker }
5852*ec779b8eSAndroid Build Coastguard Worker mTorchClientMap.removeItemsAt(i);
5853*ec779b8eSAndroid Build Coastguard Worker break;
5854*ec779b8eSAndroid Build Coastguard Worker }
5855*ec779b8eSAndroid Build Coastguard Worker }
5856*ec779b8eSAndroid Build Coastguard Worker }
5857*ec779b8eSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> & who)5858*ec779b8eSAndroid Build Coastguard Worker /*virtual*/void CameraService::binderDied(const wp<IBinder> &who) {
5859*ec779b8eSAndroid Build Coastguard Worker
5860*ec779b8eSAndroid Build Coastguard Worker /**
5861*ec779b8eSAndroid Build Coastguard Worker * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the
5862*ec779b8eSAndroid Build Coastguard Worker * binder driver
5863*ec779b8eSAndroid Build Coastguard Worker */
5864*ec779b8eSAndroid Build Coastguard Worker // PID here is approximate and can be wrong.
5865*ec779b8eSAndroid Build Coastguard Worker logClientDied(getCallingPid(), "Binder died unexpectedly");
5866*ec779b8eSAndroid Build Coastguard Worker
5867*ec779b8eSAndroid Build Coastguard Worker // check torch client
5868*ec779b8eSAndroid Build Coastguard Worker handleTorchClientBinderDied(who);
5869*ec779b8eSAndroid Build Coastguard Worker
5870*ec779b8eSAndroid Build Coastguard Worker // check camera device client
5871*ec779b8eSAndroid Build Coastguard Worker if(!evictClientIdByRemote(who)) {
5872*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__);
5873*ec779b8eSAndroid Build Coastguard Worker return;
5874*ec779b8eSAndroid Build Coastguard Worker }
5875*ec779b8eSAndroid Build Coastguard Worker
5876*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Java client's binder died, removing it from the list of active clients",
5877*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
5878*ec779b8eSAndroid Build Coastguard Worker }
5879*ec779b8eSAndroid Build Coastguard Worker
updateStatus(StatusInternal status,const std::string & cameraId)5880*ec779b8eSAndroid Build Coastguard Worker void CameraService::updateStatus(StatusInternal status, const std::string& cameraId) {
5881*ec779b8eSAndroid Build Coastguard Worker updateStatus(status, cameraId, {});
5882*ec779b8eSAndroid Build Coastguard Worker }
5883*ec779b8eSAndroid Build Coastguard Worker
updateStatus(StatusInternal status,const std::string & cameraId,std::initializer_list<StatusInternal> rejectSourceStates)5884*ec779b8eSAndroid Build Coastguard Worker void CameraService::updateStatus(StatusInternal status, const std::string& cameraId,
5885*ec779b8eSAndroid Build Coastguard Worker std::initializer_list<StatusInternal> rejectSourceStates) {
5886*ec779b8eSAndroid Build Coastguard Worker // Do not lock mServiceLock here or can get into a deadlock from
5887*ec779b8eSAndroid Build Coastguard Worker // connect() -> disconnect -> updateStatus
5888*ec779b8eSAndroid Build Coastguard Worker
5889*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
5890*ec779b8eSAndroid Build Coastguard Worker
5891*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
5892*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
5893*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
5894*ec779b8eSAndroid Build Coastguard Worker return;
5895*ec779b8eSAndroid Build Coastguard Worker }
5896*ec779b8eSAndroid Build Coastguard Worker
5897*ec779b8eSAndroid Build Coastguard Worker // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275)
5898*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
5899*ec779b8eSAndroid Build Coastguard Worker if (getSystemCameraKind(cameraId, &deviceKind) != OK) {
5900*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str());
5901*ec779b8eSAndroid Build Coastguard Worker return;
5902*ec779b8eSAndroid Build Coastguard Worker }
5903*ec779b8eSAndroid Build Coastguard Worker
5904*ec779b8eSAndroid Build Coastguard Worker if (vd_flags::camera_device_awareness() && status == StatusInternal::PRESENT) {
5905*ec779b8eSAndroid Build Coastguard Worker CameraMetadata cameraInfo;
5906*ec779b8eSAndroid Build Coastguard Worker status_t res = mCameraProviderManager->getCameraCharacteristics(
5907*ec779b8eSAndroid Build Coastguard Worker cameraId, false, &cameraInfo, hardware::ICameraService::ROTATION_OVERRIDE_NONE);
5908*ec779b8eSAndroid Build Coastguard Worker if (res != OK) {
5909*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Not able to get camera characteristics for camera id %s",
5910*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, cameraId.c_str());
5911*ec779b8eSAndroid Build Coastguard Worker } else {
5912*ec779b8eSAndroid Build Coastguard Worker int32_t deviceId = getDeviceId(cameraInfo);
5913*ec779b8eSAndroid Build Coastguard Worker if (deviceId != kDefaultDeviceId) {
5914*ec779b8eSAndroid Build Coastguard Worker const auto &lensFacingEntry = cameraInfo.find(ANDROID_LENS_FACING);
5915*ec779b8eSAndroid Build Coastguard Worker camera_metadata_enum_android_lens_facing_t androidLensFacing =
5916*ec779b8eSAndroid Build Coastguard Worker static_cast<camera_metadata_enum_android_lens_facing_t>(
5917*ec779b8eSAndroid Build Coastguard Worker lensFacingEntry.data.u8[0]);
5918*ec779b8eSAndroid Build Coastguard Worker std::string mappedCameraId;
5919*ec779b8eSAndroid Build Coastguard Worker if (androidLensFacing == ANDROID_LENS_FACING_BACK) {
5920*ec779b8eSAndroid Build Coastguard Worker mappedCameraId = kVirtualDeviceBackCameraId;
5921*ec779b8eSAndroid Build Coastguard Worker } else if (androidLensFacing == ANDROID_LENS_FACING_FRONT) {
5922*ec779b8eSAndroid Build Coastguard Worker mappedCameraId = kVirtualDeviceFrontCameraId;
5923*ec779b8eSAndroid Build Coastguard Worker } else {
5924*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: Not adding entry for an external camera of a virtual device",
5925*ec779b8eSAndroid Build Coastguard Worker __func__);
5926*ec779b8eSAndroid Build Coastguard Worker }
5927*ec779b8eSAndroid Build Coastguard Worker if (!mappedCameraId.empty()) {
5928*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.addCamera(cameraId, deviceId, mappedCameraId);
5929*ec779b8eSAndroid Build Coastguard Worker }
5930*ec779b8eSAndroid Build Coastguard Worker }
5931*ec779b8eSAndroid Build Coastguard Worker }
5932*ec779b8eSAndroid Build Coastguard Worker }
5933*ec779b8eSAndroid Build Coastguard Worker
5934*ec779b8eSAndroid Build Coastguard Worker // Collect the logical cameras without holding mStatusLock in updateStatus
5935*ec779b8eSAndroid Build Coastguard Worker // as that can lead to a deadlock(b/162192331).
5936*ec779b8eSAndroid Build Coastguard Worker auto logicalCameraIds = getLogicalCameras(cameraId);
5937*ec779b8eSAndroid Build Coastguard Worker // Update the status for this camera state, then send the onStatusChangedCallbacks to each
5938*ec779b8eSAndroid Build Coastguard Worker // of the listeners with both the mStatusLock and mStatusListenerLock held
5939*ec779b8eSAndroid Build Coastguard Worker state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind,
5940*ec779b8eSAndroid Build Coastguard Worker &logicalCameraIds]
5941*ec779b8eSAndroid Build Coastguard Worker (const std::string& cameraId, StatusInternal status) {
5942*ec779b8eSAndroid Build Coastguard Worker // Get the device id and app-visible camera id for the given HAL-visible camera id.
5943*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, mappedCameraId] =
5944*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
5945*ec779b8eSAndroid Build Coastguard Worker
5946*ec779b8eSAndroid Build Coastguard Worker if (status != StatusInternal::ENUMERATING) {
5947*ec779b8eSAndroid Build Coastguard Worker // Update torch status if it has a flash unit.
5948*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock al(mTorchStatusMutex);
5949*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus torchStatus;
5950*ec779b8eSAndroid Build Coastguard Worker if (getTorchStatusLocked(cameraId, &torchStatus) !=
5951*ec779b8eSAndroid Build Coastguard Worker NAME_NOT_FOUND) {
5952*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus newTorchStatus =
5953*ec779b8eSAndroid Build Coastguard Worker status == StatusInternal::PRESENT ?
5954*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus::AVAILABLE_OFF :
5955*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus::NOT_AVAILABLE;
5956*ec779b8eSAndroid Build Coastguard Worker if (torchStatus != newTorchStatus) {
5957*ec779b8eSAndroid Build Coastguard Worker onTorchStatusChangedLocked(cameraId, newTorchStatus, deviceKind);
5958*ec779b8eSAndroid Build Coastguard Worker }
5959*ec779b8eSAndroid Build Coastguard Worker }
5960*ec779b8eSAndroid Build Coastguard Worker }
5961*ec779b8eSAndroid Build Coastguard Worker
5962*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
5963*ec779b8eSAndroid Build Coastguard Worker notifyPhysicalCameraStatusLocked(mapToInterface(status), mappedCameraId,
5964*ec779b8eSAndroid Build Coastguard Worker logicalCameraIds, deviceKind, deviceId);
5965*ec779b8eSAndroid Build Coastguard Worker
5966*ec779b8eSAndroid Build Coastguard Worker for (auto& listener : mListenerList) {
5967*ec779b8eSAndroid Build Coastguard Worker bool isVendorListener = listener->isVendorListener();
5968*ec779b8eSAndroid Build Coastguard Worker if (shouldSkipStatusUpdates(deviceKind, isVendorListener,
5969*ec779b8eSAndroid Build Coastguard Worker listener->getListenerPid(), listener->getListenerUid())) {
5970*ec779b8eSAndroid Build Coastguard Worker ALOGV("Skipping discovery callback for system-only camera device %s",
5971*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
5972*ec779b8eSAndroid Build Coastguard Worker continue;
5973*ec779b8eSAndroid Build Coastguard Worker }
5974*ec779b8eSAndroid Build Coastguard Worker
5975*ec779b8eSAndroid Build Coastguard Worker auto ret = listener->getListener()->onStatusChanged(mapToInterface(status),
5976*ec779b8eSAndroid Build Coastguard Worker mappedCameraId, deviceId);
5977*ec779b8eSAndroid Build Coastguard Worker listener->handleBinderStatus(ret,
5978*ec779b8eSAndroid Build Coastguard Worker "%s: Failed to trigger onStatusChanged callback for %d:%d: %d",
5979*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
5980*ec779b8eSAndroid Build Coastguard Worker ret.exceptionCode());
5981*ec779b8eSAndroid Build Coastguard Worker }
5982*ec779b8eSAndroid Build Coastguard Worker });
5983*ec779b8eSAndroid Build Coastguard Worker }
5984*ec779b8eSAndroid Build Coastguard Worker
updateOpenCloseStatus(const std::string & cameraId,bool open,const std::string & clientPackageName,bool sharedMode)5985*ec779b8eSAndroid Build Coastguard Worker void CameraService::updateOpenCloseStatus(const std::string& cameraId, bool open,
5986*ec779b8eSAndroid Build Coastguard Worker const std::string& clientPackageName, bool sharedMode) {
5987*ec779b8eSAndroid Build Coastguard Worker auto state = getCameraState(cameraId);
5988*ec779b8eSAndroid Build Coastguard Worker if (state == nullptr) {
5989*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__,
5990*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str());
5991*ec779b8eSAndroid Build Coastguard Worker return;
5992*ec779b8eSAndroid Build Coastguard Worker }
5993*ec779b8eSAndroid Build Coastguard Worker if (open) {
5994*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_multi_client() && sharedMode) {
5995*ec779b8eSAndroid Build Coastguard Worker state->addClientPackage(clientPackageName);
5996*ec779b8eSAndroid Build Coastguard Worker } else {
5997*ec779b8eSAndroid Build Coastguard Worker state->setClientPackage(clientPackageName);
5998*ec779b8eSAndroid Build Coastguard Worker }
5999*ec779b8eSAndroid Build Coastguard Worker } else {
6000*ec779b8eSAndroid Build Coastguard Worker if (flags::camera_multi_client() && sharedMode) {
6001*ec779b8eSAndroid Build Coastguard Worker state->removeClientPackage(clientPackageName);
6002*ec779b8eSAndroid Build Coastguard Worker } else {
6003*ec779b8eSAndroid Build Coastguard Worker state->setClientPackage(std::string());
6004*ec779b8eSAndroid Build Coastguard Worker }
6005*ec779b8eSAndroid Build Coastguard Worker }
6006*ec779b8eSAndroid Build Coastguard Worker
6007*ec779b8eSAndroid Build Coastguard Worker // Get the device id and app-visible camera id for the given HAL-visible camera id.
6008*ec779b8eSAndroid Build Coastguard Worker auto [deviceId, mappedCameraId] =
6009*ec779b8eSAndroid Build Coastguard Worker mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
6010*ec779b8eSAndroid Build Coastguard Worker
6011*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusListenerLock);
6012*ec779b8eSAndroid Build Coastguard Worker
6013*ec779b8eSAndroid Build Coastguard Worker for (const auto& it : mListenerList) {
6014*ec779b8eSAndroid Build Coastguard Worker if (!it->isOpenCloseCallbackAllowed()) {
6015*ec779b8eSAndroid Build Coastguard Worker continue;
6016*ec779b8eSAndroid Build Coastguard Worker }
6017*ec779b8eSAndroid Build Coastguard Worker
6018*ec779b8eSAndroid Build Coastguard Worker binder::Status ret;
6019*ec779b8eSAndroid Build Coastguard Worker if (open) {
6020*ec779b8eSAndroid Build Coastguard Worker ret = it->getListener()->onCameraOpened(mappedCameraId, clientPackageName,
6021*ec779b8eSAndroid Build Coastguard Worker deviceId);
6022*ec779b8eSAndroid Build Coastguard Worker } else {
6023*ec779b8eSAndroid Build Coastguard Worker if (!flags::camera_multi_client() || !sharedMode || (sharedMode &&
6024*ec779b8eSAndroid Build Coastguard Worker mActiveClientManager.getCameraClient(cameraId) == nullptr)) {
6025*ec779b8eSAndroid Build Coastguard Worker ret = it->getListener()->onCameraClosed(mappedCameraId, deviceId);
6026*ec779b8eSAndroid Build Coastguard Worker }
6027*ec779b8eSAndroid Build Coastguard Worker }
6028*ec779b8eSAndroid Build Coastguard Worker
6029*ec779b8eSAndroid Build Coastguard Worker it->handleBinderStatus(ret,
6030*ec779b8eSAndroid Build Coastguard Worker "%s: Failed to trigger onCameraOpened/onCameraClosed callback for %d:%d: %d",
6031*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode());
6032*ec779b8eSAndroid Build Coastguard Worker }
6033*ec779b8eSAndroid Build Coastguard Worker }
6034*ec779b8eSAndroid Build Coastguard Worker
6035*ec779b8eSAndroid Build Coastguard Worker template<class Func>
updateStatus(StatusInternal status,const std::string & cameraId,std::initializer_list<StatusInternal> rejectSourceStates,Func onStatusUpdatedLocked)6036*ec779b8eSAndroid Build Coastguard Worker void CameraService::CameraState::updateStatus(StatusInternal status,
6037*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId,
6038*ec779b8eSAndroid Build Coastguard Worker std::initializer_list<StatusInternal> rejectSourceStates,
6039*ec779b8eSAndroid Build Coastguard Worker Func onStatusUpdatedLocked) {
6040*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mStatusLock);
6041*ec779b8eSAndroid Build Coastguard Worker StatusInternal oldStatus = mStatus;
6042*ec779b8eSAndroid Build Coastguard Worker mStatus = status;
6043*ec779b8eSAndroid Build Coastguard Worker
6044*ec779b8eSAndroid Build Coastguard Worker if (oldStatus == status) {
6045*ec779b8eSAndroid Build Coastguard Worker return;
6046*ec779b8eSAndroid Build Coastguard Worker }
6047*ec779b8eSAndroid Build Coastguard Worker
6048*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
6049*ec779b8eSAndroid Build Coastguard Worker cameraId.c_str(), eToI(oldStatus), eToI(status));
6050*ec779b8eSAndroid Build Coastguard Worker
6051*ec779b8eSAndroid Build Coastguard Worker if (oldStatus == StatusInternal::NOT_PRESENT &&
6052*ec779b8eSAndroid Build Coastguard Worker (status != StatusInternal::PRESENT &&
6053*ec779b8eSAndroid Build Coastguard Worker status != StatusInternal::ENUMERATING)) {
6054*ec779b8eSAndroid Build Coastguard Worker
6055*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING",
6056*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__);
6057*ec779b8eSAndroid Build Coastguard Worker mStatus = oldStatus;
6058*ec779b8eSAndroid Build Coastguard Worker return;
6059*ec779b8eSAndroid Build Coastguard Worker }
6060*ec779b8eSAndroid Build Coastguard Worker
6061*ec779b8eSAndroid Build Coastguard Worker /**
6062*ec779b8eSAndroid Build Coastguard Worker * Sometimes we want to conditionally do a transition.
6063*ec779b8eSAndroid Build Coastguard Worker * For example if a client disconnects, we want to go to PRESENT
6064*ec779b8eSAndroid Build Coastguard Worker * only if we weren't already in NOT_PRESENT or ENUMERATING.
6065*ec779b8eSAndroid Build Coastguard Worker */
6066*ec779b8eSAndroid Build Coastguard Worker for (auto& rejectStatus : rejectSourceStates) {
6067*ec779b8eSAndroid Build Coastguard Worker if (oldStatus == rejectStatus) {
6068*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: Rejecting status transition for Camera ID %s, since the source "
6069*ec779b8eSAndroid Build Coastguard Worker "state was was in one of the bad states.", __FUNCTION__, cameraId.c_str());
6070*ec779b8eSAndroid Build Coastguard Worker mStatus = oldStatus;
6071*ec779b8eSAndroid Build Coastguard Worker return;
6072*ec779b8eSAndroid Build Coastguard Worker }
6073*ec779b8eSAndroid Build Coastguard Worker }
6074*ec779b8eSAndroid Build Coastguard Worker
6075*ec779b8eSAndroid Build Coastguard Worker onStatusUpdatedLocked(cameraId, status);
6076*ec779b8eSAndroid Build Coastguard Worker }
6077*ec779b8eSAndroid Build Coastguard Worker
getTorchStatusLocked(const std::string & cameraId,TorchModeStatus * status) const6078*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::getTorchStatusLocked(
6079*ec779b8eSAndroid Build Coastguard Worker const std::string& cameraId,
6080*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus *status) const {
6081*ec779b8eSAndroid Build Coastguard Worker if (!status) {
6082*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6083*ec779b8eSAndroid Build Coastguard Worker }
6084*ec779b8eSAndroid Build Coastguard Worker ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
6085*ec779b8eSAndroid Build Coastguard Worker if (index == NAME_NOT_FOUND) {
6086*ec779b8eSAndroid Build Coastguard Worker // invalid camera ID or the camera doesn't have a flash unit
6087*ec779b8eSAndroid Build Coastguard Worker return NAME_NOT_FOUND;
6088*ec779b8eSAndroid Build Coastguard Worker }
6089*ec779b8eSAndroid Build Coastguard Worker
6090*ec779b8eSAndroid Build Coastguard Worker *status = mTorchStatusMap.valueAt(index);
6091*ec779b8eSAndroid Build Coastguard Worker return OK;
6092*ec779b8eSAndroid Build Coastguard Worker }
6093*ec779b8eSAndroid Build Coastguard Worker
setTorchStatusLocked(const std::string & cameraId,TorchModeStatus status)6094*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::setTorchStatusLocked(const std::string& cameraId,
6095*ec779b8eSAndroid Build Coastguard Worker TorchModeStatus status) {
6096*ec779b8eSAndroid Build Coastguard Worker ssize_t index = mTorchStatusMap.indexOfKey(cameraId);
6097*ec779b8eSAndroid Build Coastguard Worker if (index == NAME_NOT_FOUND) {
6098*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6099*ec779b8eSAndroid Build Coastguard Worker }
6100*ec779b8eSAndroid Build Coastguard Worker mTorchStatusMap.editValueAt(index) = status;
6101*ec779b8eSAndroid Build Coastguard Worker
6102*ec779b8eSAndroid Build Coastguard Worker return OK;
6103*ec779b8eSAndroid Build Coastguard Worker }
6104*ec779b8eSAndroid Build Coastguard Worker
getLogicalCameras(const std::string & physicalCameraId)6105*ec779b8eSAndroid Build Coastguard Worker std::list<std::string> CameraService::getLogicalCameras(
6106*ec779b8eSAndroid Build Coastguard Worker const std::string& physicalCameraId) {
6107*ec779b8eSAndroid Build Coastguard Worker std::list<std::string> retList;
6108*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mCameraStatesLock);
6109*ec779b8eSAndroid Build Coastguard Worker for (const auto& state : mCameraStates) {
6110*ec779b8eSAndroid Build Coastguard Worker if (state.second->containsPhysicalCamera(physicalCameraId)) {
6111*ec779b8eSAndroid Build Coastguard Worker retList.emplace_back(state.first);
6112*ec779b8eSAndroid Build Coastguard Worker }
6113*ec779b8eSAndroid Build Coastguard Worker }
6114*ec779b8eSAndroid Build Coastguard Worker return retList;
6115*ec779b8eSAndroid Build Coastguard Worker }
6116*ec779b8eSAndroid Build Coastguard Worker
notifyPhysicalCameraStatusLocked(int32_t status,const std::string & physicalCameraId,const std::list<std::string> & logicalCameraIds,SystemCameraKind deviceKind,int32_t deviceId)6117*ec779b8eSAndroid Build Coastguard Worker void CameraService::notifyPhysicalCameraStatusLocked(int32_t status,
6118*ec779b8eSAndroid Build Coastguard Worker const std::string& physicalCameraId, const std::list<std::string>& logicalCameraIds,
6119*ec779b8eSAndroid Build Coastguard Worker SystemCameraKind deviceKind, int32_t deviceId) {
6120*ec779b8eSAndroid Build Coastguard Worker // mStatusListenerLock is expected to be locked
6121*ec779b8eSAndroid Build Coastguard Worker for (const auto& logicalCameraId : logicalCameraIds) {
6122*ec779b8eSAndroid Build Coastguard Worker for (auto& listener : mListenerList) {
6123*ec779b8eSAndroid Build Coastguard Worker // Note: we check only the deviceKind of the physical camera id
6124*ec779b8eSAndroid Build Coastguard Worker // since, logical camera ids and their physical camera ids are
6125*ec779b8eSAndroid Build Coastguard Worker // guaranteed to have the same system camera kind.
6126*ec779b8eSAndroid Build Coastguard Worker if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(),
6127*ec779b8eSAndroid Build Coastguard Worker listener->getListenerPid(), listener->getListenerUid())) {
6128*ec779b8eSAndroid Build Coastguard Worker ALOGV("Skipping discovery callback for system-only camera device %s",
6129*ec779b8eSAndroid Build Coastguard Worker physicalCameraId.c_str());
6130*ec779b8eSAndroid Build Coastguard Worker continue;
6131*ec779b8eSAndroid Build Coastguard Worker }
6132*ec779b8eSAndroid Build Coastguard Worker auto ret = listener->getListener()->onPhysicalCameraStatusChanged(status,
6133*ec779b8eSAndroid Build Coastguard Worker logicalCameraId, physicalCameraId, deviceId);
6134*ec779b8eSAndroid Build Coastguard Worker listener->handleBinderStatus(ret,
6135*ec779b8eSAndroid Build Coastguard Worker "%s: Failed to trigger onPhysicalCameraStatusChanged for %d:%d: %d",
6136*ec779b8eSAndroid Build Coastguard Worker __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(),
6137*ec779b8eSAndroid Build Coastguard Worker ret.exceptionCode());
6138*ec779b8eSAndroid Build Coastguard Worker }
6139*ec779b8eSAndroid Build Coastguard Worker }
6140*ec779b8eSAndroid Build Coastguard Worker }
6141*ec779b8eSAndroid Build Coastguard Worker
blockClientsForUid(uid_t uid)6142*ec779b8eSAndroid Build Coastguard Worker void CameraService::blockClientsForUid(uid_t uid) {
6143*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6144*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6145*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6146*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6147*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) {
6148*ec779b8eSAndroid Build Coastguard Worker basicClient->block();
6149*ec779b8eSAndroid Build Coastguard Worker }
6150*ec779b8eSAndroid Build Coastguard Worker }
6151*ec779b8eSAndroid Build Coastguard Worker }
6152*ec779b8eSAndroid Build Coastguard Worker }
6153*ec779b8eSAndroid Build Coastguard Worker
blockAllClients()6154*ec779b8eSAndroid Build Coastguard Worker void CameraService::blockAllClients() {
6155*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6156*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6157*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6158*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6159*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6160*ec779b8eSAndroid Build Coastguard Worker basicClient->block();
6161*ec779b8eSAndroid Build Coastguard Worker }
6162*ec779b8eSAndroid Build Coastguard Worker }
6163*ec779b8eSAndroid Build Coastguard Worker }
6164*ec779b8eSAndroid Build Coastguard Worker }
6165*ec779b8eSAndroid Build Coastguard Worker
blockPrivacyEnabledClients()6166*ec779b8eSAndroid Build Coastguard Worker void CameraService::blockPrivacyEnabledClients() {
6167*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6168*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6169*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6170*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6171*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6172*ec779b8eSAndroid Build Coastguard Worker std::string pkgName = basicClient->getPackageName();
6173*ec779b8eSAndroid Build Coastguard Worker bool cameraPrivacyEnabled =
6174*ec779b8eSAndroid Build Coastguard Worker mSensorPrivacyPolicy->isCameraPrivacyEnabled(toString16(pkgName));
6175*ec779b8eSAndroid Build Coastguard Worker if (cameraPrivacyEnabled) {
6176*ec779b8eSAndroid Build Coastguard Worker basicClient->block();
6177*ec779b8eSAndroid Build Coastguard Worker }
6178*ec779b8eSAndroid Build Coastguard Worker }
6179*ec779b8eSAndroid Build Coastguard Worker }
6180*ec779b8eSAndroid Build Coastguard Worker }
6181*ec779b8eSAndroid Build Coastguard Worker }
6182*ec779b8eSAndroid Build Coastguard Worker
6183*ec779b8eSAndroid Build Coastguard Worker // NOTE: This is a remote API - make sure all args are validated
shellCommand(int in,int out,int err,const Vector<String16> & args)6184*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
6185*ec779b8eSAndroid Build Coastguard Worker if (!checkCallingPermission(toString16(sManageCameraPermission), nullptr, nullptr)) {
6186*ec779b8eSAndroid Build Coastguard Worker return PERMISSION_DENIED;
6187*ec779b8eSAndroid Build Coastguard Worker }
6188*ec779b8eSAndroid Build Coastguard Worker if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
6189*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6190*ec779b8eSAndroid Build Coastguard Worker }
6191*ec779b8eSAndroid Build Coastguard Worker if (args.size() >= 3 && args[0] == toString16("set-uid-state")) {
6192*ec779b8eSAndroid Build Coastguard Worker return handleSetUidState(args, err);
6193*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("reset-uid-state")) {
6194*ec779b8eSAndroid Build Coastguard Worker return handleResetUidState(args, err);
6195*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("get-uid-state")) {
6196*ec779b8eSAndroid Build Coastguard Worker return handleGetUidState(args, out, err);
6197*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("set-rotate-and-crop")) {
6198*ec779b8eSAndroid Build Coastguard Worker return handleSetRotateAndCrop(args);
6199*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 1 && args[0] == toString16("get-rotate-and-crop")) {
6200*ec779b8eSAndroid Build Coastguard Worker return handleGetRotateAndCrop(out);
6201*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("set-autoframing")) {
6202*ec779b8eSAndroid Build Coastguard Worker return handleSetAutoframing(args);
6203*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 1 && args[0] == toString16("get-autoframing")) {
6204*ec779b8eSAndroid Build Coastguard Worker return handleGetAutoframing(out);
6205*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("set-image-dump-mask")) {
6206*ec779b8eSAndroid Build Coastguard Worker return handleSetImageDumpMask(args);
6207*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 1 && args[0] == toString16("get-image-dump-mask")) {
6208*ec779b8eSAndroid Build Coastguard Worker return handleGetImageDumpMask(out);
6209*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("set-camera-mute")) {
6210*ec779b8eSAndroid Build Coastguard Worker return handleSetCameraMute(args);
6211*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("set-stream-use-case-override")) {
6212*ec779b8eSAndroid Build Coastguard Worker return handleSetStreamUseCaseOverrides(args);
6213*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 1 && args[0] == toString16("clear-stream-use-case-override")) {
6214*ec779b8eSAndroid Build Coastguard Worker handleClearStreamUseCaseOverrides();
6215*ec779b8eSAndroid Build Coastguard Worker return OK;
6216*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 1 && args[0] == toString16("set-zoom-override")) {
6217*ec779b8eSAndroid Build Coastguard Worker return handleSetZoomOverride(args);
6218*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("watch")) {
6219*ec779b8eSAndroid Build Coastguard Worker return handleWatchCommand(args, in, out);
6220*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[0] == toString16("set-watchdog")) {
6221*ec779b8eSAndroid Build Coastguard Worker return handleSetCameraServiceWatchdog(args);
6222*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() == 1 && args[0] == toString16("help")) {
6223*ec779b8eSAndroid Build Coastguard Worker printHelp(out);
6224*ec779b8eSAndroid Build Coastguard Worker return OK;
6225*ec779b8eSAndroid Build Coastguard Worker }
6226*ec779b8eSAndroid Build Coastguard Worker printHelp(err);
6227*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6228*ec779b8eSAndroid Build Coastguard Worker }
6229*ec779b8eSAndroid Build Coastguard Worker
handleSetUidState(const Vector<String16> & args,int err)6230*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) {
6231*ec779b8eSAndroid Build Coastguard Worker std::string packageName = toStdString(args[1]);
6232*ec779b8eSAndroid Build Coastguard Worker
6233*ec779b8eSAndroid Build Coastguard Worker bool active = false;
6234*ec779b8eSAndroid Build Coastguard Worker if (args[2] == toString16("active")) {
6235*ec779b8eSAndroid Build Coastguard Worker active = true;
6236*ec779b8eSAndroid Build Coastguard Worker } else if ((args[2] != toString16("idle"))) {
6237*ec779b8eSAndroid Build Coastguard Worker ALOGE("Expected active or idle but got: '%s'", toStdString(args[2]).c_str());
6238*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6239*ec779b8eSAndroid Build Coastguard Worker }
6240*ec779b8eSAndroid Build Coastguard Worker
6241*ec779b8eSAndroid Build Coastguard Worker int userId = 0;
6242*ec779b8eSAndroid Build Coastguard Worker if (args.size() >= 5 && args[3] == toString16("--user")) {
6243*ec779b8eSAndroid Build Coastguard Worker userId = atoi(toStdString(args[4]).c_str());
6244*ec779b8eSAndroid Build Coastguard Worker }
6245*ec779b8eSAndroid Build Coastguard Worker
6246*ec779b8eSAndroid Build Coastguard Worker uid_t uid;
6247*ec779b8eSAndroid Build Coastguard Worker if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) {
6248*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6249*ec779b8eSAndroid Build Coastguard Worker }
6250*ec779b8eSAndroid Build Coastguard Worker
6251*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->addOverrideUid(uid, packageName, active);
6252*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
6253*ec779b8eSAndroid Build Coastguard Worker }
6254*ec779b8eSAndroid Build Coastguard Worker
handleResetUidState(const Vector<String16> & args,int err)6255*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) {
6256*ec779b8eSAndroid Build Coastguard Worker std::string packageName = toStdString(args[1]);
6257*ec779b8eSAndroid Build Coastguard Worker
6258*ec779b8eSAndroid Build Coastguard Worker int userId = 0;
6259*ec779b8eSAndroid Build Coastguard Worker if (args.size() >= 4 && args[2] == toString16("--user")) {
6260*ec779b8eSAndroid Build Coastguard Worker userId = atoi(toStdString(args[3]).c_str());
6261*ec779b8eSAndroid Build Coastguard Worker }
6262*ec779b8eSAndroid Build Coastguard Worker
6263*ec779b8eSAndroid Build Coastguard Worker uid_t uid;
6264*ec779b8eSAndroid Build Coastguard Worker if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) {
6265*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6266*ec779b8eSAndroid Build Coastguard Worker }
6267*ec779b8eSAndroid Build Coastguard Worker
6268*ec779b8eSAndroid Build Coastguard Worker mUidPolicy->removeOverrideUid(uid, packageName);
6269*ec779b8eSAndroid Build Coastguard Worker return NO_ERROR;
6270*ec779b8eSAndroid Build Coastguard Worker }
6271*ec779b8eSAndroid Build Coastguard Worker
handleGetUidState(const Vector<String16> & args,int out,int err)6272*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) {
6273*ec779b8eSAndroid Build Coastguard Worker std::string packageName = toStdString(args[1]);
6274*ec779b8eSAndroid Build Coastguard Worker
6275*ec779b8eSAndroid Build Coastguard Worker int userId = 0;
6276*ec779b8eSAndroid Build Coastguard Worker if (args.size() >= 4 && args[2] == toString16("--user")) {
6277*ec779b8eSAndroid Build Coastguard Worker userId = atoi(toStdString(args[3]).c_str());
6278*ec779b8eSAndroid Build Coastguard Worker }
6279*ec779b8eSAndroid Build Coastguard Worker
6280*ec779b8eSAndroid Build Coastguard Worker uid_t uid;
6281*ec779b8eSAndroid Build Coastguard Worker if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) {
6282*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6283*ec779b8eSAndroid Build Coastguard Worker }
6284*ec779b8eSAndroid Build Coastguard Worker
6285*ec779b8eSAndroid Build Coastguard Worker if (mUidPolicy->isUidActive(uid, packageName)) {
6286*ec779b8eSAndroid Build Coastguard Worker return dprintf(out, "active\n");
6287*ec779b8eSAndroid Build Coastguard Worker } else {
6288*ec779b8eSAndroid Build Coastguard Worker return dprintf(out, "idle\n");
6289*ec779b8eSAndroid Build Coastguard Worker }
6290*ec779b8eSAndroid Build Coastguard Worker }
6291*ec779b8eSAndroid Build Coastguard Worker
handleSetRotateAndCrop(const Vector<String16> & args)6292*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) {
6293*ec779b8eSAndroid Build Coastguard Worker int rotateValue = atoi(toStdString(args[1]).c_str());
6294*ec779b8eSAndroid Build Coastguard Worker if (rotateValue < ANDROID_SCALER_ROTATE_AND_CROP_NONE ||
6295*ec779b8eSAndroid Build Coastguard Worker rotateValue > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
6296*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6297*ec779b8eSAndroid Build Coastguard Worker
6298*ec779b8eSAndroid Build Coastguard Worker mOverrideRotateAndCropMode = rotateValue;
6299*ec779b8eSAndroid Build Coastguard Worker
6300*ec779b8eSAndroid Build Coastguard Worker if (rotateValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return OK;
6301*ec779b8eSAndroid Build Coastguard Worker
6302*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6303*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6304*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6305*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6306*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6307*ec779b8eSAndroid Build Coastguard Worker basicClient->setRotateAndCropOverride(rotateValue);
6308*ec779b8eSAndroid Build Coastguard Worker }
6309*ec779b8eSAndroid Build Coastguard Worker }
6310*ec779b8eSAndroid Build Coastguard Worker }
6311*ec779b8eSAndroid Build Coastguard Worker
6312*ec779b8eSAndroid Build Coastguard Worker return OK;
6313*ec779b8eSAndroid Build Coastguard Worker }
6314*ec779b8eSAndroid Build Coastguard Worker
handleSetAutoframing(const Vector<String16> & args)6315*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetAutoframing(const Vector<String16>& args) {
6316*ec779b8eSAndroid Build Coastguard Worker char* end;
6317*ec779b8eSAndroid Build Coastguard Worker int autoframingValue = (int) strtol(toStdString(args[1]).c_str(), &end, /*base=*/10);
6318*ec779b8eSAndroid Build Coastguard Worker if ((*end != '\0') ||
6319*ec779b8eSAndroid Build Coastguard Worker (autoframingValue != ANDROID_CONTROL_AUTOFRAMING_OFF &&
6320*ec779b8eSAndroid Build Coastguard Worker autoframingValue != ANDROID_CONTROL_AUTOFRAMING_ON &&
6321*ec779b8eSAndroid Build Coastguard Worker autoframingValue != ANDROID_CONTROL_AUTOFRAMING_AUTO)) {
6322*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6323*ec779b8eSAndroid Build Coastguard Worker }
6324*ec779b8eSAndroid Build Coastguard Worker
6325*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6326*ec779b8eSAndroid Build Coastguard Worker mOverrideAutoframingMode = autoframingValue;
6327*ec779b8eSAndroid Build Coastguard Worker
6328*ec779b8eSAndroid Build Coastguard Worker if (autoframingValue == ANDROID_CONTROL_AUTOFRAMING_AUTO) return OK;
6329*ec779b8eSAndroid Build Coastguard Worker
6330*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6331*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6332*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6333*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6334*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6335*ec779b8eSAndroid Build Coastguard Worker basicClient->setAutoframingOverride(autoframingValue);
6336*ec779b8eSAndroid Build Coastguard Worker }
6337*ec779b8eSAndroid Build Coastguard Worker }
6338*ec779b8eSAndroid Build Coastguard Worker }
6339*ec779b8eSAndroid Build Coastguard Worker
6340*ec779b8eSAndroid Build Coastguard Worker return OK;
6341*ec779b8eSAndroid Build Coastguard Worker }
6342*ec779b8eSAndroid Build Coastguard Worker
handleSetCameraServiceWatchdog(const Vector<String16> & args)6343*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetCameraServiceWatchdog(const Vector<String16>& args) {
6344*ec779b8eSAndroid Build Coastguard Worker int enableWatchdog = atoi(toStdString(args[1]).c_str());
6345*ec779b8eSAndroid Build Coastguard Worker
6346*ec779b8eSAndroid Build Coastguard Worker if (enableWatchdog < 0 || enableWatchdog > 1) return BAD_VALUE;
6347*ec779b8eSAndroid Build Coastguard Worker
6348*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6349*ec779b8eSAndroid Build Coastguard Worker
6350*ec779b8eSAndroid Build Coastguard Worker mCameraServiceWatchdogEnabled = enableWatchdog;
6351*ec779b8eSAndroid Build Coastguard Worker
6352*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6353*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6354*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6355*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6356*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6357*ec779b8eSAndroid Build Coastguard Worker basicClient->setCameraServiceWatchdog(enableWatchdog);
6358*ec779b8eSAndroid Build Coastguard Worker }
6359*ec779b8eSAndroid Build Coastguard Worker }
6360*ec779b8eSAndroid Build Coastguard Worker }
6361*ec779b8eSAndroid Build Coastguard Worker
6362*ec779b8eSAndroid Build Coastguard Worker return OK;
6363*ec779b8eSAndroid Build Coastguard Worker }
6364*ec779b8eSAndroid Build Coastguard Worker
handleGetRotateAndCrop(int out)6365*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleGetRotateAndCrop(int out) {
6366*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6367*ec779b8eSAndroid Build Coastguard Worker
6368*ec779b8eSAndroid Build Coastguard Worker return dprintf(out, "rotateAndCrop override: %d\n", mOverrideRotateAndCropMode);
6369*ec779b8eSAndroid Build Coastguard Worker }
6370*ec779b8eSAndroid Build Coastguard Worker
handleGetAutoframing(int out)6371*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleGetAutoframing(int out) {
6372*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6373*ec779b8eSAndroid Build Coastguard Worker
6374*ec779b8eSAndroid Build Coastguard Worker return dprintf(out, "autoframing override: %d\n", mOverrideAutoframingMode);
6375*ec779b8eSAndroid Build Coastguard Worker }
6376*ec779b8eSAndroid Build Coastguard Worker
handleSetImageDumpMask(const Vector<String16> & args)6377*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetImageDumpMask(const Vector<String16>& args) {
6378*ec779b8eSAndroid Build Coastguard Worker char *endPtr;
6379*ec779b8eSAndroid Build Coastguard Worker errno = 0;
6380*ec779b8eSAndroid Build Coastguard Worker std::string maskString = toStdString(args[1]);
6381*ec779b8eSAndroid Build Coastguard Worker long maskValue = strtol(maskString.c_str(), &endPtr, 10);
6382*ec779b8eSAndroid Build Coastguard Worker
6383*ec779b8eSAndroid Build Coastguard Worker if (errno != 0) return BAD_VALUE;
6384*ec779b8eSAndroid Build Coastguard Worker if (endPtr != maskString.c_str() + maskString.size()) return BAD_VALUE;
6385*ec779b8eSAndroid Build Coastguard Worker if (maskValue < 0 || maskValue > 1) return BAD_VALUE;
6386*ec779b8eSAndroid Build Coastguard Worker
6387*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6388*ec779b8eSAndroid Build Coastguard Worker
6389*ec779b8eSAndroid Build Coastguard Worker mImageDumpMask = maskValue;
6390*ec779b8eSAndroid Build Coastguard Worker
6391*ec779b8eSAndroid Build Coastguard Worker return OK;
6392*ec779b8eSAndroid Build Coastguard Worker }
6393*ec779b8eSAndroid Build Coastguard Worker
handleGetImageDumpMask(int out)6394*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleGetImageDumpMask(int out) {
6395*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6396*ec779b8eSAndroid Build Coastguard Worker
6397*ec779b8eSAndroid Build Coastguard Worker return dprintf(out, "Image dump mask: %d\n", mImageDumpMask);
6398*ec779b8eSAndroid Build Coastguard Worker }
6399*ec779b8eSAndroid Build Coastguard Worker
handleSetCameraMute(const Vector<String16> & args)6400*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetCameraMute(const Vector<String16>& args) {
6401*ec779b8eSAndroid Build Coastguard Worker int muteValue = strtol(toStdString(args[1]).c_str(), nullptr, 10);
6402*ec779b8eSAndroid Build Coastguard Worker if (errno != 0) return BAD_VALUE;
6403*ec779b8eSAndroid Build Coastguard Worker
6404*ec779b8eSAndroid Build Coastguard Worker if (muteValue < 0 || muteValue > 1) return BAD_VALUE;
6405*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6406*ec779b8eSAndroid Build Coastguard Worker
6407*ec779b8eSAndroid Build Coastguard Worker mOverrideCameraMuteMode = (muteValue == 1);
6408*ec779b8eSAndroid Build Coastguard Worker
6409*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6410*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6411*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6412*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6413*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6414*ec779b8eSAndroid Build Coastguard Worker if (basicClient->supportsCameraMute()) {
6415*ec779b8eSAndroid Build Coastguard Worker basicClient->setCameraMute(mOverrideCameraMuteMode);
6416*ec779b8eSAndroid Build Coastguard Worker }
6417*ec779b8eSAndroid Build Coastguard Worker }
6418*ec779b8eSAndroid Build Coastguard Worker }
6419*ec779b8eSAndroid Build Coastguard Worker }
6420*ec779b8eSAndroid Build Coastguard Worker
6421*ec779b8eSAndroid Build Coastguard Worker return OK;
6422*ec779b8eSAndroid Build Coastguard Worker }
6423*ec779b8eSAndroid Build Coastguard Worker
handleSetStreamUseCaseOverrides(const Vector<String16> & args)6424*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetStreamUseCaseOverrides(const Vector<String16>& args) {
6425*ec779b8eSAndroid Build Coastguard Worker std::vector<int64_t> useCasesOverride;
6426*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 1; i < args.size(); i++) {
6427*ec779b8eSAndroid Build Coastguard Worker int64_t useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
6428*ec779b8eSAndroid Build Coastguard Worker std::string arg = toStdString(args[i]);
6429*ec779b8eSAndroid Build Coastguard Worker if (arg == "DEFAULT") {
6430*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
6431*ec779b8eSAndroid Build Coastguard Worker } else if (arg == "PREVIEW") {
6432*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW;
6433*ec779b8eSAndroid Build Coastguard Worker } else if (arg == "STILL_CAPTURE") {
6434*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE;
6435*ec779b8eSAndroid Build Coastguard Worker } else if (arg == "VIDEO_RECORD") {
6436*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD;
6437*ec779b8eSAndroid Build Coastguard Worker } else if (arg == "PREVIEW_VIDEO_STILL") {
6438*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL;
6439*ec779b8eSAndroid Build Coastguard Worker } else if (arg == "VIDEO_CALL") {
6440*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL;
6441*ec779b8eSAndroid Build Coastguard Worker } else if (arg == "CROPPED_RAW") {
6442*ec779b8eSAndroid Build Coastguard Worker useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW;
6443*ec779b8eSAndroid Build Coastguard Worker } else {
6444*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg.c_str());
6445*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6446*ec779b8eSAndroid Build Coastguard Worker }
6447*ec779b8eSAndroid Build Coastguard Worker useCasesOverride.push_back(useCase);
6448*ec779b8eSAndroid Build Coastguard Worker }
6449*ec779b8eSAndroid Build Coastguard Worker
6450*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6451*ec779b8eSAndroid Build Coastguard Worker mStreamUseCaseOverrides = std::move(useCasesOverride);
6452*ec779b8eSAndroid Build Coastguard Worker
6453*ec779b8eSAndroid Build Coastguard Worker return OK;
6454*ec779b8eSAndroid Build Coastguard Worker }
6455*ec779b8eSAndroid Build Coastguard Worker
handleClearStreamUseCaseOverrides()6456*ec779b8eSAndroid Build Coastguard Worker void CameraService::handleClearStreamUseCaseOverrides() {
6457*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6458*ec779b8eSAndroid Build Coastguard Worker mStreamUseCaseOverrides.clear();
6459*ec779b8eSAndroid Build Coastguard Worker }
6460*ec779b8eSAndroid Build Coastguard Worker
handleSetZoomOverride(const Vector<String16> & args)6461*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleSetZoomOverride(const Vector<String16>& args) {
6462*ec779b8eSAndroid Build Coastguard Worker char* end;
6463*ec779b8eSAndroid Build Coastguard Worker int zoomOverrideValue = strtol(toStdString(args[1]).c_str(), &end, /*base=*/10);
6464*ec779b8eSAndroid Build Coastguard Worker if ((*end != '\0') ||
6465*ec779b8eSAndroid Build Coastguard Worker (zoomOverrideValue != -1 &&
6466*ec779b8eSAndroid Build Coastguard Worker zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF &&
6467*ec779b8eSAndroid Build Coastguard Worker zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM)) {
6468*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6469*ec779b8eSAndroid Build Coastguard Worker }
6470*ec779b8eSAndroid Build Coastguard Worker
6471*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6472*ec779b8eSAndroid Build Coastguard Worker mZoomOverrideValue = zoomOverrideValue;
6473*ec779b8eSAndroid Build Coastguard Worker
6474*ec779b8eSAndroid Build Coastguard Worker const auto clients = mActiveClientManager.getAll();
6475*ec779b8eSAndroid Build Coastguard Worker for (auto& current : clients) {
6476*ec779b8eSAndroid Build Coastguard Worker if (current != nullptr) {
6477*ec779b8eSAndroid Build Coastguard Worker const auto basicClient = current->getValue();
6478*ec779b8eSAndroid Build Coastguard Worker if (basicClient.get() != nullptr) {
6479*ec779b8eSAndroid Build Coastguard Worker if (basicClient->supportsZoomOverride()) {
6480*ec779b8eSAndroid Build Coastguard Worker basicClient->setZoomOverride(mZoomOverrideValue);
6481*ec779b8eSAndroid Build Coastguard Worker }
6482*ec779b8eSAndroid Build Coastguard Worker }
6483*ec779b8eSAndroid Build Coastguard Worker }
6484*ec779b8eSAndroid Build Coastguard Worker }
6485*ec779b8eSAndroid Build Coastguard Worker
6486*ec779b8eSAndroid Build Coastguard Worker return OK;
6487*ec779b8eSAndroid Build Coastguard Worker }
6488*ec779b8eSAndroid Build Coastguard Worker
handleWatchCommand(const Vector<String16> & args,int inFd,int outFd)6489*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) {
6490*ec779b8eSAndroid Build Coastguard Worker if (args.size() >= 3 && args[1] == toString16("start")) {
6491*ec779b8eSAndroid Build Coastguard Worker return startWatchingTags(args, outFd);
6492*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() == 2 && args[1] == toString16("stop")) {
6493*ec779b8eSAndroid Build Coastguard Worker return stopWatchingTags(outFd);
6494*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() == 2 && args[1] == toString16("dump")) {
6495*ec779b8eSAndroid Build Coastguard Worker return printWatchedTags(outFd);
6496*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() >= 2 && args[1] == toString16("live")) {
6497*ec779b8eSAndroid Build Coastguard Worker return printWatchedTagsUntilInterrupt(args, inFd, outFd);
6498*ec779b8eSAndroid Build Coastguard Worker } else if (args.size() == 2 && args[1] == toString16("clear")) {
6499*ec779b8eSAndroid Build Coastguard Worker return clearCachedMonitoredTagDumps(outFd);
6500*ec779b8eSAndroid Build Coastguard Worker }
6501*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Camera service watch commands:\n"
6502*ec779b8eSAndroid Build Coastguard Worker " start -m <comma_separated_tag_list> [-c <comma_separated_client_list>]\n"
6503*ec779b8eSAndroid Build Coastguard Worker " starts watching the provided tags for clients with provided package\n"
6504*ec779b8eSAndroid Build Coastguard Worker " recognizes tag shorthands like '3a'\n"
6505*ec779b8eSAndroid Build Coastguard Worker " watches all clients if no client is passed, or if 'all' is listed\n"
6506*ec779b8eSAndroid Build Coastguard Worker " dump dumps the monitoring information and exits\n"
6507*ec779b8eSAndroid Build Coastguard Worker " stop stops watching all tags\n"
6508*ec779b8eSAndroid Build Coastguard Worker " live [-n <refresh_interval_ms>]\n"
6509*ec779b8eSAndroid Build Coastguard Worker " prints the monitored information in real time\n"
6510*ec779b8eSAndroid Build Coastguard Worker " Hit return to exit\n"
6511*ec779b8eSAndroid Build Coastguard Worker " clear clears all buffers storing information for watch command");
6512*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6513*ec779b8eSAndroid Build Coastguard Worker }
6514*ec779b8eSAndroid Build Coastguard Worker
startWatchingTags(const Vector<String16> & args,int outFd)6515*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::startWatchingTags(const Vector<String16> &args, int outFd) {
6516*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mLogLock);
6517*ec779b8eSAndroid Build Coastguard Worker size_t tagsIdx; // index of '-m'
6518*ec779b8eSAndroid Build Coastguard Worker String16 tags("");
6519*ec779b8eSAndroid Build Coastguard Worker for (tagsIdx = 2; tagsIdx < args.size() && args[tagsIdx] != toString16("-m"); tagsIdx++);
6520*ec779b8eSAndroid Build Coastguard Worker if (tagsIdx < args.size() - 1) {
6521*ec779b8eSAndroid Build Coastguard Worker tags = args[tagsIdx + 1];
6522*ec779b8eSAndroid Build Coastguard Worker } else {
6523*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "No tags provided.\n");
6524*ec779b8eSAndroid Build Coastguard Worker return BAD_VALUE;
6525*ec779b8eSAndroid Build Coastguard Worker }
6526*ec779b8eSAndroid Build Coastguard Worker
6527*ec779b8eSAndroid Build Coastguard Worker size_t clientsIdx; // index of '-c'
6528*ec779b8eSAndroid Build Coastguard Worker // watch all clients if no clients are provided
6529*ec779b8eSAndroid Build Coastguard Worker String16 clients = toString16(kWatchAllClientsFlag);
6530*ec779b8eSAndroid Build Coastguard Worker for (clientsIdx = 2; clientsIdx < args.size() && args[clientsIdx] != toString16("-c");
6531*ec779b8eSAndroid Build Coastguard Worker clientsIdx++);
6532*ec779b8eSAndroid Build Coastguard Worker if (clientsIdx < args.size() - 1) {
6533*ec779b8eSAndroid Build Coastguard Worker clients = args[clientsIdx + 1];
6534*ec779b8eSAndroid Build Coastguard Worker }
6535*ec779b8eSAndroid Build Coastguard Worker parseClientsToWatchLocked(toStdString(clients));
6536*ec779b8eSAndroid Build Coastguard Worker
6537*ec779b8eSAndroid Build Coastguard Worker // track tags to initialize future clients with the monitoring information
6538*ec779b8eSAndroid Build Coastguard Worker mMonitorTags = toStdString(tags);
6539*ec779b8eSAndroid Build Coastguard Worker
6540*ec779b8eSAndroid Build Coastguard Worker bool serviceLock = tryLock(mServiceLock);
6541*ec779b8eSAndroid Build Coastguard Worker int numWatchedClients = 0;
6542*ec779b8eSAndroid Build Coastguard Worker auto cameraClients = mActiveClientManager.getAll();
6543*ec779b8eSAndroid Build Coastguard Worker for (const auto &clientDescriptor: cameraClients) {
6544*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor == nullptr) { continue; }
6545*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = clientDescriptor->getValue();
6546*ec779b8eSAndroid Build Coastguard Worker if (client.get() == nullptr) { continue; }
6547*ec779b8eSAndroid Build Coastguard Worker
6548*ec779b8eSAndroid Build Coastguard Worker if (isClientWatchedLocked(client.get())) {
6549*ec779b8eSAndroid Build Coastguard Worker client->startWatchingTags(mMonitorTags, outFd);
6550*ec779b8eSAndroid Build Coastguard Worker numWatchedClients++;
6551*ec779b8eSAndroid Build Coastguard Worker }
6552*ec779b8eSAndroid Build Coastguard Worker }
6553*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Started watching %d active clients\n", numWatchedClients);
6554*ec779b8eSAndroid Build Coastguard Worker
6555*ec779b8eSAndroid Build Coastguard Worker if (serviceLock) { mServiceLock.unlock(); }
6556*ec779b8eSAndroid Build Coastguard Worker return OK;
6557*ec779b8eSAndroid Build Coastguard Worker }
6558*ec779b8eSAndroid Build Coastguard Worker
stopWatchingTags(int outFd)6559*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::stopWatchingTags(int outFd) {
6560*ec779b8eSAndroid Build Coastguard Worker // clear mMonitorTags to prevent new clients from monitoring tags at initialization
6561*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mLogLock);
6562*ec779b8eSAndroid Build Coastguard Worker mMonitorTags = "";
6563*ec779b8eSAndroid Build Coastguard Worker
6564*ec779b8eSAndroid Build Coastguard Worker mWatchedClientPackages.clear();
6565*ec779b8eSAndroid Build Coastguard Worker mWatchedClientsDumpCache.clear();
6566*ec779b8eSAndroid Build Coastguard Worker
6567*ec779b8eSAndroid Build Coastguard Worker bool serviceLock = tryLock(mServiceLock);
6568*ec779b8eSAndroid Build Coastguard Worker auto cameraClients = mActiveClientManager.getAll();
6569*ec779b8eSAndroid Build Coastguard Worker for (const auto &clientDescriptor : cameraClients) {
6570*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor == nullptr) { continue; }
6571*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = clientDescriptor->getValue();
6572*ec779b8eSAndroid Build Coastguard Worker if (client.get() == nullptr) { continue; }
6573*ec779b8eSAndroid Build Coastguard Worker client->stopWatchingTags(outFd);
6574*ec779b8eSAndroid Build Coastguard Worker }
6575*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Stopped watching all clients.\n");
6576*ec779b8eSAndroid Build Coastguard Worker if (serviceLock) { mServiceLock.unlock(); }
6577*ec779b8eSAndroid Build Coastguard Worker return OK;
6578*ec779b8eSAndroid Build Coastguard Worker }
6579*ec779b8eSAndroid Build Coastguard Worker
clearCachedMonitoredTagDumps(int outFd)6580*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::clearCachedMonitoredTagDumps(int outFd) {
6581*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mLogLock);
6582*ec779b8eSAndroid Build Coastguard Worker size_t clearedSize = mWatchedClientsDumpCache.size();
6583*ec779b8eSAndroid Build Coastguard Worker mWatchedClientsDumpCache.clear();
6584*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Cleared tag information of %zu cached clients.\n", clearedSize);
6585*ec779b8eSAndroid Build Coastguard Worker return OK;
6586*ec779b8eSAndroid Build Coastguard Worker }
6587*ec779b8eSAndroid Build Coastguard Worker
printWatchedTags(int outFd)6588*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::printWatchedTags(int outFd) {
6589*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock logLock(mLogLock);
6590*ec779b8eSAndroid Build Coastguard Worker std::set<std::string> connectedMonitoredClients;
6591*ec779b8eSAndroid Build Coastguard Worker
6592*ec779b8eSAndroid Build Coastguard Worker bool printedSomething = false; // tracks if any monitoring information was printed
6593*ec779b8eSAndroid Build Coastguard Worker // (from either cached or active clients)
6594*ec779b8eSAndroid Build Coastguard Worker
6595*ec779b8eSAndroid Build Coastguard Worker bool serviceLock = tryLock(mServiceLock);
6596*ec779b8eSAndroid Build Coastguard Worker // get all watched clients that are currently connected
6597*ec779b8eSAndroid Build Coastguard Worker for (const auto &clientDescriptor: mActiveClientManager.getAll()) {
6598*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor == nullptr) { continue; }
6599*ec779b8eSAndroid Build Coastguard Worker
6600*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = clientDescriptor->getValue();
6601*ec779b8eSAndroid Build Coastguard Worker if (client.get() == nullptr) { continue; }
6602*ec779b8eSAndroid Build Coastguard Worker if (!isClientWatchedLocked(client.get())) { continue; }
6603*ec779b8eSAndroid Build Coastguard Worker
6604*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> dumpVector;
6605*ec779b8eSAndroid Build Coastguard Worker client->dumpWatchedEventsToVector(dumpVector);
6606*ec779b8eSAndroid Build Coastguard Worker
6607*ec779b8eSAndroid Build Coastguard Worker size_t printIdx = dumpVector.size();
6608*ec779b8eSAndroid Build Coastguard Worker if (printIdx == 0) {
6609*ec779b8eSAndroid Build Coastguard Worker continue;
6610*ec779b8eSAndroid Build Coastguard Worker }
6611*ec779b8eSAndroid Build Coastguard Worker
6612*ec779b8eSAndroid Build Coastguard Worker // Print tag dumps for active client
6613*ec779b8eSAndroid Build Coastguard Worker const std::string &cameraId = clientDescriptor->getKey();
6614*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Client: %s (active)\n", client->getPackageName().c_str());
6615*ec779b8eSAndroid Build Coastguard Worker while(printIdx > 0) {
6616*ec779b8eSAndroid Build Coastguard Worker printIdx--;
6617*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "%s:%s %s", cameraId.c_str(), client->getPackageName().c_str(),
6618*ec779b8eSAndroid Build Coastguard Worker dumpVector[printIdx].c_str());
6619*ec779b8eSAndroid Build Coastguard Worker }
6620*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "\n");
6621*ec779b8eSAndroid Build Coastguard Worker printedSomething = true;
6622*ec779b8eSAndroid Build Coastguard Worker
6623*ec779b8eSAndroid Build Coastguard Worker connectedMonitoredClients.emplace(client->getPackageName());
6624*ec779b8eSAndroid Build Coastguard Worker }
6625*ec779b8eSAndroid Build Coastguard Worker if (serviceLock) { mServiceLock.unlock(); }
6626*ec779b8eSAndroid Build Coastguard Worker
6627*ec779b8eSAndroid Build Coastguard Worker // Print entries in mWatchedClientsDumpCache for clients that are not connected
6628*ec779b8eSAndroid Build Coastguard Worker for (const auto &kv: mWatchedClientsDumpCache) {
6629*ec779b8eSAndroid Build Coastguard Worker const std::string &package = kv.first;
6630*ec779b8eSAndroid Build Coastguard Worker if (connectedMonitoredClients.find(package) != connectedMonitoredClients.end()) {
6631*ec779b8eSAndroid Build Coastguard Worker continue;
6632*ec779b8eSAndroid Build Coastguard Worker }
6633*ec779b8eSAndroid Build Coastguard Worker
6634*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Client: %s (cached)\n", package.c_str());
6635*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "%s\n", kv.second.c_str());
6636*ec779b8eSAndroid Build Coastguard Worker printedSomething = true;
6637*ec779b8eSAndroid Build Coastguard Worker }
6638*ec779b8eSAndroid Build Coastguard Worker
6639*ec779b8eSAndroid Build Coastguard Worker if (!printedSomething) {
6640*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "No monitoring information to print.\n");
6641*ec779b8eSAndroid Build Coastguard Worker }
6642*ec779b8eSAndroid Build Coastguard Worker
6643*ec779b8eSAndroid Build Coastguard Worker return OK;
6644*ec779b8eSAndroid Build Coastguard Worker }
6645*ec779b8eSAndroid Build Coastguard Worker
6646*ec779b8eSAndroid Build Coastguard Worker // Print all events in vector `events' that came after lastPrintedEvent
printNewWatchedEvents(int outFd,const std::string & cameraId,const std::string & packageName,const std::vector<std::string> & events,const std::string & lastPrintedEvent)6647*ec779b8eSAndroid Build Coastguard Worker void printNewWatchedEvents(int outFd,
6648*ec779b8eSAndroid Build Coastguard Worker const std::string &cameraId,
6649*ec779b8eSAndroid Build Coastguard Worker const std::string &packageName,
6650*ec779b8eSAndroid Build Coastguard Worker const std::vector<std::string> &events,
6651*ec779b8eSAndroid Build Coastguard Worker const std::string &lastPrintedEvent) {
6652*ec779b8eSAndroid Build Coastguard Worker if (events.empty()) { return; }
6653*ec779b8eSAndroid Build Coastguard Worker
6654*ec779b8eSAndroid Build Coastguard Worker // index of lastPrintedEvent in events.
6655*ec779b8eSAndroid Build Coastguard Worker // lastPrintedIdx = events.size() if lastPrintedEvent is not in events
6656*ec779b8eSAndroid Build Coastguard Worker size_t lastPrintedIdx;
6657*ec779b8eSAndroid Build Coastguard Worker for (lastPrintedIdx = 0;
6658*ec779b8eSAndroid Build Coastguard Worker lastPrintedIdx < events.size() && lastPrintedEvent != events[lastPrintedIdx];
6659*ec779b8eSAndroid Build Coastguard Worker lastPrintedIdx++);
6660*ec779b8eSAndroid Build Coastguard Worker
6661*ec779b8eSAndroid Build Coastguard Worker if (lastPrintedIdx == 0) { return; } // early exit if no new event in `events`
6662*ec779b8eSAndroid Build Coastguard Worker
6663*ec779b8eSAndroid Build Coastguard Worker // print events in chronological order (latest event last)
6664*ec779b8eSAndroid Build Coastguard Worker size_t idxToPrint = lastPrintedIdx;
6665*ec779b8eSAndroid Build Coastguard Worker do {
6666*ec779b8eSAndroid Build Coastguard Worker idxToPrint--;
6667*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "%s:%s %s", cameraId.c_str(), packageName.c_str(),
6668*ec779b8eSAndroid Build Coastguard Worker events[idxToPrint].c_str());
6669*ec779b8eSAndroid Build Coastguard Worker } while (idxToPrint != 0);
6670*ec779b8eSAndroid Build Coastguard Worker }
6671*ec779b8eSAndroid Build Coastguard Worker
6672*ec779b8eSAndroid Build Coastguard Worker // Returns true if adb shell cmd watch should be interrupted based on data in inFd. The watch
6673*ec779b8eSAndroid Build Coastguard Worker // command should be interrupted if the user presses the return key, or if user loses any way to
6674*ec779b8eSAndroid Build Coastguard Worker // signal interrupt.
6675*ec779b8eSAndroid Build Coastguard Worker // If timeoutMs == 0, this function will always return false
shouldInterruptWatchCommand(int inFd,int outFd,long timeoutMs)6676*ec779b8eSAndroid Build Coastguard Worker bool shouldInterruptWatchCommand(int inFd, int outFd, long timeoutMs) {
6677*ec779b8eSAndroid Build Coastguard Worker struct timeval startTime;
6678*ec779b8eSAndroid Build Coastguard Worker int startTimeError = gettimeofday(&startTime, nullptr);
6679*ec779b8eSAndroid Build Coastguard Worker if (startTimeError) {
6680*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Failed waiting for interrupt, aborting.\n");
6681*ec779b8eSAndroid Build Coastguard Worker return true;
6682*ec779b8eSAndroid Build Coastguard Worker }
6683*ec779b8eSAndroid Build Coastguard Worker
6684*ec779b8eSAndroid Build Coastguard Worker const nfds_t numFds = 1;
6685*ec779b8eSAndroid Build Coastguard Worker struct pollfd pollFd = { .fd = inFd, .events = POLLIN, .revents = 0 };
6686*ec779b8eSAndroid Build Coastguard Worker
6687*ec779b8eSAndroid Build Coastguard Worker struct timeval currTime;
6688*ec779b8eSAndroid Build Coastguard Worker char buffer[2];
6689*ec779b8eSAndroid Build Coastguard Worker while(true) {
6690*ec779b8eSAndroid Build Coastguard Worker int currTimeError = gettimeofday(&currTime, nullptr);
6691*ec779b8eSAndroid Build Coastguard Worker if (currTimeError) {
6692*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Failed waiting for interrupt, aborting.\n");
6693*ec779b8eSAndroid Build Coastguard Worker return true;
6694*ec779b8eSAndroid Build Coastguard Worker }
6695*ec779b8eSAndroid Build Coastguard Worker
6696*ec779b8eSAndroid Build Coastguard Worker long elapsedTimeMs = ((currTime.tv_sec - startTime.tv_sec) * 1000L)
6697*ec779b8eSAndroid Build Coastguard Worker + ((currTime.tv_usec - startTime.tv_usec) / 1000L);
6698*ec779b8eSAndroid Build Coastguard Worker int remainingTimeMs = (int) (timeoutMs - elapsedTimeMs);
6699*ec779b8eSAndroid Build Coastguard Worker
6700*ec779b8eSAndroid Build Coastguard Worker if (remainingTimeMs <= 0) {
6701*ec779b8eSAndroid Build Coastguard Worker // No user interrupt within timeoutMs, don't interrupt watch command
6702*ec779b8eSAndroid Build Coastguard Worker return false;
6703*ec779b8eSAndroid Build Coastguard Worker }
6704*ec779b8eSAndroid Build Coastguard Worker
6705*ec779b8eSAndroid Build Coastguard Worker int numFdsUpdated = poll(&pollFd, numFds, remainingTimeMs);
6706*ec779b8eSAndroid Build Coastguard Worker if (numFdsUpdated < 0) {
6707*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Failed while waiting for user input. Exiting.\n");
6708*ec779b8eSAndroid Build Coastguard Worker return true;
6709*ec779b8eSAndroid Build Coastguard Worker }
6710*ec779b8eSAndroid Build Coastguard Worker
6711*ec779b8eSAndroid Build Coastguard Worker if (numFdsUpdated == 0) {
6712*ec779b8eSAndroid Build Coastguard Worker // No user input within timeoutMs, don't interrupt watch command
6713*ec779b8eSAndroid Build Coastguard Worker return false;
6714*ec779b8eSAndroid Build Coastguard Worker }
6715*ec779b8eSAndroid Build Coastguard Worker
6716*ec779b8eSAndroid Build Coastguard Worker if (!(pollFd.revents & POLLIN)) {
6717*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Failed while waiting for user input. Exiting.\n");
6718*ec779b8eSAndroid Build Coastguard Worker return true;
6719*ec779b8eSAndroid Build Coastguard Worker }
6720*ec779b8eSAndroid Build Coastguard Worker
6721*ec779b8eSAndroid Build Coastguard Worker ssize_t sizeRead = read(inFd, buffer, sizeof(buffer) - 1);
6722*ec779b8eSAndroid Build Coastguard Worker if (sizeRead < 0) {
6723*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Error reading user input. Exiting.\n");
6724*ec779b8eSAndroid Build Coastguard Worker return true;
6725*ec779b8eSAndroid Build Coastguard Worker }
6726*ec779b8eSAndroid Build Coastguard Worker
6727*ec779b8eSAndroid Build Coastguard Worker if (sizeRead == 0) {
6728*ec779b8eSAndroid Build Coastguard Worker // Reached end of input fd (can happen if input is piped)
6729*ec779b8eSAndroid Build Coastguard Worker // User has no way to signal an interrupt, so interrupt here
6730*ec779b8eSAndroid Build Coastguard Worker return true;
6731*ec779b8eSAndroid Build Coastguard Worker }
6732*ec779b8eSAndroid Build Coastguard Worker
6733*ec779b8eSAndroid Build Coastguard Worker if (buffer[0] == '\n') {
6734*ec779b8eSAndroid Build Coastguard Worker // User pressed return, interrupt watch command.
6735*ec779b8eSAndroid Build Coastguard Worker return true;
6736*ec779b8eSAndroid Build Coastguard Worker }
6737*ec779b8eSAndroid Build Coastguard Worker }
6738*ec779b8eSAndroid Build Coastguard Worker }
6739*ec779b8eSAndroid Build Coastguard Worker
printWatchedTagsUntilInterrupt(const Vector<String16> & args,int inFd,int outFd)6740*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::printWatchedTagsUntilInterrupt(const Vector<String16> &args,
6741*ec779b8eSAndroid Build Coastguard Worker int inFd, int outFd) {
6742*ec779b8eSAndroid Build Coastguard Worker // Figure out refresh interval, if present in args
6743*ec779b8eSAndroid Build Coastguard Worker long refreshTimeoutMs = 1000L; // refresh every 1s by default
6744*ec779b8eSAndroid Build Coastguard Worker if (args.size() > 2) {
6745*ec779b8eSAndroid Build Coastguard Worker size_t intervalIdx; // index of '-n'
6746*ec779b8eSAndroid Build Coastguard Worker for (intervalIdx = 2; intervalIdx < args.size() && toString16("-n") != args[intervalIdx];
6747*ec779b8eSAndroid Build Coastguard Worker intervalIdx++);
6748*ec779b8eSAndroid Build Coastguard Worker
6749*ec779b8eSAndroid Build Coastguard Worker size_t intervalValIdx = intervalIdx + 1;
6750*ec779b8eSAndroid Build Coastguard Worker if (intervalValIdx < args.size()) {
6751*ec779b8eSAndroid Build Coastguard Worker refreshTimeoutMs = strtol(toStdString(args[intervalValIdx]).c_str(), nullptr, 10);
6752*ec779b8eSAndroid Build Coastguard Worker if (errno) { return BAD_VALUE; }
6753*ec779b8eSAndroid Build Coastguard Worker }
6754*ec779b8eSAndroid Build Coastguard Worker }
6755*ec779b8eSAndroid Build Coastguard Worker
6756*ec779b8eSAndroid Build Coastguard Worker // Set min timeout of 10ms. This prevents edge cases in polling when timeout of 0 is passed.
6757*ec779b8eSAndroid Build Coastguard Worker refreshTimeoutMs = refreshTimeoutMs < 10 ? 10 : refreshTimeoutMs;
6758*ec779b8eSAndroid Build Coastguard Worker
6759*ec779b8eSAndroid Build Coastguard Worker dprintf(outFd, "Press return to exit...\n\n");
6760*ec779b8eSAndroid Build Coastguard Worker std::map<std::string, std::string> packageNameToLastEvent;
6761*ec779b8eSAndroid Build Coastguard Worker
6762*ec779b8eSAndroid Build Coastguard Worker while (true) {
6763*ec779b8eSAndroid Build Coastguard Worker bool serviceLock = tryLock(mServiceLock);
6764*ec779b8eSAndroid Build Coastguard Worker auto cameraClients = mActiveClientManager.getAll();
6765*ec779b8eSAndroid Build Coastguard Worker if (serviceLock) { mServiceLock.unlock(); }
6766*ec779b8eSAndroid Build Coastguard Worker
6767*ec779b8eSAndroid Build Coastguard Worker for (const auto& clientDescriptor : cameraClients) {
6768*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mLogLock);
6769*ec779b8eSAndroid Build Coastguard Worker if (clientDescriptor == nullptr) { continue; }
6770*ec779b8eSAndroid Build Coastguard Worker
6771*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> client = clientDescriptor->getValue();
6772*ec779b8eSAndroid Build Coastguard Worker if (client.get() == nullptr) { continue; }
6773*ec779b8eSAndroid Build Coastguard Worker if (!isClientWatchedLocked(client.get())) { continue; }
6774*ec779b8eSAndroid Build Coastguard Worker
6775*ec779b8eSAndroid Build Coastguard Worker const std::string &packageName = client->getPackageName();
6776*ec779b8eSAndroid Build Coastguard Worker // This also initializes the map entries with an empty string
6777*ec779b8eSAndroid Build Coastguard Worker const std::string& lastPrintedEvent = packageNameToLastEvent[packageName];
6778*ec779b8eSAndroid Build Coastguard Worker
6779*ec779b8eSAndroid Build Coastguard Worker std::vector<std::string> latestEvents;
6780*ec779b8eSAndroid Build Coastguard Worker client->dumpWatchedEventsToVector(latestEvents);
6781*ec779b8eSAndroid Build Coastguard Worker
6782*ec779b8eSAndroid Build Coastguard Worker if (!latestEvents.empty()) {
6783*ec779b8eSAndroid Build Coastguard Worker printNewWatchedEvents(outFd,
6784*ec779b8eSAndroid Build Coastguard Worker clientDescriptor->getKey(),
6785*ec779b8eSAndroid Build Coastguard Worker packageName,
6786*ec779b8eSAndroid Build Coastguard Worker latestEvents,
6787*ec779b8eSAndroid Build Coastguard Worker lastPrintedEvent);
6788*ec779b8eSAndroid Build Coastguard Worker packageNameToLastEvent[packageName] = latestEvents[0];
6789*ec779b8eSAndroid Build Coastguard Worker }
6790*ec779b8eSAndroid Build Coastguard Worker }
6791*ec779b8eSAndroid Build Coastguard Worker if (shouldInterruptWatchCommand(inFd, outFd, refreshTimeoutMs)) {
6792*ec779b8eSAndroid Build Coastguard Worker break;
6793*ec779b8eSAndroid Build Coastguard Worker }
6794*ec779b8eSAndroid Build Coastguard Worker }
6795*ec779b8eSAndroid Build Coastguard Worker return OK;
6796*ec779b8eSAndroid Build Coastguard Worker }
6797*ec779b8eSAndroid Build Coastguard Worker
parseClientsToWatchLocked(const std::string & clients)6798*ec779b8eSAndroid Build Coastguard Worker void CameraService::parseClientsToWatchLocked(const std::string &clients) {
6799*ec779b8eSAndroid Build Coastguard Worker mWatchedClientPackages.clear();
6800*ec779b8eSAndroid Build Coastguard Worker
6801*ec779b8eSAndroid Build Coastguard Worker std::istringstream iss(clients);
6802*ec779b8eSAndroid Build Coastguard Worker std::string nextClient;
6803*ec779b8eSAndroid Build Coastguard Worker
6804*ec779b8eSAndroid Build Coastguard Worker while (std::getline(iss, nextClient, ',')) {
6805*ec779b8eSAndroid Build Coastguard Worker if (nextClient == kWatchAllClientsFlag) {
6806*ec779b8eSAndroid Build Coastguard Worker // Don't need to track any other package if 'all' is present
6807*ec779b8eSAndroid Build Coastguard Worker mWatchedClientPackages.clear();
6808*ec779b8eSAndroid Build Coastguard Worker mWatchedClientPackages.emplace(kWatchAllClientsFlag);
6809*ec779b8eSAndroid Build Coastguard Worker break;
6810*ec779b8eSAndroid Build Coastguard Worker }
6811*ec779b8eSAndroid Build Coastguard Worker
6812*ec779b8eSAndroid Build Coastguard Worker // track package names
6813*ec779b8eSAndroid Build Coastguard Worker mWatchedClientPackages.emplace(nextClient);
6814*ec779b8eSAndroid Build Coastguard Worker }
6815*ec779b8eSAndroid Build Coastguard Worker }
6816*ec779b8eSAndroid Build Coastguard Worker
printHelp(int out)6817*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::printHelp(int out) {
6818*ec779b8eSAndroid Build Coastguard Worker return dprintf(out, "Camera service commands:\n"
6819*ec779b8eSAndroid Build Coastguard Worker " get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
6820*ec779b8eSAndroid Build Coastguard Worker " set-uid-state <PACKAGE> <active|idle> [--user USER_ID] overrides the uid state\n"
6821*ec779b8eSAndroid Build Coastguard Worker " reset-uid-state <PACKAGE> [--user USER_ID] clears the uid state override\n"
6822*ec779b8eSAndroid Build Coastguard Worker " set-rotate-and-crop <ROTATION> overrides the rotate-and-crop value for AUTO backcompat\n"
6823*ec779b8eSAndroid Build Coastguard Worker " Valid values 0=0 deg, 1=90 deg, 2=180 deg, 3=270 deg, 4=No override\n"
6824*ec779b8eSAndroid Build Coastguard Worker " get-rotate-and-crop returns the current override rotate-and-crop value\n"
6825*ec779b8eSAndroid Build Coastguard Worker " set-autoframing <VALUE> overrides the autoframing value for AUTO\n"
6826*ec779b8eSAndroid Build Coastguard Worker " Valid values 0=false, 1=true, 2=auto\n"
6827*ec779b8eSAndroid Build Coastguard Worker " get-autoframing returns the current override autoframing value\n"
6828*ec779b8eSAndroid Build Coastguard Worker " set-image-dump-mask <MASK> specifies the formats to be saved to disk\n"
6829*ec779b8eSAndroid Build Coastguard Worker " Valid values 0=OFF, 1=ON for JPEG\n"
6830*ec779b8eSAndroid Build Coastguard Worker " get-image-dump-mask returns the current image-dump-mask value\n"
6831*ec779b8eSAndroid Build Coastguard Worker " set-camera-mute <0/1> enable or disable camera muting\n"
6832*ec779b8eSAndroid Build Coastguard Worker " set-stream-use-case-override <usecase1> <usecase2> ... override stream use cases\n"
6833*ec779b8eSAndroid Build Coastguard Worker " Use cases applied in descending resolutions. So usecase1 is assigned to the\n"
6834*ec779b8eSAndroid Build Coastguard Worker " largest resolution, usecase2 is assigned to the 2nd largest resolution, and so\n"
6835*ec779b8eSAndroid Build Coastguard Worker " on. In case the number of usecases is smaller than the number of streams, the\n"
6836*ec779b8eSAndroid Build Coastguard Worker " last use case is assigned to all the remaining streams. In case of multiple\n"
6837*ec779b8eSAndroid Build Coastguard Worker " streams with the same resolution, the tie-breaker is (JPEG, RAW, YUV, and PRIV)\n"
6838*ec779b8eSAndroid Build Coastguard Worker " Valid values are (case sensitive): DEFAULT, PREVIEW, STILL_CAPTURE, VIDEO_RECORD,\n"
6839*ec779b8eSAndroid Build Coastguard Worker " PREVIEW_VIDEO_STILL, VIDEO_CALL, CROPPED_RAW\n"
6840*ec779b8eSAndroid Build Coastguard Worker " clear-stream-use-case-override clear the stream use case override\n"
6841*ec779b8eSAndroid Build Coastguard Worker " set-zoom-override <-1/0/1> enable or disable zoom override\n"
6842*ec779b8eSAndroid Build Coastguard Worker " Valid values -1: do not override, 0: override to OFF, 1: override to ZOOM\n"
6843*ec779b8eSAndroid Build Coastguard Worker " set-watchdog <VALUE> enables or disables the camera service watchdog\n"
6844*ec779b8eSAndroid Build Coastguard Worker " Valid values 0=disable, 1=enable\n"
6845*ec779b8eSAndroid Build Coastguard Worker " watch <start|stop|dump|print|clear> manages tag monitoring in connected clients\n"
6846*ec779b8eSAndroid Build Coastguard Worker " help print this message\n");
6847*ec779b8eSAndroid Build Coastguard Worker }
6848*ec779b8eSAndroid Build Coastguard Worker
isClientWatched(const BasicClient * client)6849*ec779b8eSAndroid Build Coastguard Worker bool CameraService::isClientWatched(const BasicClient *client) {
6850*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mLogLock);
6851*ec779b8eSAndroid Build Coastguard Worker return isClientWatchedLocked(client);
6852*ec779b8eSAndroid Build Coastguard Worker }
6853*ec779b8eSAndroid Build Coastguard Worker
isClientWatchedLocked(const BasicClient * client)6854*ec779b8eSAndroid Build Coastguard Worker bool CameraService::isClientWatchedLocked(const BasicClient *client) {
6855*ec779b8eSAndroid Build Coastguard Worker return mWatchedClientPackages.find(kWatchAllClientsFlag) != mWatchedClientPackages.end() ||
6856*ec779b8eSAndroid Build Coastguard Worker mWatchedClientPackages.find(client->getPackageName()) != mWatchedClientPackages.end();
6857*ec779b8eSAndroid Build Coastguard Worker }
6858*ec779b8eSAndroid Build Coastguard Worker
updateAudioRestriction()6859*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::updateAudioRestriction() {
6860*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mServiceLock);
6861*ec779b8eSAndroid Build Coastguard Worker return updateAudioRestrictionLocked();
6862*ec779b8eSAndroid Build Coastguard Worker }
6863*ec779b8eSAndroid Build Coastguard Worker
updateAudioRestrictionLocked()6864*ec779b8eSAndroid Build Coastguard Worker int32_t CameraService::updateAudioRestrictionLocked() {
6865*ec779b8eSAndroid Build Coastguard Worker int32_t mode = 0;
6866*ec779b8eSAndroid Build Coastguard Worker // iterate through all active client
6867*ec779b8eSAndroid Build Coastguard Worker for (const auto& i : mActiveClientManager.getAll()) {
6868*ec779b8eSAndroid Build Coastguard Worker const auto clientSp = i->getValue();
6869*ec779b8eSAndroid Build Coastguard Worker mode |= clientSp->getAudioRestriction();
6870*ec779b8eSAndroid Build Coastguard Worker }
6871*ec779b8eSAndroid Build Coastguard Worker
6872*ec779b8eSAndroid Build Coastguard Worker bool modeChanged = (mAudioRestriction != mode);
6873*ec779b8eSAndroid Build Coastguard Worker mAudioRestriction = mode;
6874*ec779b8eSAndroid Build Coastguard Worker if (modeChanged) {
6875*ec779b8eSAndroid Build Coastguard Worker mAppOps.setCameraAudioRestriction(mode);
6876*ec779b8eSAndroid Build Coastguard Worker }
6877*ec779b8eSAndroid Build Coastguard Worker return mode;
6878*ec779b8eSAndroid Build Coastguard Worker }
6879*ec779b8eSAndroid Build Coastguard Worker
checkIfInjectionCameraIsPresent(const std::string & externalCamId,sp<BasicClient> clientSp)6880*ec779b8eSAndroid Build Coastguard Worker status_t CameraService::checkIfInjectionCameraIsPresent(const std::string& externalCamId,
6881*ec779b8eSAndroid Build Coastguard Worker sp<BasicClient> clientSp) {
6882*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<AutoConditionLock> lock =
6883*ec779b8eSAndroid Build Coastguard Worker AutoConditionLock::waitAndAcquire(mServiceLockWrapper);
6884*ec779b8eSAndroid Build Coastguard Worker status_t res = NO_ERROR;
6885*ec779b8eSAndroid Build Coastguard Worker if ((res = checkIfDeviceIsUsable(externalCamId)) != NO_ERROR) {
6886*ec779b8eSAndroid Build Coastguard Worker ALOGW("Device %s is not usable!", externalCamId.c_str());
6887*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->notifyInjectionError(
6888*ec779b8eSAndroid Build Coastguard Worker externalCamId, UNKNOWN_TRANSACTION);
6889*ec779b8eSAndroid Build Coastguard Worker clientSp->notifyError(
6890*ec779b8eSAndroid Build Coastguard Worker hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
6891*ec779b8eSAndroid Build Coastguard Worker CaptureResultExtras());
6892*ec779b8eSAndroid Build Coastguard Worker
6893*ec779b8eSAndroid Build Coastguard Worker // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking
6894*ec779b8eSAndroid Build Coastguard Worker // other clients from connecting in mServiceLockWrapper if held
6895*ec779b8eSAndroid Build Coastguard Worker mServiceLock.unlock();
6896*ec779b8eSAndroid Build Coastguard Worker
6897*ec779b8eSAndroid Build Coastguard Worker // Clear caller identity temporarily so client disconnect PID checks work correctly
6898*ec779b8eSAndroid Build Coastguard Worker int64_t token = clearCallingIdentity();
6899*ec779b8eSAndroid Build Coastguard Worker clientSp->disconnect();
6900*ec779b8eSAndroid Build Coastguard Worker restoreCallingIdentity(token);
6901*ec779b8eSAndroid Build Coastguard Worker
6902*ec779b8eSAndroid Build Coastguard Worker // Reacquire mServiceLock
6903*ec779b8eSAndroid Build Coastguard Worker mServiceLock.lock();
6904*ec779b8eSAndroid Build Coastguard Worker }
6905*ec779b8eSAndroid Build Coastguard Worker
6906*ec779b8eSAndroid Build Coastguard Worker return res;
6907*ec779b8eSAndroid Build Coastguard Worker }
6908*ec779b8eSAndroid Build Coastguard Worker
clearInjectionParameters()6909*ec779b8eSAndroid Build Coastguard Worker void CameraService::clearInjectionParameters() {
6910*ec779b8eSAndroid Build Coastguard Worker {
6911*ec779b8eSAndroid Build Coastguard Worker Mutex::Autolock lock(mInjectionParametersLock);
6912*ec779b8eSAndroid Build Coastguard Worker mInjectionInitPending = false;
6913*ec779b8eSAndroid Build Coastguard Worker mInjectionInternalCamId = "";
6914*ec779b8eSAndroid Build Coastguard Worker }
6915*ec779b8eSAndroid Build Coastguard Worker mInjectionExternalCamId = "";
6916*ec779b8eSAndroid Build Coastguard Worker mInjectionStatusListener->removeListener();
6917*ec779b8eSAndroid Build Coastguard Worker }
6918*ec779b8eSAndroid Build Coastguard Worker
6919*ec779b8eSAndroid Build Coastguard Worker } // namespace android
6920