| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1 | /* | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 2 |  * Copyright (C) 2008 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 16 |  | 
 | 17 | #define LOG_TAG "CameraService" | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 18 | #define ATRACE_TAG ATRACE_TAG_CAMERA | 
| Iliyan Malchev | 8951a97 | 2011-04-14 16:55:59 -0700 | [diff] [blame] | 19 | //#define LOG_NDEBUG 0 | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 20 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 21 | #include <algorithm> | 
 | 22 | #include <climits> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 23 | #include <stdio.h> | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 24 | #include <cstdlib> | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 25 | #include <cstring> | 
 | 26 | #include <ctime> | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 27 | #include <iostream> | 
 | 28 | #include <sstream> | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 29 | #include <string> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 30 | #include <sys/types.h> | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 31 | #include <inttypes.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 32 | #include <pthread.h> | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 33 | #include <poll.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 34 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 35 | #include <android/hardware/ICamera.h> | 
 | 36 | #include <android/hardware/ICameraClient.h> | 
 | 37 |  | 
| Avichal Rakesh | fcb78cb | 2022-10-27 15:45:54 -0700 | [diff] [blame] | 38 | #include <aidl/AidlCameraService.h> | 
| Alex Deymo | 9c2a2c2 | 2016-08-25 11:59:14 -0700 | [diff] [blame] | 39 | #include <android-base/macros.h> | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 40 | #include <android-base/parseint.h> | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 41 | #include <android_companion_virtualdevice_flags.h> | 
 | 42 | #include <android/companion/virtualnative/IVirtualDeviceManagerNative.h> | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 43 | #include <binder/ActivityManager.h> | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 44 | #include <binder/AppOpsManager.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 45 | #include <binder/IPCThreadState.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 46 | #include <binder/MemoryBase.h> | 
 | 47 | #include <binder/MemoryHeapBase.h> | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 48 | #include <binder/PermissionController.h> | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 49 | #include <binder/IResultReceiver.h> | 
| Steven Moreland | 89a2c5c | 2020-01-31 15:02:25 -0800 | [diff] [blame] | 50 | #include <binderthreadstate/CallerUtils.h> | 
| Jyoti Bhayana | a16cc4c | 2023-09-26 15:37:19 -0700 | [diff] [blame] | 51 | #include <com_android_internal_camera_flags.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 52 | #include <cutils/atomic.h> | 
| Nipun Kwatra | b5ca461 | 2010-09-11 19:31:10 -0700 | [diff] [blame] | 53 | #include <cutils/properties.h> | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 54 | #include <cutils/misc.h> | 
| Mathias Agopian | df712ea | 2012-02-25 18:48:35 -0800 | [diff] [blame] | 55 | #include <gui/Surface.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 56 | #include <hardware/hardware.h> | 
| Jayant Chowdhary | be543d4 | 2018-08-15 13:16:14 -0700 | [diff] [blame] | 57 | #include "hidl/HidlCameraService.h" | 
 | 58 | #include <hidl/HidlTransportSupport.h> | 
| Jayant Chowdhary | f949ddd | 2019-01-29 14:34:11 -0800 | [diff] [blame] | 59 | #include <hwbinder/IPCThreadState.h> | 
| Eino-Ville Talvala | d89821e | 2016-04-20 11:23:50 -0700 | [diff] [blame] | 60 | #include <memunreachable/memunreachable.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 61 | #include <media/AudioSystem.h> | 
| Andreas Huber | 1b86fe0 | 2014-01-29 11:13:26 -0800 | [diff] [blame] | 62 | #include <media/IMediaHTTPService.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 63 | #include <media/mediaplayer.h> | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 64 | #include <mediautils/BatteryNotifier.h> | 
| Steven Moreland | 886d732 | 2021-04-02 04:19:45 +0000 | [diff] [blame] | 65 | #include <processinfo/ProcessInfoService.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 66 | #include <utils/Errors.h> | 
 | 67 | #include <utils/Log.h> | 
 | 68 | #include <utils/String16.h> | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 69 | #include <utils/SystemClock.h> | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 70 | #include <utils/Trace.h> | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 71 | #include <utils/CallStack.h> | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 72 | #include <private/android_filesystem_config.h> | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 73 | #include <system/camera_vendor_tags.h> | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 74 | #include <system/camera_metadata.h> | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 75 | #include <binder/IServiceManager.h> | 
 | 76 | #include <binder/IActivityManager.h> | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 77 | #include <camera/CameraUtils.h> | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 78 | #include <camera/StringUtils.h> | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 79 |  | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 80 | #include <system/camera.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 81 |  | 
 | 82 | #include "CameraService.h" | 
| Eino-Ville Talvala | 7b82efe | 2013-07-25 17:12:35 -0700 | [diff] [blame] | 83 | #include "api1/Camera2Client.h" | 
| Eino-Ville Talvala | 7b82efe | 2013-07-25 17:12:35 -0700 | [diff] [blame] | 84 | #include "api2/CameraDeviceClient.h" | 
| Shuzhen Wang | 316781a | 2020-08-18 18:11:01 -0700 | [diff] [blame] | 85 | #include "utils/CameraServiceProxyWrapper.h" | 
| Emilian Peev | 31bd242 | 2024-04-23 22:24:09 +0000 | [diff] [blame] | 86 | #include "utils/CameraTraces.h" | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 87 | #include "utils/SessionConfigurationUtils.h" | 
| Emilian Peev | 31bd242 | 2024-04-23 22:24:09 +0000 | [diff] [blame] | 88 | #include "utils/TagMonitor.h" | 
 | 89 | #include "utils/Utils.h" | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 90 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 91 | namespace { | 
 | 92 |     const char* kPermissionServiceName = "permission"; | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 93 |     const char* kActivityServiceName = "activity"; | 
 | 94 |     const char* kSensorPrivacyServiceName = "sensor_privacy"; | 
 | 95 |     const char* kAppopsServiceName = "appops"; | 
| Jyoti Bhayana | da519ab | 2023-05-15 15:49:15 -0700 | [diff] [blame] | 96 |     const char* kProcessInfoServiceName = "processinfo"; | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 97 |     const char* kVirtualDeviceBackCameraId = "0"; | 
 | 98 |     const char* kVirtualDeviceFrontCameraId = "1"; | 
 | 99 |  | 
 | 100 |     int32_t getDeviceId(const android::CameraMetadata& cameraInfo) { | 
 | 101 |         if (!cameraInfo.exists(ANDROID_INFO_DEVICE_ID)) { | 
 | 102 |             return android::kDefaultDeviceId; | 
 | 103 |         } | 
 | 104 |  | 
 | 105 |         const auto &deviceIdEntry = cameraInfo.find(ANDROID_INFO_DEVICE_ID); | 
 | 106 |         return deviceIdEntry.data.i32[0]; | 
 | 107 |     } | 
 | 108 | } // namespace anonymous | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 109 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 110 | namespace android { | 
 | 111 |  | 
| Austin Borger | ea93124 | 2021-12-13 23:10:41 +0000 | [diff] [blame] | 112 | using namespace camera3; | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 113 | using namespace camera3::SessionConfigurationUtils; | 
 | 114 |  | 
 | 115 | using binder::Status; | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 116 | using companion::virtualnative::IVirtualDeviceManagerNative; | 
| Jayant Chowdhary | be543d4 | 2018-08-15 13:16:14 -0700 | [diff] [blame] | 117 | using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService; | 
| Avichal Rakesh | fcb78cb | 2022-10-27 15:45:54 -0700 | [diff] [blame] | 118 | using frameworks::cameraservice::service::implementation::AidlCameraService; | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 119 | using hardware::ICamera; | 
 | 120 | using hardware::ICameraClient; | 
 | 121 | using hardware::ICameraServiceListener; | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 122 | using hardware::camera2::ICameraInjectionCallback; | 
 | 123 | using hardware::camera2::ICameraInjectionSession; | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 124 | using hardware::camera2::utils::CameraIdAndSessionConfiguration; | 
 | 125 | using hardware::camera2::utils::ConcurrentCameraIdCombination; | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 126 |  | 
| Jyoti Bhayana | a16cc4c | 2023-09-26 15:37:19 -0700 | [diff] [blame] | 127 | namespace flags = com::android::internal::camera::flags; | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 128 | namespace vd_flags = android::companion::virtualdevice::flags; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 129 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 130 | // ---------------------------------------------------------------------------- | 
 | 131 | // Logging support -- this is for debugging only | 
 | 132 | // Use "adb shell dumpsys media.camera -v 1" to change it. | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 133 | volatile int32_t gLogLevel = 0; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 134 |  | 
| Steve Block | b8a8052 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 135 | #define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__); | 
 | 136 | #define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 137 |  | 
 | 138 | static void setLogLevel(int level) { | 
 | 139 |     android_atomic_write(level, &gLogLevel); | 
 | 140 | } | 
 | 141 |  | 
| Henri Chataing | bcb9945 | 2023-11-01 17:40:30 +0000 | [diff] [blame] | 142 | int32_t format_as(CameraService::StatusInternal s) { | 
 | 143 |   return fmt::underlying(s); | 
 | 144 | } | 
 | 145 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 146 | // ---------------------------------------------------------------------------- | 
 | 147 |  | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 148 | // Permission strings (references to AttributionAndPermissionUtils for brevity) | 
 | 149 | static const std::string &sDumpPermission = | 
 | 150 |         AttributionAndPermissionUtils::sDumpPermission; | 
 | 151 | static const std::string &sManageCameraPermission = | 
 | 152 |         AttributionAndPermissionUtils::sManageCameraPermission; | 
 | 153 | static const std::string &sCameraSendSystemEventsPermission = | 
 | 154 |         AttributionAndPermissionUtils::sCameraSendSystemEventsPermission; | 
 | 155 | static const std::string &sCameraInjectExternalCameraPermission = | 
 | 156 |         AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission; | 
 | 157 |  | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 158 | // Constant integer for FGS Logging, used to denote the API type for logger | 
 | 159 | static const int LOG_FGS_CAMERA_API = 1; | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 160 | const char *sFileName = "lastOpenSessionDumpFile"; | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 161 | static constexpr int32_t kSystemNativeClientScore = resource_policy::PERCEPTIBLE_APP_ADJ; | 
 | 162 | static constexpr int32_t kSystemNativeClientState = | 
 | 163 |         ActivityManager::PROCESS_STATE_PERSISTENT_UI; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 164 | static const std::string kServiceName("cameraserver"); | 
| Eino-Ville Talvala | 7c602c3 | 2021-03-20 17:00:18 -0700 | [diff] [blame] | 165 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 166 | const std::string CameraService::kOfflineDevice("offline-"); | 
 | 167 | const std::string CameraService::kWatchAllClientsFlag("all"); | 
| Jayant Chowdhary | c578a50 | 2019-05-08 10:57:54 -0700 | [diff] [blame] | 168 |  | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 169 | constexpr int32_t kInvalidDeviceId = -1; | 
 | 170 |  | 
| Rucha Katakwar | d9ea645 | 2021-05-06 11:57:16 -0700 | [diff] [blame] | 171 | // Set to keep track of logged service error events. | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 172 | static std::set<std::string> sServiceErrorEventSet; | 
| Rucha Katakwar | d9ea645 | 2021-05-06 11:57:16 -0700 | [diff] [blame] | 173 |  | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 174 | CameraService::CameraService( | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 175 |         std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper, | 
 | 176 |         std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils) : | 
 | 177 |         AttributionAndPermissionUtilsEncapsulator(attributionAndPermissionUtils == nullptr ? | 
 | 178 |                 std::make_shared<AttributionAndPermissionUtils>()\ | 
 | 179 |                 : attributionAndPermissionUtils), | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 180 |         mCameraServiceProxyWrapper(cameraServiceProxyWrapper == nullptr ? | 
 | 181 |                 std::make_shared<CameraServiceProxyWrapper>() : cameraServiceProxyWrapper), | 
| Eino-Ville Talvala | 49c9705 | 2016-01-12 14:29:40 -0800 | [diff] [blame] | 182 |         mEventLog(DEFAULT_EVENT_LOG_LENGTH), | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 183 |         mNumberOfCameras(0), | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 184 |         mNumberOfCamerasWithoutSystemCamera(0), | 
| Yin-Chia Yeh | dba0323 | 2019-08-19 15:54:28 -0700 | [diff] [blame] | 185 |         mSoundRef(0), mInitialized(false), | 
 | 186 |         mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) { | 
| Steve Block | df64d15 | 2012-01-04 20:05:49 +0000 | [diff] [blame] | 187 |     ALOGI("CameraService started (pid=%d)", getpid()); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 188 |     mAttributionAndPermissionUtils->setCameraService(this); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 189 |     mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock); | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 190 |     mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING); | 
 | 191 |     if (mMemFd == -1) { | 
 | 192 |         ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName); | 
 | 193 |     } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 194 | } | 
 | 195 |  | 
| Charles Chen | a7b613c | 2023-01-24 21:57:33 +0000 | [diff] [blame] | 196 | // Enable processes with isolated AID to request the binder | 
 | 197 | void CameraService::instantiate() { | 
 | 198 |     CameraService::publish(true); | 
 | 199 | } | 
 | 200 |  | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 201 | void CameraService::onServiceRegistration(const String16& name, const sp<IBinder>&) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 202 |     if (name != toString16(kAppopsServiceName)) { | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 203 |         return; | 
 | 204 |     } | 
 | 205 |  | 
 | 206 |     ALOGV("appops service registered. setting camera audio restriction"); | 
 | 207 |     mAppOps.setCameraAudioRestriction(mAudioRestriction); | 
 | 208 | } | 
 | 209 |  | 
| Iliyan Malchev | 8951a97 | 2011-04-14 16:55:59 -0700 | [diff] [blame] | 210 | void CameraService::onFirstRef() | 
 | 211 | { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 212 |     ALOGI("CameraService process starting"); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 213 |  | 
| Iliyan Malchev | 8951a97 | 2011-04-14 16:55:59 -0700 | [diff] [blame] | 214 |     BnCameraService::onFirstRef(); | 
 | 215 |  | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 216 |     // Update battery life tracking if service is restarting | 
 | 217 |     BatteryNotifier& notifier(BatteryNotifier::getInstance()); | 
 | 218 |     notifier.noteResetCamera(); | 
 | 219 |     notifier.noteResetFlashlight(); | 
 | 220 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 221 |     status_t res = INVALID_OPERATION; | 
| Eino-Ville Talvala | 9cbbc83 | 2017-01-23 15:39:53 -0800 | [diff] [blame] | 222 |  | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 223 |     res = enumerateProviders(); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 224 |     if (res == OK) { | 
 | 225 |         mInitialized = true; | 
 | 226 |     } | 
 | 227 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 228 |     mUidPolicy = new UidPolicy(this); | 
 | 229 |     mUidPolicy->registerSelf(); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 230 |     mSensorPrivacyPolicy = new SensorPrivacyPolicy(this, mAttributionAndPermissionUtils); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 231 |     mSensorPrivacyPolicy->registerSelf(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 232 |     mInjectionStatusListener = new InjectionStatusListener(this); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 233 |  | 
 | 234 |     // appops function setCamerAudioRestriction uses getService which | 
 | 235 |     // is blocking till the appops service is ready. To enable early | 
 | 236 |     // boot availability for cameraservice, use checkService which is | 
 | 237 |     // non blocking and register for notifications | 
 | 238 |     sp<IServiceManager> sm = defaultServiceManager(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 239 |     sp<IBinder> binder = sm->checkService(toString16(kAppopsServiceName)); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 240 |     if (!binder) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 241 |         sm->registerForNotifications(toString16(kAppopsServiceName), this); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 242 |     } else { | 
 | 243 |         mAppOps.setCameraAudioRestriction(mAudioRestriction); | 
 | 244 |     } | 
 | 245 |  | 
| Jayant Chowdhary | be543d4 | 2018-08-15 13:16:14 -0700 | [diff] [blame] | 246 |     sp<HidlCameraService> hcs = HidlCameraService::getInstance(this); | 
 | 247 |     if (hcs->registerAsService() != android::OK) { | 
| Devin Moore | a1350e7 | 2023-01-11 23:40:42 +0000 | [diff] [blame] | 248 |         // Deprecated, so it will fail to register on newer devices | 
 | 249 |         ALOGW("%s: Did not register default android.frameworks.cameraservice.service@2.2", | 
| Jayant Chowdhary | be543d4 | 2018-08-15 13:16:14 -0700 | [diff] [blame] | 250 |               __FUNCTION__); | 
 | 251 |     } | 
| Shuzhen Wang | 24b4415 | 2019-09-20 10:38:11 -0700 | [diff] [blame] | 252 |  | 
| Avichal Rakesh | fcb78cb | 2022-10-27 15:45:54 -0700 | [diff] [blame] | 253 |     if (!AidlCameraService::registerService(this)) { | 
 | 254 |         ALOGE("%s: Failed to register default AIDL VNDK CameraService", __FUNCTION__); | 
 | 255 |     } | 
 | 256 |  | 
| Shuzhen Wang | 24b4415 | 2019-09-20 10:38:11 -0700 | [diff] [blame] | 257 |     // This needs to be last call in this function, so that it's as close to | 
 | 258 |     // ServiceManager::addService() as possible. | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 259 |     mCameraServiceProxyWrapper->pingCameraServiceProxy(); | 
| Shuzhen Wang | 24b4415 | 2019-09-20 10:38:11 -0700 | [diff] [blame] | 260 |     ALOGI("CameraService pinged cameraservice proxy"); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 261 | } | 
 | 262 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 263 | status_t CameraService::enumerateProviders() { | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 264 |     status_t res; | 
| Emilian Peev | aee727d | 2017-05-04 16:35:48 +0100 | [diff] [blame] | 265 |  | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 266 |     std::vector<std::string> deviceIds; | 
| Shuzhen Wang | 3d316f3 | 2022-10-25 20:33:34 +0000 | [diff] [blame] | 267 |     std::unordered_map<std::string, std::set<std::string>> unavailPhysicalIds; | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 268 |     { | 
 | 269 |         Mutex::Autolock l(mServiceLock); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 270 |  | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 271 |         if (nullptr == mCameraProviderManager.get()) { | 
 | 272 |             mCameraProviderManager = new CameraProviderManager(); | 
 | 273 |             res = mCameraProviderManager->initialize(this); | 
 | 274 |             if (res != OK) { | 
 | 275 |                 ALOGE("%s: Unable to initialize camera provider manager: %s (%d)", | 
 | 276 |                         __FUNCTION__, strerror(-res), res); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 277 |                 logServiceError("Unable to initialize camera provider manager", | 
 | 278 |                         ERROR_DISCONNECTED); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 279 |                 return res; | 
| Emilian Peev | aee727d | 2017-05-04 16:35:48 +0100 | [diff] [blame] | 280 |             } | 
 | 281 |         } | 
 | 282 |  | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 283 |         // Setup vendor tags before we call get_camera_info the first time | 
 | 284 |         // because HAL might need to setup static vendor keys in get_camera_info | 
 | 285 |         // TODO: maybe put this into CameraProviderManager::initialize()? | 
 | 286 |         mCameraProviderManager->setUpVendorTags(); | 
 | 287 |  | 
 | 288 |         if (nullptr == mFlashlight.get()) { | 
 | 289 |             mFlashlight = new CameraFlashlight(mCameraProviderManager, this); | 
| Yin-Chia Yeh | 92e3321 | 2017-05-24 15:54:15 -0700 | [diff] [blame] | 290 |         } | 
 | 291 |  | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 292 |         res = mFlashlight->findFlashUnits(); | 
 | 293 |         if (res != OK) { | 
 | 294 |             ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res); | 
 | 295 |         } | 
 | 296 |  | 
| Shuzhen Wang | 3d316f3 | 2022-10-25 20:33:34 +0000 | [diff] [blame] | 297 |         deviceIds = mCameraProviderManager->getCameraDeviceIds(&unavailPhysicalIds); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 298 |     } | 
 | 299 |  | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 300 |     for (auto& cameraId : deviceIds) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 301 |         if (getCameraState(cameraId) == nullptr) { | 
 | 302 |             onDeviceStatusChanged(cameraId, CameraDeviceStatus::PRESENT); | 
| Shuzhen Wang | 6ba3f5e | 2018-11-20 10:04:08 -0800 | [diff] [blame] | 303 |         } | 
| Shuzhen Wang | 3d316f3 | 2022-10-25 20:33:34 +0000 | [diff] [blame] | 304 |         if (unavailPhysicalIds.count(cameraId) > 0) { | 
 | 305 |             for (const auto& physicalId : unavailPhysicalIds[cameraId]) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 306 |                 onDeviceStatusChanged(cameraId, physicalId, CameraDeviceStatus::NOT_PRESENT); | 
| Shuzhen Wang | 3d316f3 | 2022-10-25 20:33:34 +0000 | [diff] [blame] | 307 |             } | 
 | 308 |         } | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 309 |     } | 
 | 310 |  | 
| Shuzhen Wang | b38b53f | 2021-07-15 12:46:09 -0700 | [diff] [blame] | 311 |     // Derive primary rear/front cameras, and filter their charactierstics. | 
 | 312 |     // This needs to be done after all cameras are enumerated and camera ids are sorted. | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 313 |     if (SessionConfigurationUtils::IS_PERF_CLASS) { | 
| Shuzhen Wang | b38b53f | 2021-07-15 12:46:09 -0700 | [diff] [blame] | 314 |         // Assume internal cameras are advertised from the same | 
 | 315 |         // provider. If multiple providers are registered at different time, | 
 | 316 |         // and each provider contains multiple internal color cameras, the current | 
 | 317 |         // logic may filter the characteristics of more than one front/rear color | 
 | 318 |         // cameras. | 
 | 319 |         Mutex::Autolock l(mServiceLock); | 
 | 320 |         filterSPerfClassCharacteristicsLocked(); | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 321 |     } | 
| Shuzhen Wang | 89db299 | 2021-05-20 13:09:48 -0700 | [diff] [blame] | 322 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 323 |     return OK; | 
 | 324 | } | 
 | 325 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 326 | void CameraService::broadcastTorchModeStatus(const std::string& cameraId, TorchModeStatus status, | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 327 |         SystemCameraKind systemCameraKind) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 328 |     // Get the device id and app-visible camera id for the given HAL-visible camera id. | 
 | 329 |     auto [deviceId, mappedCameraId] = | 
 | 330 |             mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
 | 331 |  | 
| Shuzhen Wang | 7d859d4 | 2018-11-06 15:33:23 -0800 | [diff] [blame] | 332 |     Mutex::Autolock lock(mStatusListenerLock); | 
| Shuzhen Wang | 7d859d4 | 2018-11-06 15:33:23 -0800 | [diff] [blame] | 333 |     for (auto& i : mListenerList) { | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 334 |         if (shouldSkipStatusUpdates(systemCameraKind, i->isVendorListener(), i->getListenerPid(), | 
 | 335 |                 i->getListenerUid())) { | 
| malikakash | 82ed435 | 2023-07-21 22:44:34 +0000 | [diff] [blame] | 336 |             ALOGV("%s: Skipping torch callback for system-only camera device %s", | 
 | 337 |                     __FUNCTION__, cameraId.c_str()); | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 338 |             continue; | 
 | 339 |         } | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 340 |  | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 341 |         auto ret = i->getListener()->onTorchStatusChanged(mapToInterface(status), | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 342 |                 mappedCameraId, deviceId); | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 343 |         i->handleBinderStatus(ret, "%s: Failed to trigger onTorchStatusChanged for %d:%d: %d", | 
 | 344 |                 __FUNCTION__, i->getListenerUid(), i->getListenerPid(), ret.exceptionCode()); | 
| Shuzhen Wang | 7d859d4 | 2018-11-06 15:33:23 -0800 | [diff] [blame] | 345 |     } | 
 | 346 | } | 
 | 347 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 348 | CameraService::~CameraService() { | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 349 |     VendorTagDescriptor::clearGlobalVendorTagDescriptor(); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 350 |     mUidPolicy->unregisterSelf(); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 351 |     mSensorPrivacyPolicy->unregisterSelf(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 352 |     mInjectionStatusListener->removeListener(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 353 | } | 
 | 354 |  | 
| Emilian Peev | aee727d | 2017-05-04 16:35:48 +0100 | [diff] [blame] | 355 | void CameraService::onNewProviderRegistered() { | 
 | 356 |     enumerateProviders(); | 
 | 357 | } | 
 | 358 |  | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 359 | void CameraService::filterAPI1SystemCameraLocked( | 
 | 360 |         const std::vector<std::string> &normalDeviceIds) { | 
 | 361 |     mNormalDeviceIdsWithoutSystemCamera.clear(); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 362 |     for (auto &cameraId : normalDeviceIds) { | 
 | 363 |         if (vd_flags::camera_device_awareness()) { | 
 | 364 |             CameraMetadata cameraInfo; | 
 | 365 |             status_t res = mCameraProviderManager->getCameraCharacteristics( | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 366 |                     cameraId, false, &cameraInfo, | 
 | 367 |                     hardware::ICameraService::ROTATION_OVERRIDE_NONE); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 368 |             int32_t deviceId = kDefaultDeviceId; | 
 | 369 |             if (res != OK) { | 
 | 370 |                 ALOGW("%s: Not able to get camera characteristics for camera id %s", | 
 | 371 |                       __FUNCTION__, cameraId.c_str()); | 
 | 372 |             } else { | 
 | 373 |                 deviceId = getDeviceId(cameraInfo); | 
 | 374 |             } | 
 | 375 |             // Cameras associated with non-default device id's (i.e., virtual cameras) can never be | 
 | 376 |             // system cameras, so skip for non-default device id's. | 
 | 377 |             if (deviceId != kDefaultDeviceId) { | 
 | 378 |                 continue; | 
 | 379 |             } | 
 | 380 |         } | 
 | 381 |  | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 382 |         SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 383 |         if (getSystemCameraKind(cameraId, &deviceKind) != OK) { | 
 | 384 |             ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str()); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 385 |             continue; | 
 | 386 |         } | 
 | 387 |         if (deviceKind == SystemCameraKind::SYSTEM_ONLY_CAMERA) { | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 388 |             // All system camera ids will necessarily come after public camera | 
 | 389 |             // device ids as per the HAL interface contract. | 
 | 390 |             break; | 
 | 391 |         } | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 392 |         mNormalDeviceIdsWithoutSystemCamera.push_back(cameraId); | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 393 |     } | 
 | 394 |     ALOGV("%s: number of API1 compatible public cameras is %zu", __FUNCTION__, | 
 | 395 |               mNormalDeviceIdsWithoutSystemCamera.size()); | 
 | 396 | } | 
 | 397 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 398 | status_t CameraService::getSystemCameraKind(const std::string& cameraId, | 
 | 399 |         SystemCameraKind *kind) const { | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 400 |     auto state = getCameraState(cameraId); | 
 | 401 |     if (state != nullptr) { | 
 | 402 |         *kind = state->getSystemCameraKind(); | 
 | 403 |         return OK; | 
 | 404 |     } | 
 | 405 |     // Hidden physical camera ids won't have CameraState | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 406 |     return mCameraProviderManager->getSystemCameraKind(cameraId, kind); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 407 | } | 
 | 408 |  | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 409 | void CameraService::updateCameraNumAndIds() { | 
 | 410 |     Mutex::Autolock l(mServiceLock); | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 411 |     std::pair<int, int> systemAndNonSystemCameras = mCameraProviderManager->getCameraCount(); | 
 | 412 |     // Excludes hidden secure cameras | 
 | 413 |     mNumberOfCameras = | 
 | 414 |             systemAndNonSystemCameras.first + systemAndNonSystemCameras.second; | 
 | 415 |     mNumberOfCamerasWithoutSystemCamera = systemAndNonSystemCameras.second; | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 416 |     mNormalDeviceIds = | 
 | 417 |             mCameraProviderManager->getAPI1CompatibleCameraDeviceIds(); | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 418 |     filterAPI1SystemCameraLocked(mNormalDeviceIds); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 419 | } | 
 | 420 |  | 
| Shuzhen Wang | b38b53f | 2021-07-15 12:46:09 -0700 | [diff] [blame] | 421 | void CameraService::filterSPerfClassCharacteristicsLocked() { | 
| Shuzhen Wang | 89db299 | 2021-05-20 13:09:48 -0700 | [diff] [blame] | 422 |     // To claim to be S Performance primary cameras, the cameras must be | 
 | 423 |     // backward compatible. So performance class primary camera Ids must be API1 | 
 | 424 |     // compatible. | 
 | 425 |     bool firstRearCameraSeen = false, firstFrontCameraSeen = false; | 
 | 426 |     for (const auto& cameraId : mNormalDeviceIdsWithoutSystemCamera) { | 
 | 427 |         int facing = -1; | 
 | 428 |         int orientation = 0; | 
| Shuzhen Wang | f221e8d | 2022-12-15 13:26:29 -0800 | [diff] [blame] | 429 |         int portraitRotation; | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 430 |         getDeviceVersion(cameraId, | 
 | 431 |                 /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, | 
 | 432 |                 /*out*/&portraitRotation, /*out*/&facing, /*out*/&orientation); | 
| Shuzhen Wang | 89db299 | 2021-05-20 13:09:48 -0700 | [diff] [blame] | 433 |         if (facing == -1) { | 
 | 434 |             ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.c_str()); | 
 | 435 |             return; | 
 | 436 |         } | 
 | 437 |  | 
 | 438 |         if ((facing == hardware::CAMERA_FACING_BACK && !firstRearCameraSeen) || | 
 | 439 |                 (facing == hardware::CAMERA_FACING_FRONT && !firstFrontCameraSeen)) { | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 440 |             status_t res = mCameraProviderManager->filterSmallJpegSizes(cameraId); | 
 | 441 |             if (res == OK) { | 
 | 442 |                 mPerfClassPrimaryCameraIds.insert(cameraId); | 
 | 443 |             } else { | 
 | 444 |                 ALOGE("%s: Failed to filter small JPEG sizes for performance class primary " | 
 | 445 |                         "camera %s: %s(%d)", __FUNCTION__, cameraId.c_str(), strerror(-res), res); | 
 | 446 |                 break; | 
 | 447 |             } | 
| Shuzhen Wang | 89db299 | 2021-05-20 13:09:48 -0700 | [diff] [blame] | 448 |  | 
 | 449 |             if (facing == hardware::CAMERA_FACING_BACK) { | 
 | 450 |                 firstRearCameraSeen = true; | 
 | 451 |             } | 
 | 452 |             if (facing == hardware::CAMERA_FACING_FRONT) { | 
 | 453 |                 firstFrontCameraSeen = true; | 
 | 454 |             } | 
 | 455 |         } | 
 | 456 |  | 
 | 457 |         if (firstRearCameraSeen && firstFrontCameraSeen) { | 
 | 458 |             break; | 
 | 459 |         } | 
 | 460 |     } | 
 | 461 | } | 
 | 462 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 463 | void CameraService::addStates(const std::string& cameraId) { | 
| Jayant Chowdhary | 0bd3852 | 2021-11-05 17:49:27 -0700 | [diff] [blame] | 464 |     CameraResourceCost cost; | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 465 |     status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost); | 
 | 466 |     if (res != OK) { | 
 | 467 |         ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res); | 
 | 468 |         return; | 
 | 469 |     } | 
| Shuzhen Wang | 403af6d | 2021-12-21 00:08:43 +0000 | [diff] [blame] | 470 |     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 471 |     res = mCameraProviderManager->getSystemCameraKind(cameraId, &deviceKind); | 
 | 472 |     if (res != OK) { | 
 | 473 |         ALOGE("Failed to query device kind: %s (%d)", strerror(-res), res); | 
 | 474 |         return; | 
 | 475 |     } | 
| Shuzhen Wang | 403af6d | 2021-12-21 00:08:43 +0000 | [diff] [blame] | 476 |     std::vector<std::string> physicalCameraIds; | 
 | 477 |     mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 478 |     std::set<std::string> conflicting; | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 479 |     for (size_t i = 0; i < cost.conflictingDevices.size(); i++) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 480 |         conflicting.emplace(cost.conflictingDevices[i]); | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 481 |     } | 
 | 482 |  | 
 | 483 |     { | 
 | 484 |         Mutex::Autolock lock(mCameraStatesLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 485 |         mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost.resourceCost, | 
| Shuzhen Wang | 403af6d | 2021-12-21 00:08:43 +0000 | [diff] [blame] | 486 |                 conflicting, deviceKind, physicalCameraIds)); | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 487 |     } | 
 | 488 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 489 |     if (mFlashlight->hasFlashUnit(cameraId)) { | 
| Emilian Peev | 7f25e5f | 2018-04-11 16:50:34 +0100 | [diff] [blame] | 490 |         Mutex::Autolock al(mTorchStatusMutex); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 491 |         mTorchStatusMap.add(cameraId, TorchModeStatus::AVAILABLE_OFF); | 
| Shuzhen Wang | 7d859d4 | 2018-11-06 15:33:23 -0800 | [diff] [blame] | 492 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 493 |         broadcastTorchModeStatus(cameraId, TorchModeStatus::AVAILABLE_OFF, deviceKind); | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 494 |     } | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 495 |  | 
 | 496 |     updateCameraNumAndIds(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 497 |     logDeviceAdded(cameraId, "Device added"); | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 498 | } | 
 | 499 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 500 | void CameraService::removeStates(const std::string& cameraId) { | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 501 |     updateCameraNumAndIds(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 502 |     if (mFlashlight->hasFlashUnit(cameraId)) { | 
| Emilian Peev | 7f25e5f | 2018-04-11 16:50:34 +0100 | [diff] [blame] | 503 |         Mutex::Autolock al(mTorchStatusMutex); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 504 |         mTorchStatusMap.removeItem(cameraId); | 
| Guennadi Liakhovetski | 6034bf5 | 2017-12-07 10:28:29 +0100 | [diff] [blame] | 505 |     } | 
 | 506 |  | 
 | 507 |     { | 
 | 508 |         Mutex::Autolock lock(mCameraStatesLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 509 |         mCameraStates.erase(cameraId); | 
| Guennadi Liakhovetski | 6034bf5 | 2017-12-07 10:28:29 +0100 | [diff] [blame] | 510 |     } | 
 | 511 | } | 
 | 512 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 513 | void CameraService::onDeviceStatusChanged(const std::string& cameraId, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 514 |         CameraDeviceStatus newHalStatus) { | 
 | 515 |     ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 516 |             cameraId.c_str(), newHalStatus); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 517 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 518 |     StatusInternal newStatus = mapToInternal(newHalStatus); | 
 | 519 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 520 |     std::shared_ptr<CameraState> state = getCameraState(cameraId); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 521 |  | 
 | 522 |     if (state == nullptr) { | 
| Yin-Chia Yeh | 92e3321 | 2017-05-24 15:54:15 -0700 | [diff] [blame] | 523 |         if (newStatus == StatusInternal::PRESENT) { | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 524 |             ALOGI("%s: Unknown camera ID %s, a new camera is added", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 525 |                     __FUNCTION__, cameraId.c_str()); | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 526 |  | 
 | 527 |             // First add as absent to make sure clients are notified below | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 528 |             addStates(cameraId); | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 529 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 530 |             updateStatus(newStatus, cameraId); | 
| Yin-Chia Yeh | 92e3321 | 2017-05-24 15:54:15 -0700 | [diff] [blame] | 531 |         } else { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 532 |             ALOGE("%s: Bad camera ID %s", __FUNCTION__, cameraId.c_str()); | 
| Yin-Chia Yeh | 92e3321 | 2017-05-24 15:54:15 -0700 | [diff] [blame] | 533 |         } | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 534 |         return; | 
 | 535 |     } | 
 | 536 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 537 |     StatusInternal oldStatus = state->getStatus(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 538 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 539 |     if (oldStatus == newStatus) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 540 |         ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 541 |         return; | 
 | 542 |     } | 
 | 543 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 544 |     if (newStatus == StatusInternal::NOT_PRESENT) { | 
| Henri Chataing | bcb9945 | 2023-11-01 17:40:30 +0000 | [diff] [blame] | 545 |         logDeviceRemoved(cameraId, fmt::format("Device status changed from {} to {}", | 
 | 546 |                 oldStatus, newStatus)); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 547 |         // Set the device status to NOT_PRESENT, clients will no longer be able to connect | 
 | 548 |         // to this device until the status changes | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 549 |         updateStatus(StatusInternal::NOT_PRESENT, cameraId); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 550 |         mVirtualDeviceCameraIdMapper.removeCamera(cameraId); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 551 |  | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 552 |         sp<BasicClient> clientToDisconnectOnline, clientToDisconnectOffline; | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 553 |         { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 554 |             // Don't do this in updateStatus to avoid deadlock over mServiceLock | 
 | 555 |             Mutex::Autolock lock(mServiceLock); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 556 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 557 |             // Remove cached shim parameters | 
 | 558 |             state->setShimParams(CameraParameters()); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 559 |  | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 560 |             // Remove online as well as offline client from the list of active clients, | 
 | 561 |             // if they are present | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 562 |             clientToDisconnectOnline = removeClientLocked(cameraId); | 
 | 563 |             clientToDisconnectOffline = removeClientLocked(kOfflineDevice + cameraId); | 
| Eino-Ville Talvala | 8d942f9 | 2017-03-13 10:09:51 -0700 | [diff] [blame] | 564 |         } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 565 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 566 |         disconnectClient(cameraId, clientToDisconnectOnline); | 
 | 567 |         disconnectClient(kOfflineDevice + cameraId, clientToDisconnectOffline); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 568 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 569 |         removeStates(cameraId); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 570 |     } else { | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 571 |         if (oldStatus == StatusInternal::NOT_PRESENT) { | 
| Henri Chataing | bcb9945 | 2023-11-01 17:40:30 +0000 | [diff] [blame] | 572 |             logDeviceAdded(cameraId, fmt::format("Device status changed from {} to {}", | 
 | 573 |                     oldStatus, newStatus)); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 574 |         } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 575 |         updateStatus(newStatus, cameraId); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 576 |     } | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 577 | } | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 578 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 579 | void CameraService::onDeviceStatusChanged(const std::string& id, | 
 | 580 |         const std::string& physicalId, | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 581 |         CameraDeviceStatus newHalStatus) { | 
 | 582 |     ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 583 |             __FUNCTION__, id.c_str(), physicalId.c_str(), newHalStatus); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 584 |  | 
 | 585 |     StatusInternal newStatus = mapToInternal(newHalStatus); | 
 | 586 |  | 
 | 587 |     std::shared_ptr<CameraState> state = getCameraState(id); | 
 | 588 |  | 
 | 589 |     if (state == nullptr) { | 
 | 590 |         ALOGE("%s: Physical camera id %s status change on a non-present ID %s", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 591 |                 __FUNCTION__, physicalId.c_str(), id.c_str()); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 592 |         return; | 
 | 593 |     } | 
 | 594 |  | 
 | 595 |     StatusInternal logicalCameraStatus = state->getStatus(); | 
 | 596 |     if (logicalCameraStatus != StatusInternal::PRESENT && | 
 | 597 |             logicalCameraStatus != StatusInternal::NOT_AVAILABLE) { | 
 | 598 |         ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 599 |                 __FUNCTION__, physicalId.c_str(), newHalStatus, logicalCameraStatus); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 600 |         return; | 
 | 601 |     } | 
 | 602 |  | 
 | 603 |     bool updated = false; | 
 | 604 |     if (newStatus == StatusInternal::PRESENT) { | 
 | 605 |         updated = state->removeUnavailablePhysicalId(physicalId); | 
 | 606 |     } else { | 
 | 607 |         updated = state->addUnavailablePhysicalId(physicalId); | 
 | 608 |     } | 
 | 609 |  | 
 | 610 |     if (updated) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 611 |         std::string idCombo = id + " : " + physicalId; | 
| Shuzhen Wang | 4fa28d2 | 2020-01-23 15:57:25 -0800 | [diff] [blame] | 612 |         if (newStatus == StatusInternal::PRESENT) { | 
| Henri Chataing | bcb9945 | 2023-11-01 17:40:30 +0000 | [diff] [blame] | 613 |             logDeviceAdded(idCombo, fmt::format("Device status changed to {}", newStatus)); | 
| Shuzhen Wang | 4fa28d2 | 2020-01-23 15:57:25 -0800 | [diff] [blame] | 614 |         } else { | 
| Henri Chataing | bcb9945 | 2023-11-01 17:40:30 +0000 | [diff] [blame] | 615 |             logDeviceRemoved(idCombo, fmt::format("Device status changed to {}", newStatus)); | 
| Shuzhen Wang | 4fa28d2 | 2020-01-23 15:57:25 -0800 | [diff] [blame] | 616 |         } | 
| Jayant Chowdhary | d1478ce | 2020-05-07 17:35:23 -0700 | [diff] [blame] | 617 |         // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275) | 
 | 618 |         SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
 | 619 |         if (getSystemCameraKind(id, &deviceKind) != OK) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 620 |             ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.c_str()); | 
| Jayant Chowdhary | d1478ce | 2020-05-07 17:35:23 -0700 | [diff] [blame] | 621 |             return; | 
 | 622 |         } | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 623 |         Mutex::Autolock lock(mStatusListenerLock); | 
 | 624 |         for (auto& listener : mListenerList) { | 
| Jayant Chowdhary | d1478ce | 2020-05-07 17:35:23 -0700 | [diff] [blame] | 625 |             if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(), | 
 | 626 |                     listener->getListenerPid(), listener->getListenerUid())) { | 
 | 627 |                 ALOGV("Skipping discovery callback for system-only camera device %s", | 
 | 628 |                         id.c_str()); | 
 | 629 |                 continue; | 
 | 630 |             } | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 631 |             auto ret = listener->getListener()->onPhysicalCameraStatusChanged( | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 632 |                     mapToInterface(newStatus), id, physicalId, kDefaultDeviceId); | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 633 |             listener->handleBinderStatus(ret, | 
 | 634 |                     "%s: Failed to trigger onPhysicalCameraStatusChanged for %d:%d: %d", | 
 | 635 |                     __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(), | 
 | 636 |                     ret.exceptionCode()); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 637 |         } | 
 | 638 |     } | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 639 | } | 
 | 640 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 641 | void CameraService::disconnectClient(const std::string& id, sp<BasicClient> clientToDisconnect) { | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 642 |     if (clientToDisconnect.get() != nullptr) { | 
 | 643 |         ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 644 |                 __FUNCTION__, id.c_str()); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 645 |         // Notify the client of disconnection | 
 | 646 |         clientToDisconnect->notifyError( | 
 | 647 |                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, | 
 | 648 |                 CaptureResultExtras{}); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 649 |         clientToDisconnect->disconnect(); | 
 | 650 |     } | 
 | 651 | } | 
 | 652 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 653 | void CameraService::onTorchStatusChanged(const std::string& cameraId, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 654 |         TorchModeStatus newStatus) { | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 655 |     SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC; | 
 | 656 |     status_t res = getSystemCameraKind(cameraId, &systemCameraKind); | 
 | 657 |     if (res != OK) { | 
 | 658 |         ALOGE("%s: Could not get system camera kind for camera id %s", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 659 |                 cameraId.c_str()); | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 660 |         return; | 
 | 661 |     } | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 662 |     Mutex::Autolock al(mTorchStatusMutex); | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 663 |     onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 664 | } | 
 | 665 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 666 | void CameraService::onTorchStatusChanged(const std::string& cameraId, | 
| Jayant Chowdhary | 46ef0f5 | 2021-10-05 14:36:13 -0700 | [diff] [blame] | 667 |         TorchModeStatus newStatus, SystemCameraKind systemCameraKind) { | 
 | 668 |     Mutex::Autolock al(mTorchStatusMutex); | 
 | 669 |     onTorchStatusChangedLocked(cameraId, newStatus, systemCameraKind); | 
 | 670 | } | 
 | 671 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 672 | void CameraService::broadcastTorchStrengthLevel(const std::string& cameraId, | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 673 |         int32_t newStrengthLevel) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 674 |     // Get the device id and app-visible camera id for the given HAL-visible camera id. | 
 | 675 |     auto [deviceId, mappedCameraId] = | 
 | 676 |             mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
 | 677 |  | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 678 |     Mutex::Autolock lock(mStatusListenerLock); | 
 | 679 |     for (auto& i : mListenerList) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 680 |         auto ret = i->getListener()->onTorchStrengthLevelChanged(mappedCameraId, | 
 | 681 |                 newStrengthLevel, deviceId); | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 682 |         i->handleBinderStatus(ret, | 
 | 683 |                 "%s: Failed to trigger onTorchStrengthLevelChanged for %d:%d: %d", __FUNCTION__, | 
 | 684 |                 i->getListenerUid(), i->getListenerPid(), ret.exceptionCode()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 685 |     } | 
 | 686 | } | 
 | 687 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 688 | void CameraService::onTorchStatusChangedLocked(const std::string& cameraId, | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 689 |         TorchModeStatus newStatus, SystemCameraKind systemCameraKind) { | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 690 |     ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 691 |             __FUNCTION__, cameraId.c_str(), newStatus); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 692 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 693 |     TorchModeStatus status; | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 694 |     status_t res = getTorchStatusLocked(cameraId, &status); | 
 | 695 |     if (res) { | 
| Chien-Yu Chen | f6463fc | 2015-04-07 15:11:31 -0700 | [diff] [blame] | 696 |         ALOGE("%s: cannot get torch status of camera %s: %s (%d)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 697 |                 __FUNCTION__, cameraId.c_str(), strerror(-res), res); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 698 |         return; | 
 | 699 |     } | 
 | 700 |     if (status == newStatus) { | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 701 |         return; | 
 | 702 |     } | 
 | 703 |  | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 704 |     res = setTorchStatusLocked(cameraId, newStatus); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 705 |     if (res) { | 
| Eino-Ville Talvala | d309fb9 | 2015-11-25 12:12:45 -0800 | [diff] [blame] | 706 |         ALOGE("%s: Failed to set the torch status to %d: %s (%d)", __FUNCTION__, | 
 | 707 |                 (uint32_t)newStatus, strerror(-res), res); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 708 |         return; | 
 | 709 |     } | 
 | 710 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 711 |     { | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 712 |         // Update battery life logging for flashlight | 
| Chien-Yu Chen | fe751be | 2015-09-01 14:16:44 -0700 | [diff] [blame] | 713 |         Mutex::Autolock al(mTorchUidMapMutex); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 714 |         auto iter = mTorchUidMap.find(cameraId); | 
 | 715 |         if (iter != mTorchUidMap.end()) { | 
 | 716 |             int oldUid = iter->second.second; | 
 | 717 |             int newUid = iter->second.first; | 
 | 718 |             BatteryNotifier& notifier(BatteryNotifier::getInstance()); | 
 | 719 |             if (oldUid != newUid) { | 
 | 720 |                 // If the UID has changed, log the status and update current UID in mTorchUidMap | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 721 |                 if (status == TorchModeStatus::AVAILABLE_ON) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 722 |                     notifier.noteFlashlightOff(toString8(cameraId), oldUid); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 723 |                 } | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 724 |                 if (newStatus == TorchModeStatus::AVAILABLE_ON) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 725 |                     notifier.noteFlashlightOn(toString8(cameraId), newUid); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 726 |                 } | 
 | 727 |                 iter->second.second = newUid; | 
 | 728 |             } else { | 
 | 729 |                 // If the UID has not changed, log the status | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 730 |                 if (newStatus == TorchModeStatus::AVAILABLE_ON) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 731 |                     notifier.noteFlashlightOn(toString8(cameraId), oldUid); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 732 |                 } else { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 733 |                     notifier.noteFlashlightOff(toString8(cameraId), oldUid); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 734 |                 } | 
 | 735 |             } | 
 | 736 |         } | 
 | 737 |     } | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 738 |     broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 739 | } | 
 | 740 |  | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 741 | bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const { | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 742 |     // Returns false if this is not an automotive device type. | 
 | 743 |     if (!isAutomotiveDevice()) | 
 | 744 |         return false; | 
 | 745 |  | 
 | 746 |     // Returns false if no camera id is provided. | 
| Austin Borger | 1c1bee0 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 747 |     if (cam_id.empty()) | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 748 |         return false; | 
 | 749 |  | 
 | 750 |     SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC; | 
 | 751 |     if (getSystemCameraKind(cam_id, &systemCameraKind) != OK) { | 
 | 752 |         // This isn't a known camera ID, so it's not a system camera. | 
 | 753 |         ALOGE("%s: Unknown camera id %s, ", __FUNCTION__, cam_id.c_str()); | 
 | 754 |         return false; | 
 | 755 |     } | 
 | 756 |  | 
 | 757 |     if (systemCameraKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) { | 
 | 758 |         ALOGE("%s: camera id %s is not a system camera", __FUNCTION__, cam_id.c_str()); | 
 | 759 |         return false; | 
 | 760 |     } | 
 | 761 |  | 
 | 762 |     CameraMetadata cameraInfo; | 
 | 763 |     status_t res = mCameraProviderManager->getCameraCharacteristics( | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 764 |             cam_id, false, &cameraInfo, hardware::ICameraService::ROTATION_OVERRIDE_NONE); | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 765 |     if (res != OK){ | 
 | 766 |         ALOGE("%s: Not able to get camera characteristics for camera id %s",__FUNCTION__, | 
 | 767 |                 cam_id.c_str()); | 
 | 768 |         return false; | 
 | 769 |     } | 
 | 770 |  | 
 | 771 |     camera_metadata_entry auto_location  = cameraInfo.find(ANDROID_AUTOMOTIVE_LOCATION); | 
 | 772 |     if (auto_location.count != 1) | 
 | 773 |         return false; | 
 | 774 |  | 
 | 775 |     uint8_t location = auto_location.data.u8[0]; | 
 | 776 |     if ((location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT) && | 
 | 777 |             (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR) && | 
 | 778 |             (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT) && | 
 | 779 |             (location != ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT)) { | 
 | 780 |         return false; | 
 | 781 |     } | 
 | 782 |  | 
 | 783 |     return true; | 
 | 784 | } | 
 | 785 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 786 | Status CameraService::getNumberOfCameras(int32_t type, int32_t deviceId, int32_t devicePolicy, | 
 | 787 |         int32_t* numCameras) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 788 |     ATRACE_CALL(); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 789 |     if (vd_flags::camera_device_awareness() && (deviceId != kDefaultDeviceId) | 
 | 790 |             && (devicePolicy != IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) { | 
 | 791 |         *numCameras = mVirtualDeviceCameraIdMapper.getNumberOfCameras(deviceId); | 
 | 792 |         return Status::ok(); | 
 | 793 |     } | 
 | 794 |  | 
| Emilian Peev | aee727d | 2017-05-04 16:35:48 +0100 | [diff] [blame] | 795 |     Mutex::Autolock l(mServiceLock); | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 796 |     bool hasSystemCameraPermissions = | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 797 |             hasPermissionsForSystemCamera(std::string(), getCallingPid(), | 
 | 798 |                     getCallingUid()); | 
| Eino-Ville Talvala | bad4358 | 2015-08-14 13:12:32 -0700 | [diff] [blame] | 799 |     switch (type) { | 
 | 800 |         case CAMERA_TYPE_BACKWARD_COMPATIBLE: | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 801 |             if (hasSystemCameraPermissions) { | 
 | 802 |                 *numCameras = static_cast<int>(mNormalDeviceIds.size()); | 
 | 803 |             } else { | 
 | 804 |                 *numCameras = static_cast<int>(mNormalDeviceIdsWithoutSystemCamera.size()); | 
 | 805 |             } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 806 |             break; | 
| Eino-Ville Talvala | bad4358 | 2015-08-14 13:12:32 -0700 | [diff] [blame] | 807 |         case CAMERA_TYPE_ALL: | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 808 |             if (hasSystemCameraPermissions) { | 
 | 809 |                 *numCameras = mNumberOfCameras; | 
 | 810 |             } else { | 
 | 811 |                 *numCameras = mNumberOfCamerasWithoutSystemCamera; | 
 | 812 |             } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 813 |             break; | 
| Eino-Ville Talvala | bad4358 | 2015-08-14 13:12:32 -0700 | [diff] [blame] | 814 |         default: | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 815 |             ALOGW("%s: Unknown camera type %d", | 
| Eino-Ville Talvala | bad4358 | 2015-08-14 13:12:32 -0700 | [diff] [blame] | 816 |                     __FUNCTION__, type); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 817 |             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
 | 818 |                     "Unknown camera type %d", type); | 
| Eino-Ville Talvala | bad4358 | 2015-08-14 13:12:32 -0700 | [diff] [blame] | 819 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 820 |     return Status::ok(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 821 | } | 
 | 822 |  | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 823 | Status CameraService::createDefaultRequest(const std::string& unresolvedCameraId, int templateId, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 824 |         int32_t deviceId, int32_t devicePolicy, | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 825 |         /* out */ | 
 | 826 |         hardware::camera2::impl::CameraMetadataNative* request) { | 
 | 827 |     ATRACE_CALL(); | 
 | 828 |  | 
 | 829 |     if (!flags::feature_combination_query()) { | 
 | 830 |         return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, | 
 | 831 |                 "Camera subsystem doesn't support this method!"); | 
 | 832 |     } | 
 | 833 |     if (!mInitialized) { | 
 | 834 |         ALOGE("%s: Camera subsystem is not available", __FUNCTION__); | 
 | 835 |         logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED); | 
 | 836 |         return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available"); | 
 | 837 |     } | 
 | 838 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 839 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 840 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 841 |     if (!cameraIdOptional.has_value()) { | 
 | 842 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 843 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 844 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 845 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 846 |     } | 
 | 847 |     std::string cameraId = cameraIdOptional.value(); | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 848 |  | 
 | 849 |     binder::Status res; | 
 | 850 |     if (request == nullptr) { | 
 | 851 |         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION, | 
 | 852 |                 "Camera %s: Error creating default request", cameraId.c_str()); | 
 | 853 |         return res; | 
 | 854 |     } | 
 | 855 |     camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT; | 
 | 856 |     res = SessionConfigurationUtils::mapRequestTemplateFromClient( | 
 | 857 |             cameraId, templateId, &tempId); | 
 | 858 |     if (!res.isOk()) { | 
 | 859 |         ALOGE("%s: Camera %s: failed to map request Template %d", | 
 | 860 |                 __FUNCTION__, cameraId.c_str(), templateId); | 
 | 861 |         return res; | 
 | 862 |     } | 
 | 863 |  | 
 | 864 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
 | 865 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to create default" | 
 | 866 |                 "request for system only device %s: ", cameraId.c_str()); | 
 | 867 |     } | 
 | 868 |  | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 869 |     CameraMetadata metadata; | 
 | 870 |     status_t err = mCameraProviderManager->createDefaultRequest(cameraId, tempId, &metadata); | 
 | 871 |     if (err == OK) { | 
 | 872 |         request->swap(metadata); | 
 | 873 |     } else if (err == BAD_VALUE) { | 
 | 874 |         res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT, | 
 | 875 |                 "Camera %s: Template ID %d is invalid or not supported: %s (%d)", | 
 | 876 |                 cameraId.c_str(), templateId, strerror(-err), err); | 
 | 877 |     } else { | 
 | 878 |         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION, | 
 | 879 |                 "Camera %s: Error creating default request for template %d: %s (%d)", | 
 | 880 |                 cameraId.c_str(), templateId, strerror(-err), err); | 
 | 881 |     } | 
 | 882 |     return res; | 
 | 883 | } | 
 | 884 |  | 
 | 885 | Status CameraService::isSessionConfigurationWithParametersSupported( | 
| Avichal Rakesh | caf179b | 2024-04-04 18:42:46 -0700 | [diff] [blame] | 886 |         const std::string& unresolvedCameraId, int targetSdkVersion, | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 887 |         const SessionConfiguration& sessionConfiguration, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 888 |         int32_t deviceId, int32_t devicePolicy, | 
| Avichal Rakesh | caf179b | 2024-04-04 18:42:46 -0700 | [diff] [blame] | 889 |         /*out*/ bool* supported) { | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 890 |     ATRACE_CALL(); | 
 | 891 |  | 
 | 892 |     if (!flags::feature_combination_query()) { | 
 | 893 |         return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, | 
 | 894 |                 "Camera subsystem doesn't support this method!"); | 
 | 895 |     } | 
 | 896 |     if (!mInitialized) { | 
 | 897 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
 | 898 |         logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED); | 
 | 899 |         return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available"); | 
 | 900 |     } | 
 | 901 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 902 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 903 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 904 |     if (!cameraIdOptional.has_value()) { | 
 | 905 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 906 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 907 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 908 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 909 |     } | 
 | 910 |     std::string cameraId = cameraIdOptional.value(); | 
 | 911 |  | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 912 |     if (supported == nullptr) { | 
 | 913 |         std::string msg = fmt::sprintf("Camera %s: Invalid 'support' input!", | 
 | 914 |                 unresolvedCameraId.c_str()); | 
 | 915 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 916 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 917 |     } | 
 | 918 |  | 
 | 919 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
 | 920 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query " | 
 | 921 |                 "session configuration with parameters support for system only device %s: ", | 
 | 922 |                 cameraId.c_str()); | 
 | 923 |     } | 
 | 924 |  | 
| Avichal Rakesh | caf179b | 2024-04-04 18:42:46 -0700 | [diff] [blame] | 925 |     bool overrideForPerfClass = flags::calculate_perf_override_during_session_support() && | 
 | 926 |                                 SessionConfigurationUtils::targetPerfClassPrimaryCamera( | 
 | 927 |                                         mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion); | 
 | 928 |  | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 929 |     return isSessionConfigurationWithParametersSupportedUnsafe(cameraId, sessionConfiguration, | 
| Avichal Rakesh | caf179b | 2024-04-04 18:42:46 -0700 | [diff] [blame] | 930 |                                                                overrideForPerfClass, supported); | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 931 | } | 
 | 932 |  | 
 | 933 | Status CameraService::isSessionConfigurationWithParametersSupportedUnsafe( | 
 | 934 |         const std::string& cameraId, const SessionConfiguration& sessionConfiguration, | 
 | 935 |         bool overrideForPerfClass, /*out*/ bool* supported) { | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 936 |     *supported = false; | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 937 |     status_t ret = mCameraProviderManager->isSessionConfigurationSupported( | 
 | 938 |             cameraId, sessionConfiguration, overrideForPerfClass, | 
 | 939 |             /*checkSessionParams=*/true, supported); | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 940 |     binder::Status res; | 
 | 941 |     switch (ret) { | 
 | 942 |         case OK: | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 943 |             // Expected. Do Nothing. | 
 | 944 |             return Status::ok(); | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 945 |         case INVALID_OPERATION: { | 
 | 946 |                 std::string msg = fmt::sprintf( | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 947 |                         "Camera %s: Session configuration with parameters supported query not " | 
 | 948 |                         "supported!", | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 949 |                         cameraId.c_str()); | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 950 |                 ALOGW("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 951 |                 logServiceError(msg, CameraService::ERROR_INVALID_OPERATION); | 
 | 952 |                 *supported = false; | 
 | 953 |                 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str()); | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 954 |             } | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 955 |             break; | 
 | 956 |         case NAME_NOT_FOUND: { | 
 | 957 |                 std::string msg = fmt::sprintf("Camera %s: Unknown camera ID.", cameraId.c_str()); | 
 | 958 |                 ALOGW("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 959 |                 logServiceError(msg, CameraService::ERROR_ILLEGAL_ARGUMENT); | 
 | 960 |                 *supported = false; | 
 | 961 |                 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 962 |             } | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 963 |             break; | 
 | 964 |         default: { | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 965 |                 std::string msg = fmt::sprintf( | 
 | 966 |                         "Unable to retrieve session configuration support for camera " | 
 | 967 |                         "device %s: Error: %s (%d)", | 
 | 968 |                         cameraId.c_str(), strerror(-ret), ret); | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 969 |                 ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 970 |                 logServiceError(msg, CameraService::ERROR_ILLEGAL_ARGUMENT); | 
 | 971 |                 *supported = false; | 
 | 972 |                 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 973 |             } | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 974 |             break; | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 975 |     } | 
| Shuzhen Wang | 045be6c | 2023-10-12 10:01:10 -0700 | [diff] [blame] | 976 | } | 
 | 977 |  | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 978 | Status CameraService::getSessionCharacteristics(const std::string& unresolvedCameraId, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 979 |         int targetSdkVersion, int rotationOverride, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 980 |         const SessionConfiguration& sessionConfiguration, int32_t deviceId, int32_t devicePolicy, | 
 | 981 |         /*out*/ CameraMetadata* outMetadata) { | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 982 |     ATRACE_CALL(); | 
 | 983 |  | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 984 |     if (outMetadata == nullptr) { | 
 | 985 |         std::string msg = | 
 | 986 |                 fmt::sprintf("Camera %s: Invalid 'outMetadata' input!", unresolvedCameraId.c_str()); | 
 | 987 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 988 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 989 |     } | 
 | 990 |  | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 991 |     if (!mInitialized) { | 
 | 992 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
 | 993 |         logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED); | 
 | 994 |         return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available"); | 
 | 995 |     } | 
 | 996 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 997 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 998 |                                                                   devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 999 |     if (!cameraIdOptional.has_value()) { | 
 | 1000 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1001 |                                        unresolvedCameraId.c_str(), deviceId); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1002 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 1003 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 1004 |     } | 
 | 1005 |     std::string cameraId = cameraIdOptional.value(); | 
 | 1006 |  | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1007 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
 | 1008 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1009 |                                 "Unable to retrieve camera" | 
 | 1010 |                                 "characteristics for system only device %s: ", | 
 | 1011 |                                 cameraId.c_str()); | 
 | 1012 |     } | 
 | 1013 |  | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1014 |     bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera( | 
 | 1015 |             mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion); | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 1016 |     if (flags::check_session_support_before_session_char()) { | 
 | 1017 |         bool sessionConfigSupported; | 
 | 1018 |         Status res = isSessionConfigurationWithParametersSupportedUnsafe( | 
 | 1019 |                 cameraId, sessionConfiguration, overrideForPerfClass, &sessionConfigSupported); | 
 | 1020 |         if (!res.isOk()) { | 
 | 1021 |             // isSessionConfigurationWithParametersSupportedUnsafe should log what went wrong and | 
 | 1022 |             // report the correct Status to send to the client. Simply forward the error to | 
 | 1023 |             // the client. | 
 | 1024 |             outMetadata->clear(); | 
 | 1025 |             return res; | 
 | 1026 |         } | 
 | 1027 |         if (!sessionConfigSupported) { | 
 | 1028 |             std::string msg = fmt::sprintf( | 
 | 1029 |                     "Session configuration not supported for camera device %s.", cameraId.c_str()); | 
 | 1030 |             outMetadata->clear(); | 
 | 1031 |             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 1032 |         } | 
 | 1033 |     } | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1034 |  | 
 | 1035 |     status_t ret = mCameraProviderManager->getSessionCharacteristics( | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1036 |             cameraId, sessionConfiguration, overrideForPerfClass, rotationOverride, outMetadata); | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1037 |  | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1038 |     switch (ret) { | 
 | 1039 |         case OK: | 
 | 1040 |             // Expected, no handling needed. | 
 | 1041 |             break; | 
 | 1042 |         case INVALID_OPERATION: { | 
 | 1043 |                 std::string msg = fmt::sprintf( | 
 | 1044 |                         "Camera %s: Session characteristics query not supported!", | 
 | 1045 |                         cameraId.c_str()); | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 1046 |                 ALOGW("%s: %s", __FUNCTION__, msg.c_str()); | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1047 |                 logServiceError(msg, CameraService::ERROR_INVALID_OPERATION); | 
 | 1048 |                 outMetadata->clear(); | 
 | 1049 |                 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str()); | 
 | 1050 |             } | 
 | 1051 |             break; | 
 | 1052 |         case NAME_NOT_FOUND: { | 
 | 1053 |                 std::string msg = fmt::sprintf( | 
 | 1054 |                         "Camera %s: Unknown camera ID.", | 
 | 1055 |                         cameraId.c_str()); | 
| Avichal Rakesh | 8fbda41 | 2024-04-04 17:16:33 -0700 | [diff] [blame] | 1056 |                 ALOGW("%s: %s", __FUNCTION__, msg.c_str()); | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1057 |                 logServiceError(msg, CameraService::ERROR_ILLEGAL_ARGUMENT); | 
 | 1058 |                 outMetadata->clear(); | 
 | 1059 |                 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1060 |             } | 
 | 1061 |             break; | 
 | 1062 |         default: { | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1063 |                 std::string msg = fmt::sprintf( | 
 | 1064 |                         "Unable to retrieve session characteristics for camera device %s: " | 
 | 1065 |                         "Error: %s (%d)", | 
 | 1066 |                         cameraId.c_str(), strerror(-ret), ret); | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1067 |                 ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1068 |                 logServiceError(msg, CameraService::ERROR_INVALID_OPERATION); | 
 | 1069 |                 outMetadata->clear(); | 
 | 1070 |                 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str()); | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1071 |             } | 
 | 1072 |     } | 
 | 1073 |  | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1074 |     return filterSensitiveMetadataIfNeeded(cameraId, outMetadata); | 
 | 1075 | } | 
 | 1076 |  | 
 | 1077 | Status CameraService::filterSensitiveMetadataIfNeeded( | 
 | 1078 |         const std::string& cameraId, CameraMetadata* metadata) { | 
 | 1079 |     int callingPid = getCallingPid(); | 
 | 1080 |     int callingUid = getCallingUid(); | 
 | 1081 |  | 
 | 1082 |     if (callingPid == getpid()) { | 
 | 1083 |         // Caller is cameraserver; no need to remove keys | 
 | 1084 |         return Status::ok(); | 
 | 1085 |     } | 
 | 1086 |  | 
 | 1087 |     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
 | 1088 |     if (getSystemCameraKind(cameraId, &deviceKind) != OK) { | 
 | 1089 |         ALOGE("%s: Couldn't get camera kind for camera id %s", __FUNCTION__, cameraId.c_str()); | 
 | 1090 |         metadata->clear(); | 
 | 1091 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1092 |                                 "Unable to retrieve camera kind for device %s", cameraId.c_str()); | 
 | 1093 |     } | 
 | 1094 |     if (deviceKind == SystemCameraKind::SYSTEM_ONLY_CAMERA) { | 
 | 1095 |         // Attempting to query system only camera without system camera permission would have | 
 | 1096 |         // failed the shouldRejectSystemCameraConnection in the caller. So if we get here | 
 | 1097 |         // for a system only camera, then the caller has the required permission. | 
 | 1098 |         // No need to remove keys | 
 | 1099 |         return Status::ok(); | 
 | 1100 |     } | 
 | 1101 |  | 
 | 1102 |     std::vector<int32_t> tagsRemoved; | 
| Biswarup Pal | e506e73 | 2024-03-27 13:46:20 +0000 | [diff] [blame] | 1103 |     // Get the device id that owns this camera. | 
 | 1104 |     auto [cameraOwnerDeviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair( | 
 | 1105 |             cameraId); | 
 | 1106 |     bool hasCameraPermission = hasPermissionsForCamera(cameraId, callingPid, callingUid, | 
 | 1107 |             cameraOwnerDeviceId); | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1108 |     if (hasCameraPermission) { | 
 | 1109 |         // Caller has camera permission; no need to remove keys | 
 | 1110 |         return Status::ok(); | 
 | 1111 |     } | 
 | 1112 |  | 
 | 1113 |     status_t ret = metadata->removePermissionEntries( | 
 | 1114 |             mCameraProviderManager->getProviderTagIdLocked(cameraId), &tagsRemoved); | 
 | 1115 |     if (ret != OK) { | 
 | 1116 |         metadata->clear(); | 
 | 1117 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1118 |                                 "Failed to remove camera characteristics needing camera permission " | 
 | 1119 |                                 "for device %s:%s (%d)", | 
 | 1120 |                                 cameraId.c_str(), strerror(-ret), ret); | 
 | 1121 |     } | 
 | 1122 |  | 
 | 1123 |     if (!tagsRemoved.empty()) { | 
 | 1124 |         ret = metadata->update(ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, | 
 | 1125 |                                   tagsRemoved.data(), tagsRemoved.size()); | 
 | 1126 |         if (ret != OK) { | 
 | 1127 |             metadata->clear(); | 
 | 1128 |             return STATUS_ERROR_FMT( | 
 | 1129 |                     ERROR_INVALID_OPERATION, | 
 | 1130 |                     "Failed to insert camera keys needing permission for device %s: %s (%d)", | 
 | 1131 |                     cameraId.c_str(), strerror(-ret), ret); | 
 | 1132 |         } | 
 | 1133 |     } | 
 | 1134 |     return Status::ok(); | 
| Avichal Rakesh | 3c522e2 | 2024-02-07 16:40:46 -0800 | [diff] [blame] | 1135 | } | 
 | 1136 |  | 
| malikakash | 22af94c | 2023-12-04 18:13:14 +0000 | [diff] [blame] | 1137 | Status CameraService::injectSessionParams( | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1138 |         const std::string& cameraId, | 
 | 1139 |         const CameraMetadata& sessionParams) { | 
 | 1140 |     if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1141 |         const int pid = getCallingPid(); | 
 | 1142 |         const int uid = getCallingUid(); | 
| malikakash | 22af94c | 2023-12-04 18:13:14 +0000 | [diff] [blame] | 1143 |         ALOGE("%s: Permission Denial: can't inject session params pid=%d, uid=%d", | 
 | 1144 |                 __FUNCTION__, pid, uid); | 
 | 1145 |         return STATUS_ERROR(ERROR_PERMISSION_DENIED, | 
 | 1146 |                 "Permission Denial: no permission to inject session params"); | 
 | 1147 |     } | 
 | 1148 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1149 |     // Do not allow session params injection for a virtual camera. | 
 | 1150 |     auto [deviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
 | 1151 |     if (deviceId != kDefaultDeviceId) { | 
 | 1152 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, | 
 | 1153 |                 "Cannot inject session params for a virtual camera"); | 
 | 1154 |     } | 
 | 1155 |  | 
| malikakash | 22af94c | 2023-12-04 18:13:14 +0000 | [diff] [blame] | 1156 |     std::unique_ptr<AutoConditionLock> serviceLockWrapper = | 
 | 1157 |             AutoConditionLock::waitAndAcquire(mServiceLockWrapper); | 
 | 1158 |  | 
 | 1159 |     auto clientDescriptor = mActiveClientManager.get(cameraId); | 
 | 1160 |     if (clientDescriptor == nullptr) { | 
 | 1161 |         ALOGI("%s: No active client for camera id %s", __FUNCTION__, cameraId.c_str()); | 
 | 1162 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1163 |                 "No active client for camera id %s", cameraId.c_str()); | 
 | 1164 |     } | 
 | 1165 |  | 
 | 1166 |     sp<BasicClient> clientSp = clientDescriptor->getValue(); | 
 | 1167 |     status_t res = clientSp->injectSessionParams(sessionParams); | 
 | 1168 |  | 
 | 1169 |     if (res != OK) { | 
 | 1170 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1171 |                 "Error injecting session params into camera \"%s\": %s (%d)", | 
 | 1172 |                 cameraId.c_str(), strerror(-res), res); | 
 | 1173 |     } | 
 | 1174 |     return Status::ok(); | 
 | 1175 | } | 
 | 1176 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1177 | std::optional<std::string> CameraService::resolveCameraId( | 
 | 1178 |         const std::string& inputCameraId, | 
 | 1179 |         int32_t deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 1180 |         int32_t devicePolicy) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1181 |     if ((deviceId == kDefaultDeviceId) | 
 | 1182 |             || (devicePolicy == IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) { | 
 | 1183 |         auto [storedDeviceId, _] = | 
 | 1184 |                 mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(inputCameraId); | 
 | 1185 |         if (storedDeviceId != kDefaultDeviceId) { | 
 | 1186 |             // Trying to access a virtual camera from default-policy device context, we should fail. | 
 | 1187 |             std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 1188 |                     inputCameraId.c_str(), deviceId); | 
 | 1189 |             ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 1190 |             return std::nullopt; | 
 | 1191 |         } | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 1192 |         return inputCameraId; | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1193 |     } | 
 | 1194 |  | 
 | 1195 |     return mVirtualDeviceCameraIdMapper.getActualCameraId(deviceId, inputCameraId); | 
 | 1196 | } | 
 | 1197 |  | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1198 | Status CameraService::getCameraInfo(int cameraId,  int rotationOverride, int32_t deviceId, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1199 |         int32_t devicePolicy, CameraInfo* cameraInfo) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 1200 |     ATRACE_CALL(); | 
| Emilian Peev | aee727d | 2017-05-04 16:35:48 +0100 | [diff] [blame] | 1201 |     Mutex::Autolock l(mServiceLock); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1202 |     std::string cameraIdStr = cameraIdIntToStrLocked(cameraId, deviceId, devicePolicy); | 
 | 1203 |     if (cameraIdStr.empty()) { | 
 | 1204 |         std::string msg = fmt::sprintf("Camera %d: Invalid camera id for device id %d", | 
 | 1205 |                 cameraId, deviceId); | 
 | 1206 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 1207 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 1208 |     } | 
| malikakash | edb3896 | 2023-09-06 00:03:35 +0000 | [diff] [blame] | 1209 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1210 |     if (shouldRejectSystemCameraConnection(cameraIdStr)) { | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 1211 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera" | 
 | 1212 |                 "characteristics for system only device %s: ", cameraIdStr.c_str()); | 
 | 1213 |     } | 
| Emilian Peev | aee727d | 2017-05-04 16:35:48 +0100 | [diff] [blame] | 1214 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1215 |     if (!mInitialized) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1216 |         logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1217 |         return STATUS_ERROR(ERROR_DISCONNECTED, | 
 | 1218 |                 "Camera subsystem is not available"); | 
| Iliyan Malchev | 8951a97 | 2011-04-14 16:55:59 -0700 | [diff] [blame] | 1219 |     } | 
| Austin Borger | 1c1bee0 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1220 |     bool hasSystemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraId), | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1221 |             getCallingPid(), getCallingUid()); | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 1222 |     int cameraIdBound = mNumberOfCamerasWithoutSystemCamera; | 
 | 1223 |     if (hasSystemCameraPermissions) { | 
 | 1224 |         cameraIdBound = mNumberOfCameras; | 
 | 1225 |     } | 
 | 1226 |     if (cameraId < 0 || cameraId >= cameraIdBound) { | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1227 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, | 
 | 1228 |                 "CameraId is not valid"); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1229 |     } | 
 | 1230 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1231 |     Status ret = Status::ok(); | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 1232 |     int portraitRotation; | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 1233 |     status_t err = mCameraProviderManager->getCameraInfo( | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1234 |             cameraIdStr, rotationOverride, &portraitRotation, cameraInfo); | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1235 |     if (err != OK) { | 
 | 1236 |         ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1237 |                 "Error retrieving camera info from device %d: %s (%d)", cameraId, | 
 | 1238 |                 strerror(-err), err); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1239 |         logServiceError(std::string("Error retrieving camera info from device ") | 
 | 1240 |                 + std::to_string(cameraId), ERROR_INVALID_OPERATION); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1241 |     } | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1242 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1243 |     return ret; | 
 | 1244 | } | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 1245 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1246 | std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt, | 
 | 1247 |         int32_t deviceId, int32_t devicePolicy) { | 
 | 1248 |     if (vd_flags::camera_device_awareness() && (deviceId != kDefaultDeviceId) | 
 | 1249 |             && (devicePolicy != IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) { | 
 | 1250 |         std::optional<std::string> cameraIdOptional = | 
 | 1251 |                 mVirtualDeviceCameraIdMapper.getActualCameraId(cameraIdInt, deviceId); | 
 | 1252 |         return cameraIdOptional.has_value() ? cameraIdOptional.value() : std::string{}; | 
 | 1253 |     } | 
 | 1254 |  | 
 | 1255 |     const std::vector<std::string> *cameraIds = &mNormalDeviceIdsWithoutSystemCamera; | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1256 |     auto callingPid = getCallingPid(); | 
 | 1257 |     auto callingUid = getCallingUid(); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1258 |     bool systemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraIdInt), | 
 | 1259 |             callingPid, callingUid, /* checkCameraPermissions= */ false); | 
 | 1260 |     if (systemCameraPermissions || getpid() == callingPid) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1261 |         cameraIds = &mNormalDeviceIds; | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 1262 |     } | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1263 |     if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(cameraIds->size())) { | 
 | 1264 |         ALOGE("%s: input id %d invalid: valid range (0, %zu)", | 
 | 1265 |                 __FUNCTION__, cameraIdInt, cameraIds->size()); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 1266 |         return std::string{}; | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1267 |     } | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 1268 |  | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 1269 |     return (*cameraIds)[cameraIdInt]; | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 1270 | } | 
 | 1271 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1272 | std::string CameraService::cameraIdIntToStr(int cameraIdInt, int32_t deviceId, | 
 | 1273 |         int32_t devicePolicy) { | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 1274 |     Mutex::Autolock lock(mServiceLock); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1275 |     return cameraIdIntToStrLocked(cameraIdInt, deviceId, devicePolicy); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1276 | } | 
 | 1277 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1278 | Status CameraService::getCameraCharacteristics(const std::string& unresolvedCameraId, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1279 |         int targetSdkVersion, int rotationOverride, int32_t deviceId, int32_t devicePolicy, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1280 |         CameraMetadata* cameraInfo) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 1281 |     ATRACE_CALL(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1282 |  | 
| Zhijun He | 2b59be8 | 2013-09-25 10:14:30 -0700 | [diff] [blame] | 1283 |     if (!cameraInfo) { | 
 | 1284 |         ALOGE("%s: cameraInfo is NULL", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1285 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "cameraInfo is NULL"); | 
| Zhijun He | 2b59be8 | 2013-09-25 10:14:30 -0700 | [diff] [blame] | 1286 |     } | 
 | 1287 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1288 |     if (!mInitialized) { | 
 | 1289 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1290 |         logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1291 |         return STATUS_ERROR(ERROR_DISCONNECTED, | 
 | 1292 |                 "Camera subsystem is not available");; | 
| Zhijun He | 2b59be8 | 2013-09-25 10:14:30 -0700 | [diff] [blame] | 1293 |     } | 
 | 1294 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1295 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 1296 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1297 |     if (!cameraIdOptional.has_value()) { | 
 | 1298 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 1299 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 1300 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 1301 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 1302 |     } | 
 | 1303 |     std::string cameraId = cameraIdOptional.value(); | 
 | 1304 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1305 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 1306 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1307 |                 "characteristics for system only device %s: ", cameraId.c_str()); | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 1308 |     } | 
 | 1309 |  | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 1310 |     bool overrideForPerfClass = | 
 | 1311 |             SessionConfigurationUtils::targetPerfClassPrimaryCamera(mPerfClassPrimaryCameraIds, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1312 |                     cameraId, targetSdkVersion); | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1313 |     status_t res = mCameraProviderManager->getCameraCharacteristics( | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1314 |             cameraId, overrideForPerfClass, cameraInfo, rotationOverride); | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1315 |     if (res != OK) { | 
| Eino-Ville Talvala | a976df8 | 2019-06-13 18:01:58 -0700 | [diff] [blame] | 1316 |         if (res == NAME_NOT_FOUND) { | 
 | 1317 |             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to retrieve camera " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1318 |                     "characteristics for unknown device %s: %s (%d)", cameraId.c_str(), | 
| Eino-Ville Talvala | a976df8 | 2019-06-13 18:01:58 -0700 | [diff] [blame] | 1319 |                     strerror(-res), res); | 
 | 1320 |         } else { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1321 |             logServiceError(fmt::sprintf("Unable to retrieve camera characteristics for device %s.", | 
 | 1322 |                     cameraId.c_str()), ERROR_INVALID_OPERATION); | 
| Eino-Ville Talvala | a976df8 | 2019-06-13 18:01:58 -0700 | [diff] [blame] | 1323 |             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1324 |                     "characteristics for device %s: %s (%d)", cameraId.c_str(), | 
| Eino-Ville Talvala | a976df8 | 2019-06-13 18:01:58 -0700 | [diff] [blame] | 1325 |                     strerror(-res), res); | 
 | 1326 |         } | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 1327 |     } | 
| Emilian Peev | e20c637 | 2018-08-14 18:45:53 +0100 | [diff] [blame] | 1328 |  | 
| Avichal Rakesh | 4baf726 | 2024-03-20 19:16:04 -0700 | [diff] [blame] | 1329 |     return filterSensitiveMetadataIfNeeded(cameraId, cameraInfo); | 
| Zhijun He | 2b59be8 | 2013-09-25 10:14:30 -0700 | [diff] [blame] | 1330 | } | 
 | 1331 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1332 | Status CameraService::getTorchStrengthLevel(const std::string& unresolvedCameraId, int32_t deviceId, | 
 | 1333 |         int32_t devicePolicy, int32_t* torchStrength) { | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 1334 |     ATRACE_CALL(); | 
 | 1335 |     Mutex::Autolock l(mServiceLock); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1336 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1337 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 1338 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1339 |     if (!cameraIdOptional.has_value()) { | 
 | 1340 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 1341 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 1342 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 1343 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 1344 |     } | 
 | 1345 |     std::string cameraId = cameraIdOptional.value(); | 
 | 1346 |  | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 1347 |     if (!mInitialized) { | 
 | 1348 |         ALOGE("%s: Camera HAL couldn't be initialized.", __FUNCTION__); | 
 | 1349 |         return STATUS_ERROR(ERROR_DISCONNECTED, "Camera HAL couldn't be initialized."); | 
 | 1350 |     } | 
 | 1351 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 1352 |     if (torchStrength == NULL) { | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 1353 |         ALOGE("%s: strength level must not be null.", __FUNCTION__); | 
 | 1354 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Strength level should not be null."); | 
 | 1355 |     } | 
 | 1356 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1357 |     status_t res = mCameraProviderManager->getTorchStrengthLevel(cameraId, torchStrength); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 1358 |     if (res != OK) { | 
 | 1359 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve torch " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1360 |             "strength level for device %s: %s (%d)", cameraId.c_str(), | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 1361 |             strerror(-res), res); | 
 | 1362 |     } | 
 | 1363 |     ALOGI("%s: Torch strength level is: %d", __FUNCTION__, *torchStrength); | 
 | 1364 |     return Status::ok(); | 
 | 1365 | } | 
 | 1366 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1367 | std::string CameraService::getFormattedCurrentTime() { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1368 |     time_t now = time(nullptr); | 
 | 1369 |     char formattedTime[64]; | 
 | 1370 |     strftime(formattedTime, sizeof(formattedTime), "%m-%d %H:%M:%S", localtime(&now)); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1371 |     return std::string(formattedTime); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1372 | } | 
 | 1373 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1374 | Status CameraService::getCameraVendorTagDescriptor( | 
 | 1375 |         /*out*/ | 
 | 1376 |         hardware::camera2::params::VendorTagDescriptor* desc) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 1377 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1378 |     if (!mInitialized) { | 
 | 1379 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1380 |         return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem not available"); | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 1381 |     } | 
| Eino-Ville Talvala | 1e74e24 | 2016-03-03 11:24:28 -0800 | [diff] [blame] | 1382 |     sp<VendorTagDescriptor> globalDescriptor = VendorTagDescriptor::getGlobalVendorTagDescriptor(); | 
 | 1383 |     if (globalDescriptor != nullptr) { | 
 | 1384 |         *desc = *(globalDescriptor.get()); | 
 | 1385 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1386 |     return Status::ok(); | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 1387 | } | 
 | 1388 |  | 
| Emilian Peev | 71c73a2 | 2017-03-21 16:35:51 +0000 | [diff] [blame] | 1389 | Status CameraService::getCameraVendorTagCache( | 
 | 1390 |         /*out*/ hardware::camera2::params::VendorTagDescriptorCache* cache) { | 
 | 1391 |     ATRACE_CALL(); | 
 | 1392 |     if (!mInitialized) { | 
 | 1393 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
 | 1394 |         return STATUS_ERROR(ERROR_DISCONNECTED, | 
 | 1395 |                 "Camera subsystem not available"); | 
 | 1396 |     } | 
 | 1397 |     sp<VendorTagDescriptorCache> globalCache = | 
 | 1398 |             VendorTagDescriptorCache::getGlobalVendorTagCache(); | 
 | 1399 |     if (globalCache != nullptr) { | 
 | 1400 |         *cache = *(globalCache.get()); | 
 | 1401 |     } | 
 | 1402 |     return Status::ok(); | 
 | 1403 | } | 
 | 1404 |  | 
| Jayant Chowdhary | 32ced0e | 2021-04-09 14:00:22 -0700 | [diff] [blame] | 1405 | void CameraService::clearCachedVariables() { | 
 | 1406 |     BasicClient::BasicClient::sCameraService = nullptr; | 
 | 1407 | } | 
 | 1408 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1409 | std::pair<int, IPCTransport> CameraService::getDeviceVersion(const std::string& cameraId, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1410 |         int rotationOverride, int* portraitRotation, int* facing, | 
 | 1411 |         int* orientation) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 1412 |     ATRACE_CALL(); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 1413 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1414 |     int deviceVersion = 0; | 
 | 1415 |  | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1416 |     status_t res; | 
 | 1417 |     hardware::hidl_version maxVersion{0,0}; | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1418 |     IPCTransport transport = IPCTransport::INVALID; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1419 |     res = mCameraProviderManager->getHighestSupportedVersion(cameraId, &maxVersion, &transport); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1420 |     if (res != OK || transport == IPCTransport::INVALID) { | 
 | 1421 |         ALOGE("%s: Unable to get highest supported version for camera id %s", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1422 |                 cameraId.c_str()); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1423 |         return std::make_pair(-1, IPCTransport::INVALID) ; | 
 | 1424 |     } | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1425 |     deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor()); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1426 |  | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1427 |     hardware::CameraInfo info; | 
 | 1428 |     if (facing) { | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1429 |         res = mCameraProviderManager->getCameraInfo(cameraId, rotationOverride, | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 1430 |                 portraitRotation, &info); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1431 |         if (res != OK) { | 
 | 1432 |             return std::make_pair(-1, IPCTransport::INVALID); | 
 | 1433 |         } | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1434 |         *facing = info.facing; | 
| Emilian Peev | b91f180 | 2021-03-23 14:50:28 -0700 | [diff] [blame] | 1435 |         if (orientation) { | 
 | 1436 |             *orientation = info.orientation; | 
 | 1437 |         } | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 1438 |     } | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 1439 |  | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1440 |     return std::make_pair(deviceVersion, transport); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 1441 | } | 
 | 1442 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1443 | Status CameraService::filterGetInfoErrorCode(status_t err) { | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 1444 |     switch(err) { | 
 | 1445 |         case NO_ERROR: | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1446 |             return Status::ok(); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 1447 |         case BAD_VALUE: | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1448 |             return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, | 
 | 1449 |                     "CameraId is not valid for HAL module"); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 1450 |         case NO_INIT: | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1451 |             return STATUS_ERROR(ERROR_DISCONNECTED, | 
 | 1452 |                     "Camera device not available"); | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 1453 |         default: | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1454 |             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1455 |                     "Camera HAL encountered error %d: %s", | 
 | 1456 |                     err, strerror(-err)); | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 1457 |     } | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 1458 | } | 
 | 1459 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1460 | Status CameraService::makeClient(const sp<CameraService>& cameraService, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1461 |         const sp<IInterface>& cameraCb, const std::string& packageName, bool systemNativeClient, | 
 | 1462 |         const std::optional<std::string>& featureId,  const std::string& cameraId, | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 1463 |         int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid, | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1464 |         int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1465 |         apiLevel effectiveApiLevel, bool overrideForPerfClass, int rotationOverride, | 
| malikakash | 73125c6 | 2023-07-21 22:44:34 +0000 | [diff] [blame] | 1466 |         bool forceSlowJpegMode, const std::string& originalCameraId, | 
 | 1467 |         /*out*/sp<BasicClient>* client) { | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1468 |     // For HIDL devices | 
 | 1469 |     if (deviceVersionAndTransport.second == IPCTransport::HIDL) { | 
 | 1470 |         // Create CameraClient based on device version reported by the HAL. | 
 | 1471 |         int deviceVersion = deviceVersionAndTransport.first; | 
 | 1472 |         switch(deviceVersion) { | 
 | 1473 |             case CAMERA_DEVICE_API_VERSION_1_0: | 
 | 1474 |                 ALOGE("Camera using old HAL version: %d", deviceVersion); | 
 | 1475 |                 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL, | 
 | 1476 |                         "Camera device \"%s\" HAL version %d no longer supported", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1477 |                         cameraId.c_str(), deviceVersion); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1478 |                 break; | 
 | 1479 |             case CAMERA_DEVICE_API_VERSION_3_0: | 
 | 1480 |             case CAMERA_DEVICE_API_VERSION_3_1: | 
 | 1481 |             case CAMERA_DEVICE_API_VERSION_3_2: | 
 | 1482 |             case CAMERA_DEVICE_API_VERSION_3_3: | 
 | 1483 |             case CAMERA_DEVICE_API_VERSION_3_4: | 
 | 1484 |             case CAMERA_DEVICE_API_VERSION_3_5: | 
 | 1485 |             case CAMERA_DEVICE_API_VERSION_3_6: | 
 | 1486 |             case CAMERA_DEVICE_API_VERSION_3_7: | 
 | 1487 |                 break; | 
 | 1488 |             default: | 
 | 1489 |                 // Should not be reachable | 
 | 1490 |                 ALOGE("Unknown camera device HAL version: %d", deviceVersion); | 
 | 1491 |                 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 1492 |                         "Camera device \"%s\" has unknown HAL version %d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1493 |                         cameraId.c_str(), deviceVersion); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1494 |         } | 
 | 1495 |     } | 
 | 1496 |     if (effectiveApiLevel == API_1) { // Camera1 API route | 
 | 1497 |         sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get()); | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 1498 |         *client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper, | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1499 |                 cameraService->mAttributionAndPermissionUtils, packageName, featureId, cameraId, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1500 |                 api1CameraId, facing, sensorOrientation, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1501 |                 clientPid, clientUid, servicePid, overrideForPerfClass, rotationOverride, | 
| Chengfei Tao | be683db | 2023-01-31 18:52:49 +0000 | [diff] [blame] | 1502 |                 forceSlowJpegMode); | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1503 |         ALOGI("%s: Camera1 API (legacy), rotationOverride %d, forceSlowJpegMode %d", | 
 | 1504 |                 __FUNCTION__, rotationOverride, forceSlowJpegMode); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 1505 |     } else { // Camera2 API route | 
 | 1506 |         sp<hardware::camera2::ICameraDeviceCallbacks> tmp = | 
 | 1507 |                 static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get()); | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 1508 |         *client = new CameraDeviceClient(cameraService, tmp, | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1509 |                 cameraService->mCameraServiceProxyWrapper, | 
 | 1510 |                 cameraService->mAttributionAndPermissionUtils, packageName, systemNativeClient, | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 1511 |                 featureId, cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1512 |                 overrideForPerfClass, rotationOverride, originalCameraId); | 
 | 1513 |         ALOGI("%s: Camera2 API, rotationOverride %d", __FUNCTION__, rotationOverride); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1514 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1515 |     return Status::ok(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1516 | } | 
 | 1517 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1518 | std::string CameraService::toString(std::set<userid_t> intSet) { | 
 | 1519 |     std::ostringstream s; | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 1520 |     bool first = true; | 
 | 1521 |     for (userid_t i : intSet) { | 
 | 1522 |         if (first) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1523 |             s << std::to_string(i); | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 1524 |             first = false; | 
 | 1525 |         } else { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1526 |             s << ", " << std::to_string(i); | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 1527 |         } | 
 | 1528 |     } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1529 |     return std::move(s.str()); | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 1530 | } | 
 | 1531 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 1532 | int32_t CameraService::mapToInterface(TorchModeStatus status) { | 
 | 1533 |     int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; | 
 | 1534 |     switch (status) { | 
 | 1535 |         case TorchModeStatus::NOT_AVAILABLE: | 
 | 1536 |             serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE; | 
 | 1537 |             break; | 
 | 1538 |         case TorchModeStatus::AVAILABLE_OFF: | 
 | 1539 |             serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF; | 
 | 1540 |             break; | 
 | 1541 |         case TorchModeStatus::AVAILABLE_ON: | 
 | 1542 |             serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON; | 
 | 1543 |             break; | 
 | 1544 |         default: | 
 | 1545 |             ALOGW("Unknown new flash status: %d", status); | 
 | 1546 |     } | 
 | 1547 |     return serviceStatus; | 
 | 1548 | } | 
 | 1549 |  | 
 | 1550 | CameraService::StatusInternal CameraService::mapToInternal(CameraDeviceStatus status) { | 
 | 1551 |     StatusInternal serviceStatus = StatusInternal::NOT_PRESENT; | 
 | 1552 |     switch (status) { | 
 | 1553 |         case CameraDeviceStatus::NOT_PRESENT: | 
 | 1554 |             serviceStatus = StatusInternal::NOT_PRESENT; | 
 | 1555 |             break; | 
 | 1556 |         case CameraDeviceStatus::PRESENT: | 
 | 1557 |             serviceStatus = StatusInternal::PRESENT; | 
 | 1558 |             break; | 
 | 1559 |         case CameraDeviceStatus::ENUMERATING: | 
 | 1560 |             serviceStatus = StatusInternal::ENUMERATING; | 
 | 1561 |             break; | 
 | 1562 |         default: | 
 | 1563 |             ALOGW("Unknown new HAL device status: %d", status); | 
 | 1564 |     } | 
 | 1565 |     return serviceStatus; | 
 | 1566 | } | 
 | 1567 |  | 
 | 1568 | int32_t CameraService::mapToInterface(StatusInternal status) { | 
 | 1569 |     int32_t serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT; | 
 | 1570 |     switch (status) { | 
 | 1571 |         case StatusInternal::NOT_PRESENT: | 
 | 1572 |             serviceStatus = ICameraServiceListener::STATUS_NOT_PRESENT; | 
 | 1573 |             break; | 
 | 1574 |         case StatusInternal::PRESENT: | 
 | 1575 |             serviceStatus = ICameraServiceListener::STATUS_PRESENT; | 
 | 1576 |             break; | 
 | 1577 |         case StatusInternal::ENUMERATING: | 
 | 1578 |             serviceStatus = ICameraServiceListener::STATUS_ENUMERATING; | 
 | 1579 |             break; | 
 | 1580 |         case StatusInternal::NOT_AVAILABLE: | 
 | 1581 |             serviceStatus = ICameraServiceListener::STATUS_NOT_AVAILABLE; | 
 | 1582 |             break; | 
 | 1583 |         case StatusInternal::UNKNOWN: | 
 | 1584 |             serviceStatus = ICameraServiceListener::STATUS_UNKNOWN; | 
 | 1585 |             break; | 
 | 1586 |         default: | 
 | 1587 |             ALOGW("Unknown new internal device status: %d", status); | 
 | 1588 |     } | 
 | 1589 |     return serviceStatus; | 
 | 1590 | } | 
 | 1591 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1592 | Status CameraService::initializeShimMetadata(int cameraId) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1593 |     int uid = getCallingUid(); | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 1594 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1595 |     std::string cameraIdStr = std::to_string(cameraId); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1596 |     Status ret = Status::ok(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1597 |     sp<Client> tmp = nullptr; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1598 |     if (!(ret = connectHelper<ICameraClient,Client>( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1599 |             sp<ICameraClient>{nullptr}, cameraIdStr, cameraId, | 
 | 1600 |             kServiceName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID, | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 1601 |             API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 1602 |             /*targetSdkVersion*/ __ANDROID_API_FUTURE__, | 
 | 1603 |             /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1604 |             /*forceSlowJpegMode*/false, cameraIdStr, /*out*/ tmp) | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1605 |             ).isOk()) { | 
| Tomasz Wasilczyk | 12b04a5 | 2023-08-11 15:52:22 +0000 | [diff] [blame] | 1606 |         ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str()); | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 1607 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1608 |     return ret; | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 1609 | } | 
 | 1610 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1611 | Status CameraService::getLegacyParametersLazy(int cameraId, | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1612 |         /*out*/ | 
 | 1613 |         CameraParameters* parameters) { | 
 | 1614 |  | 
 | 1615 |     ALOGV("%s: for cameraId: %d", __FUNCTION__, cameraId); | 
 | 1616 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1617 |     Status ret = Status::ok(); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1618 |  | 
 | 1619 |     if (parameters == NULL) { | 
 | 1620 |         ALOGE("%s: parameters must not be null", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1621 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null"); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1622 |     } | 
 | 1623 |  | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 1624 |     std::string cameraIdStr = std::to_string(cameraId); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1625 |  | 
 | 1626 |     // Check if we already have parameters | 
 | 1627 |     { | 
 | 1628 |         // Scope for service lock | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1629 |         Mutex::Autolock lock(mServiceLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1630 |         auto cameraState = getCameraState(cameraIdStr); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1631 |         if (cameraState == nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1632 |             ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1633 |             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1634 |                     "Invalid camera ID: %s", cameraIdStr.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1635 |         } | 
 | 1636 |         CameraParameters p = cameraState->getShimParams(); | 
 | 1637 |         if (!p.isEmpty()) { | 
 | 1638 |             *parameters = p; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1639 |             return ret; | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1640 |         } | 
 | 1641 |     } | 
 | 1642 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1643 |     int64_t token = clearCallingIdentity(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1644 |     ret = initializeShimMetadata(cameraId); | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1645 |     restoreCallingIdentity(token); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1646 |     if (!ret.isOk()) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1647 |         // Error already logged by callee | 
 | 1648 |         return ret; | 
 | 1649 |     } | 
 | 1650 |  | 
 | 1651 |     // Check for parameters again | 
 | 1652 |     { | 
 | 1653 |         // Scope for service lock | 
 | 1654 |         Mutex::Autolock lock(mServiceLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1655 |         auto cameraState = getCameraState(cameraIdStr); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1656 |         if (cameraState == nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1657 |             ALOGE("%s: Invalid camera ID: %s", __FUNCTION__, cameraIdStr.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1658 |             return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1659 |                     "Invalid camera ID: %s", cameraIdStr.c_str()); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1660 |         } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1661 |         CameraParameters p = cameraState->getShimParams(); | 
 | 1662 |         if (!p.isEmpty()) { | 
 | 1663 |             *parameters = p; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1664 |             return ret; | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1665 |         } | 
 | 1666 |     } | 
 | 1667 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1668 |     ALOGE("%s: Parameters were not initialized, or were empty.  Device may not be present.", | 
 | 1669 |             __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1670 |     return STATUS_ERROR(ERROR_INVALID_OPERATION, "Unable to initialize legacy parameters"); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 1671 | } | 
 | 1672 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1673 | Status CameraService::validateConnectLocked(const std::string& cameraId, | 
 | 1674 |         const std::string& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid, | 
| Chien-Yu Chen | 18df60e | 2016-03-18 18:18:09 -0700 | [diff] [blame] | 1675 |         /*out*/int& originalClientPid) const { | 
| Tyler Luu | 5861a9a | 2011-10-06 00:00:03 -0500 | [diff] [blame] | 1676 |  | 
| Alex Deymo | 9c2a2c2 | 2016-08-25 11:59:14 -0700 | [diff] [blame] | 1677 | #ifdef __BRILLO__ | 
 | 1678 |     UNUSED(clientName8); | 
 | 1679 |     UNUSED(clientUid); | 
 | 1680 |     UNUSED(clientPid); | 
 | 1681 |     UNUSED(originalClientPid); | 
 | 1682 | #else | 
| Chien-Yu Chen | 7939aee | 2016-03-21 18:19:33 -0700 | [diff] [blame] | 1683 |     Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid, | 
 | 1684 |             originalClientPid); | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1685 |     if (!allowed.isOk()) { | 
| Christopher Wiley | ce761d1 | 2016-02-16 10:15:00 -0800 | [diff] [blame] | 1686 |         return allowed; | 
 | 1687 |     } | 
| Alex Deymo | 9c2a2c2 | 2016-08-25 11:59:14 -0700 | [diff] [blame] | 1688 | #endif  // __BRILLO__ | 
| Christopher Wiley | ce761d1 | 2016-02-16 10:15:00 -0800 | [diff] [blame] | 1689 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1690 |     int callingPid = getCallingPid(); | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1691 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 1692 |     if (!mInitialized) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1693 |         ALOGE("CameraService::connect X (PID %d) rejected (camera HAL module not loaded)", | 
 | 1694 |                 callingPid); | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1695 |         return STATUS_ERROR_FMT(ERROR_DISCONNECTED, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1696 |                 "No camera HAL module available to open camera device \"%s\"", cameraId.c_str()); | 
| Iliyan Malchev | 8951a97 | 2011-04-14 16:55:59 -0700 | [diff] [blame] | 1697 |     } | 
 | 1698 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1699 |     if (getCameraState(cameraId) == nullptr) { | 
 | 1700 |         ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1701 |                 cameraId.c_str()); | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1702 |         return STATUS_ERROR_FMT(ERROR_DISCONNECTED, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1703 |                 "No camera device with ID \"%s\" available", cameraId.c_str()); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1704 |     } | 
 | 1705 |  | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1706 |     status_t err = checkIfDeviceIsUsable(cameraId); | 
 | 1707 |     if (err != NO_ERROR) { | 
 | 1708 |         switch(err) { | 
 | 1709 |             case -ENODEV: | 
 | 1710 |             case -EBUSY: | 
 | 1711 |                 return STATUS_ERROR_FMT(ERROR_DISCONNECTED, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1712 |                         "No camera device with ID \"%s\" currently available", cameraId.c_str()); | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1713 |             default: | 
 | 1714 |                 return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1715 |                         "Unknown error connecting to ID \"%s\"", cameraId.c_str()); | 
| Eino-Ville Talvala | 0492686 | 2016-03-02 15:42:53 -0800 | [diff] [blame] | 1716 |         } | 
 | 1717 |     } | 
 | 1718 |     return Status::ok(); | 
| Christopher Wiley | 0039bcf | 2016-02-05 10:29:50 -0800 | [diff] [blame] | 1719 | } | 
 | 1720 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1721 | Status CameraService::validateClientPermissionsLocked(const std::string& cameraId, | 
 | 1722 |         const std::string& clientName, int& clientUid, int& clientPid, | 
| Chien-Yu Chen | 7939aee | 2016-03-21 18:19:33 -0700 | [diff] [blame] | 1723 |         /*out*/int& originalClientPid) const { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1724 |     int callingPid = getCallingPid(); | 
 | 1725 |     int callingUid = getCallingUid(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1726 |  | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1727 |     // Check if we can trust clientUid | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1728 |     if (clientUid == USE_CALLING_UID) { | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1729 |         clientUid = callingUid; | 
 | 1730 |     } else if (!isTrustedCallingUid(callingUid)) { | 
 | 1731 |         ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected " | 
 | 1732 |                 "(don't trust clientUid %d)", callingPid, callingUid, clientUid); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1733 |         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 1734 |                 "Untrusted caller (calling PID %d, UID %d) trying to " | 
 | 1735 |                 "forward camera access to camera %s for client %s (PID %d, UID %d)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1736 |                 callingPid, callingUid, cameraId.c_str(), | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1737 |                 clientName.c_str(), clientPid, clientUid); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1738 |     } | 
 | 1739 |  | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1740 |     // Check if we can trust clientPid | 
 | 1741 |     if (clientPid == USE_CALLING_PID) { | 
 | 1742 |         clientPid = callingPid; | 
 | 1743 |     } else if (!isTrustedCallingUid(callingUid)) { | 
 | 1744 |         ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected " | 
 | 1745 |                 "(don't trust clientPid %d)", callingPid, callingUid, clientPid); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1746 |         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 1747 |                 "Untrusted caller (calling PID %d, UID %d) trying to " | 
 | 1748 |                 "forward camera access to camera %s for client %s (PID %d, UID %d)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1749 |                 callingPid, callingUid, cameraId.c_str(), | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1750 |                 clientName.c_str(), clientPid, clientUid); | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1751 |     } | 
 | 1752 |  | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 1753 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
 | 1754 |         ALOGW("Attempting to connect to system-only camera id %s, connection rejected", | 
 | 1755 |                 cameraId.c_str()); | 
 | 1756 |         return STATUS_ERROR_FMT(ERROR_DISCONNECTED, "No camera device with ID \"%s\" is" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1757 |                                 "available", cameraId.c_str()); | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 1758 |     } | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 1759 |     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
 | 1760 |     if (getSystemCameraKind(cameraId, &deviceKind) != OK) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1761 |         ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str()); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 1762 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "No camera device with ID \"%s\"" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1763 |                 "found while trying to query device kind", cameraId.c_str()); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 1764 |     } | 
 | 1765 |  | 
| Biswarup Pal | e506e73 | 2024-03-27 13:46:20 +0000 | [diff] [blame] | 1766 |     // Get the device id that owns this camera. | 
 | 1767 |     auto [deviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
 | 1768 |  | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 1769 |     // If it's not calling from cameraserver, check the permission if the | 
 | 1770 |     // device isn't a system only camera (shouldRejectSystemCameraConnection already checks for | 
 | 1771 |     // android.permission.SYSTEM_CAMERA for system only camera devices). | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1772 |     bool checkPermissionForCamera = | 
| Biswarup Pal | e506e73 | 2024-03-27 13:46:20 +0000 | [diff] [blame] | 1773 |             hasPermissionsForCamera(cameraId, clientPid, clientUid, clientName, deviceId); | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1774 |     if (callingPid != getpid() && | 
| Joanne Chung | 02c13d0 | 2023-01-16 12:58:05 +0000 | [diff] [blame] | 1775 |                 (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) { | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1776 |         ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1777 |         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 1778 |                 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission", | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1779 |                 clientName.c_str(), clientPid, clientUid, cameraId.c_str()); | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 1780 |     } | 
 | 1781 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 1782 |     // Make sure the UID is in an active state to use the camera | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1783 |     if (!mUidPolicy->isUidActive(callingUid, clientName)) { | 
| Varun Shah | b42f1eb | 2019-04-16 14:45:13 -0700 | [diff] [blame] | 1784 |         int32_t procState = mUidPolicy->getProcState(callingUid); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 1785 |         ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d", | 
 | 1786 |             clientPid, clientUid); | 
 | 1787 |         return STATUS_ERROR_FMT(ERROR_DISABLED, | 
| Varun Shah | b42f1eb | 2019-04-16 14:45:13 -0700 | [diff] [blame] | 1788 |                 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" from background (" | 
 | 1789 |                 "calling UID %d proc state %" PRId32 ")", | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1790 |                 clientName.c_str(), clientPid, clientUid, cameraId.c_str(), | 
| Varun Shah | b42f1eb | 2019-04-16 14:45:13 -0700 | [diff] [blame] | 1791 |                 callingUid, procState); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 1792 |     } | 
 | 1793 |  | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 1794 |     // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases | 
 | 1795 |     // such as rear view and surround view cannot be disabled and are exempt from sensor privacy | 
 | 1796 |     // policy. In all other cases,if sensor privacy is enabled then prevent access to the camera. | 
 | 1797 |     if ((!isAutomotivePrivilegedClient(callingUid) || | 
 | 1798 |             !isAutomotiveExteriorSystemCamera(cameraId)) && | 
 | 1799 |             mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 1800 |         ALOGE("Access Denial: cannot use the camera when sensor privacy is enabled"); | 
 | 1801 |         return STATUS_ERROR_FMT(ERROR_DISABLED, | 
 | 1802 |                 "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" when sensor privacy " | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1803 |                 "is enabled", clientName.c_str(), clientPid, clientUid, cameraId.c_str()); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 1804 |     } | 
 | 1805 |  | 
| Chien-Yu Chen | 4f3d620 | 2016-03-22 10:50:23 -0700 | [diff] [blame] | 1806 |     // Only use passed in clientPid to check permission. Use calling PID as the client PID that's | 
 | 1807 |     // connected to camera service directly. | 
| Chien-Yu Chen | 18df60e | 2016-03-18 18:18:09 -0700 | [diff] [blame] | 1808 |     originalClientPid = clientPid; | 
| Chien-Yu Chen | 4f3d620 | 2016-03-22 10:50:23 -0700 | [diff] [blame] | 1809 |     clientPid = callingPid; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 1810 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 1811 |     userid_t clientUserId = multiuser_get_user_id(clientUid); | 
| Wu-cheng Li | a335543 | 2011-05-20 14:54:25 +0800 | [diff] [blame] | 1812 |  | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 1813 |     // For non-system clients : Only allow clients who are being used by the current foreground | 
 | 1814 |     // device user, unless calling from our own process. | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1815 |     if (!callerHasSystemUid() && callingPid != getpid() && | 
| Jayant Chowdhary | 8ec41c1 | 2019-02-21 20:17:22 -0800 | [diff] [blame] | 1816 |             (mAllowedUsers.find(clientUserId) == mAllowedUsers.end())) { | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 1817 |         ALOGE("CameraService::connect X (PID %d) rejected (cannot connect from " | 
 | 1818 |                 "device user %d, currently allowed device users: %s)", callingPid, clientUserId, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1819 |                 toString(mAllowedUsers).c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1820 |         return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 1821 |                 "Callers from device user %d are not currently allowed to connect to camera \"%s\"", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1822 |                 clientUserId, cameraId.c_str()); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 1823 |     } | 
 | 1824 |  | 
| Jyoti Bhayana | a16cc4c | 2023-09-26 15:37:19 -0700 | [diff] [blame] | 1825 |     if (flags::camera_hsum_permission()) { | 
 | 1826 |         // If the System User tries to access the camera when the device is running in | 
 | 1827 |         // headless system user mode, ensure that client has the required permission | 
 | 1828 |         // CAMERA_HEADLESS_SYSTEM_USER. | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1829 |         if (isHeadlessSystemUserMode() | 
 | 1830 |                 && (clientUserId == USER_SYSTEM) | 
 | 1831 |                 && !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) { | 
| Jyoti Bhayana | a16cc4c | 2023-09-26 15:37:19 -0700 | [diff] [blame] | 1832 |             ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid); | 
 | 1833 |             return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 1834 |                     "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" as Headless System \ | 
 | 1835 |                     User without camera headless system user permission", | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 1836 |                     clientName.c_str(), clientPid, clientUid, cameraId.c_str()); | 
| Jyoti Bhayana | a16cc4c | 2023-09-26 15:37:19 -0700 | [diff] [blame] | 1837 |         } | 
| Jyoti Bhayana | 5bdb5a6 | 2023-08-24 14:46:08 -0700 | [diff] [blame] | 1838 |     } | 
 | 1839 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1840 |     return Status::ok(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1841 | } | 
 | 1842 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1843 | status_t CameraService::checkIfDeviceIsUsable(const std::string& cameraId) const { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1844 |     auto cameraState = getCameraState(cameraId); | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1845 |     int callingPid = getCallingPid(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1846 |     if (cameraState == nullptr) { | 
 | 1847 |         ALOGE("CameraService::connect X (PID %d) rejected (invalid camera ID %s)", callingPid, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1848 |                 cameraId.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1849 |         return -ENODEV; | 
 | 1850 |     } | 
 | 1851 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 1852 |     StatusInternal currentStatus = cameraState->getStatus(); | 
 | 1853 |     if (currentStatus == StatusInternal::NOT_PRESENT) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1854 |         ALOGE("CameraService::connect X (PID %d) rejected (camera %s is not connected)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1855 |                 callingPid, cameraId.c_str()); | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 1856 |         return -ENODEV; | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 1857 |     } else if (currentStatus == StatusInternal::ENUMERATING) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1858 |         ALOGE("CameraService::connect X (PID %d) rejected, (camera %s is initializing)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1859 |                 callingPid, cameraId.c_str()); | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 1860 |         return -EBUSY; | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 1861 |     } | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 1862 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1863 |     return NO_ERROR; | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 1864 | } | 
 | 1865 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1866 | void CameraService::finishConnectLocked(const sp<BasicClient>& client, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 1867 |         const CameraService::DescriptorPtr& desc, int oomScoreOffset, bool systemNativeClient) { | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 1868 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1869 |     // Make a descriptor for the incoming client | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 1870 |     auto clientDescriptor = | 
 | 1871 |             CameraService::CameraClientManager::makeClientDescriptor(client, desc, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 1872 |                     oomScoreOffset, systemNativeClient); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1873 |     auto evicted = mActiveClientManager.addAndEvict(clientDescriptor); | 
 | 1874 |  | 
 | 1875 |     logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()), | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1876 |             client->getPackageName()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1877 |  | 
 | 1878 |     if (evicted.size() > 0) { | 
 | 1879 |         // This should never happen - clients should already have been removed in disconnect | 
 | 1880 |         for (auto& i : evicted) { | 
 | 1881 |             ALOGE("%s: Invalid state: Client for camera %s was not removed in disconnect", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1882 |                     __FUNCTION__, i->getKey().c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1883 |         } | 
 | 1884 |  | 
 | 1885 |         LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, clients not evicted properly", | 
 | 1886 |                 __FUNCTION__); | 
 | 1887 |     } | 
| Eino-Ville Talvala | 24901c8 | 2015-09-04 14:15:58 -0700 | [diff] [blame] | 1888 |  | 
 | 1889 |     // And register a death notification for the client callback. Do | 
 | 1890 |     // this last to avoid Binder policy where a nested Binder | 
 | 1891 |     // transaction might be pre-empted to service the client death | 
 | 1892 |     // notification if the client process dies before linkToDeath is | 
 | 1893 |     // invoked. | 
 | 1894 |     sp<IBinder> remoteCallback = client->getRemote(); | 
 | 1895 |     if (remoteCallback != nullptr) { | 
 | 1896 |         remoteCallback->linkToDeath(this); | 
 | 1897 |     } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1898 | } | 
 | 1899 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1900 | status_t CameraService::handleEvictionsLocked(const std::string& cameraId, int clientPid, | 
 | 1901 |         apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, | 
 | 1902 |         const std::string& packageName, int oomScoreOffset, bool systemNativeClient, | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1903 |         /*out*/ | 
 | 1904 |         sp<BasicClient>* client, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1905 |         std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>* partial) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 1906 |     ATRACE_CALL(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1907 |     status_t ret = NO_ERROR; | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 1908 |     std::vector<DescriptorPtr> evictedClients; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1909 |     DescriptorPtr clientDescriptor; | 
 | 1910 |     { | 
 | 1911 |         if (effectiveApiLevel == API_1) { | 
 | 1912 |             // If we are using API1, any existing client for this camera ID with the same remote | 
 | 1913 |             // should be returned rather than evicted to allow MediaRecorder to work properly. | 
 | 1914 |  | 
 | 1915 |             auto current = mActiveClientManager.get(cameraId); | 
 | 1916 |             if (current != nullptr) { | 
 | 1917 |                 auto clientSp = current->getValue(); | 
 | 1918 |                 if (clientSp.get() != nullptr) { // should never be needed | 
| Ruben Brunk | 0bbf8b2 | 2015-04-30 14:35:42 -0700 | [diff] [blame] | 1919 |                     if (!clientSp->canCastToApiClient(effectiveApiLevel)) { | 
| Shuzhen Wang | b2d43f6 | 2021-08-25 14:01:11 -0700 | [diff] [blame] | 1920 |                         ALOGW("CameraService connect called with a different" | 
| Ruben Brunk | 0bbf8b2 | 2015-04-30 14:35:42 -0700 | [diff] [blame] | 1921 |                                 " API level, evicting prior client..."); | 
 | 1922 |                     } else if (clientSp->getRemote() == remoteCallback) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1923 |                         ALOGI("CameraService::connect X (PID %d) (second call from same" | 
| Ruben Brunk | 0bbf8b2 | 2015-04-30 14:35:42 -0700 | [diff] [blame] | 1924 |                                 " app binder, returning the same client)", clientPid); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1925 |                         *client = clientSp; | 
 | 1926 |                         return NO_ERROR; | 
 | 1927 |                     } | 
 | 1928 |                 } | 
| Wu-cheng Li | 2fd2440 | 2012-02-23 19:01:00 -0800 | [diff] [blame] | 1929 |             } | 
| Wu-cheng Li | 2fd2440 | 2012-02-23 19:01:00 -0800 | [diff] [blame] | 1930 |         } | 
| Wu-cheng Li | 08ad5ef | 2012-04-19 12:35:00 +0800 | [diff] [blame] | 1931 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1932 |         // Get state for the given cameraId | 
 | 1933 |         auto state = getCameraState(cameraId); | 
 | 1934 |         if (state == nullptr) { | 
 | 1935 |             ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 1936 |                 clientPid, cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 1937 |             // Should never get here because validateConnectLocked should have errored out | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 1938 |             return BAD_VALUE; | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 1939 |         } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1940 |  | 
| Jyoti Bhayana | da519ab | 2023-05-15 15:49:15 -0700 | [diff] [blame] | 1941 |         sp<IServiceManager> sm = defaultServiceManager(); | 
 | 1942 |         sp<IBinder> binder = sm->checkService(String16(kProcessInfoServiceName)); | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 1943 |         if (!binder && isAutomotivePrivilegedClient(getCallingUid())) { | 
| Jyoti Bhayana | da519ab | 2023-05-15 15:49:15 -0700 | [diff] [blame] | 1944 |             // If processinfo service is not available and the client is automotive privileged | 
 | 1945 |             // client used for safety critical uses cases such as rear-view and surround-view which | 
 | 1946 |             // needs to be available before android boot completes, then use the hardcoded values | 
 | 1947 |             // for the process state and priority score. As this scenario is before android system | 
 | 1948 |             // services are up and client is native client, hence using NATIVE_ADJ as the priority | 
 | 1949 |             // score and state as PROCESS_STATE_BOUND_TOP as such automotive apps need to be | 
 | 1950 |             // visible on the top. | 
 | 1951 |             clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId, | 
 | 1952 |                     sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()), | 
 | 1953 |                     state->getConflicting(), resource_policy::NATIVE_ADJ, clientPid, | 
 | 1954 |                     ActivityManager::PROCESS_STATE_BOUND_TOP, oomScoreOffset, systemNativeClient); | 
 | 1955 |         } else { | 
 | 1956 |             // Get current active client PIDs | 
 | 1957 |             std::vector<int> ownerPids(mActiveClientManager.getAllOwners()); | 
 | 1958 |             ownerPids.push_back(clientPid); | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 1959 |  | 
| Jyoti Bhayana | da519ab | 2023-05-15 15:49:15 -0700 | [diff] [blame] | 1960 |             std::vector<int> priorityScores(ownerPids.size()); | 
 | 1961 |             std::vector<int> states(ownerPids.size()); | 
 | 1962 |  | 
 | 1963 |             // Get priority scores of all active PIDs | 
 | 1964 |             status_t err = ProcessInfoService::getProcessStatesScoresFromPids(ownerPids.size(), | 
 | 1965 |                     &ownerPids[0], /*out*/&states[0], /*out*/&priorityScores[0]); | 
 | 1966 |             if (err != OK) { | 
 | 1967 |                 ALOGE("%s: Priority score query failed: %d", __FUNCTION__, err); | 
 | 1968 |                 return err; | 
 | 1969 |             } | 
 | 1970 |  | 
 | 1971 |             // Update all active clients' priorities | 
 | 1972 |             std::map<int,resource_policy::ClientPriority> pidToPriorityMap; | 
 | 1973 |             for (size_t i = 0; i < ownerPids.size() - 1; i++) { | 
 | 1974 |                 pidToPriorityMap.emplace(ownerPids[i], | 
 | 1975 |                         resource_policy::ClientPriority(priorityScores[i], states[i], | 
 | 1976 |                         /* isVendorClient won't get copied over*/ false, | 
 | 1977 |                         /* oomScoreOffset won't get copied over*/ 0)); | 
 | 1978 |             } | 
 | 1979 |             mActiveClientManager.updatePriorities(pidToPriorityMap); | 
 | 1980 |  | 
 | 1981 |             int32_t actualScore = priorityScores[priorityScores.size() - 1]; | 
 | 1982 |             int32_t actualState = states[states.size() - 1]; | 
 | 1983 |  | 
 | 1984 |             // Make descriptor for incoming client. We store the oomScoreOffset | 
 | 1985 |             // since we might need it later on new handleEvictionsLocked and | 
 | 1986 |             // ProcessInfoService would not take that into account. | 
 | 1987 |             clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId, | 
 | 1988 |                     sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()), | 
 | 1989 |                     state->getConflicting(), actualScore, clientPid, actualState, | 
 | 1990 |                     oomScoreOffset, systemNativeClient); | 
 | 1991 |         } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1992 |  | 
| Jayant Chowdhary | 5bf11bf | 2019-06-24 19:42:56 -0700 | [diff] [blame] | 1993 |         resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority(); | 
 | 1994 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 1995 |         // Find clients that would be evicted | 
 | 1996 |         auto evicted = mActiveClientManager.wouldEvict(clientDescriptor); | 
 | 1997 |  | 
 | 1998 |         // If the incoming client was 'evicted,' higher priority clients have the camera in the | 
 | 1999 |         // background, so we cannot do evictions | 
 | 2000 |         if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) { | 
 | 2001 |             ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher" | 
 | 2002 |                     " priority).", clientPid); | 
 | 2003 |  | 
 | 2004 |             sp<BasicClient> clientSp = clientDescriptor->getValue(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2005 |             std::string curTime = getFormattedCurrentTime(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2006 |             auto incompatibleClients = | 
 | 2007 |                     mActiveClientManager.getIncompatibleClients(clientDescriptor); | 
 | 2008 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2009 |             std::string msg = fmt::sprintf("%s : DENIED connect device %s client for package %s " | 
 | 2010 |                     "(PID %d, score %d state %d) due to eviction policy", curTime.c_str(), | 
 | 2011 |                     cameraId.c_str(), packageName.c_str(), clientPid, | 
| Jayant Chowdhary | 5bf11bf | 2019-06-24 19:42:56 -0700 | [diff] [blame] | 2012 |                     clientPriority.getScore(), clientPriority.getState()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2013 |  | 
 | 2014 |             for (auto& i : incompatibleClients) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2015 |                 msg += fmt::sprintf("\n   - Blocked by existing device %s client for package %s" | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 2016 |                         "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2017 |                         i->getKey().c_str(), | 
 | 2018 |                         i->getValue()->getPackageName().c_str(), | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 2019 |                         i->getOwnerId(), i->getPriority().getScore(), | 
 | 2020 |                         i->getPriority().getState()); | 
| Eino-Ville Talvala | 022f0cb | 2015-05-19 16:31:16 -0700 | [diff] [blame] | 2021 |                 ALOGE("   Conflicts with: Device %s, client package %s (PID %" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2022 |                         PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().c_str(), | 
 | 2023 |                         i->getValue()->getPackageName().c_str(), i->getOwnerId(), | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 2024 |                         i->getPriority().getScore(), i->getPriority().getState()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2025 |             } | 
 | 2026 |  | 
 | 2027 |             // Log the client's attempt | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 2028 |             Mutex::Autolock l(mLogLock); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2029 |             mEventLog.add(msg); | 
 | 2030 |  | 
| Yin-Chia Yeh | 8dfe464 | 2020-06-01 11:57:45 -0700 | [diff] [blame] | 2031 |             auto current = mActiveClientManager.get(cameraId); | 
 | 2032 |             if (current != nullptr) { | 
 | 2033 |                 return -EBUSY; // CAMERA_IN_USE | 
 | 2034 |             } else { | 
 | 2035 |                 return -EUSERS; // MAX_CAMERAS_IN_USE | 
 | 2036 |             } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2037 |         } | 
 | 2038 |  | 
 | 2039 |         for (auto& i : evicted) { | 
 | 2040 |             sp<BasicClient> clientSp = i->getValue(); | 
 | 2041 |             if (clientSp.get() == nullptr) { | 
 | 2042 |                 ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__); | 
 | 2043 |  | 
 | 2044 |                 // TODO: Remove this | 
 | 2045 |                 LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list", | 
 | 2046 |                         __FUNCTION__); | 
 | 2047 |                 mActiveClientManager.remove(i); | 
 | 2048 |                 continue; | 
 | 2049 |             } | 
 | 2050 |  | 
 | 2051 |             ALOGE("CameraService::connect evicting conflicting client for camera ID %s", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2052 |                     i->getKey().c_str()); | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 2053 |             evictedClients.push_back(i); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2054 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2055 |             // Log the clients evicted | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2056 |             logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID" | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 2057 |                     " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for" | 
 | 2058 |                     " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2059 |                     i->getKey().c_str(), clientSp->getPackageName().c_str(), | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 2060 |                     i->getOwnerId(), i->getPriority().getScore(), | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2061 |                     i->getPriority().getState(), cameraId.c_str(), | 
 | 2062 |                     packageName.c_str(), clientPid, clientPriority.getScore(), | 
| Jayant Chowdhary | 5bf11bf | 2019-06-24 19:42:56 -0700 | [diff] [blame] | 2063 |                     clientPriority.getState())); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2064 |  | 
 | 2065 |             // Notify the client of disconnection | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2066 |             clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2067 |                     CaptureResultExtras()); | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 2068 |         } | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 2069 |     } | 
 | 2070 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2071 |     // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking | 
 | 2072 |     // other clients from connecting in mServiceLockWrapper if held | 
 | 2073 |     mServiceLock.unlock(); | 
 | 2074 |  | 
 | 2075 |     // Clear caller identity temporarily so client disconnect PID checks work correctly | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2076 |     int64_t token = clearCallingIdentity(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2077 |  | 
 | 2078 |     // Destroy evicted clients | 
 | 2079 |     for (auto& i : evictedClients) { | 
 | 2080 |         // Disconnect is blocking, and should only have returned when HAL has cleaned up | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 2081 |         i->getValue()->disconnect(); // Clients will remove themselves from the active client list | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2082 |     } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2083 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2084 |     restoreCallingIdentity(token); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2085 |  | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 2086 |     for (const auto& i : evictedClients) { | 
 | 2087 |         ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2088 |                 __FUNCTION__, i->getKey().c_str(), i->getOwnerId()); | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 2089 |         ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS); | 
 | 2090 |         if (ret == TIMED_OUT) { | 
 | 2091 |             ALOGE("%s: Timed out waiting for client for device %s to disconnect, " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2092 |                     "current clients:\n%s", __FUNCTION__, i->getKey().c_str(), | 
 | 2093 |                     mActiveClientManager.toString().c_str()); | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 2094 |             return -EBUSY; | 
 | 2095 |         } | 
 | 2096 |         if (ret != NO_ERROR) { | 
 | 2097 |             ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2098 |                     "current clients:\n%s", __FUNCTION__, i->getKey().c_str(), strerror(-ret), | 
 | 2099 |                     ret, mActiveClientManager.toString().c_str()); | 
| Ruben Brunk | 4f9576b | 2015-04-10 17:26:56 -0700 | [diff] [blame] | 2100 |             return ret; | 
 | 2101 |         } | 
 | 2102 |     } | 
 | 2103 |  | 
 | 2104 |     evictedClients.clear(); | 
 | 2105 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2106 |     // Once clients have been disconnected, relock | 
 | 2107 |     mServiceLock.lock(); | 
 | 2108 |  | 
 | 2109 |     // Check again if the device was unplugged or something while we weren't holding mServiceLock | 
 | 2110 |     if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) { | 
 | 2111 |         return ret; | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 2112 |     } | 
 | 2113 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2114 |     *partial = clientDescriptor; | 
 | 2115 |     return NO_ERROR; | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 2116 | } | 
 | 2117 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2118 | Status CameraService::connect( | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 2119 |         const sp<ICameraClient>& cameraClient, | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 2120 |         int api1CameraId, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2121 |         const std::string& clientPackageName, | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 2122 |         int clientUid, | 
| Chien-Yu Chen | 98a668f | 2015-12-18 14:10:33 -0800 | [diff] [blame] | 2123 |         int clientPid, | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 2124 |         int targetSdkVersion, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2125 |         int rotationOverride, | 
| Chengfei Tao | be683db | 2023-01-31 18:52:49 +0000 | [diff] [blame] | 2126 |         bool forceSlowJpegMode, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2127 |         int32_t deviceId, | 
 | 2128 |         int32_t devicePolicy, | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 2129 |         /*out*/ | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2130 |         sp<ICamera>* device) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 2131 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2132 |     Status ret = Status::ok(); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 2133 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2134 |     std::string cameraIdStr = cameraIdIntToStr(api1CameraId, deviceId, devicePolicy); | 
 | 2135 |     if (cameraIdStr.empty()) { | 
 | 2136 |         std::string msg = fmt::sprintf("Camera %d: Invalid camera id for device id %d", | 
 | 2137 |                 api1CameraId, deviceId); | 
 | 2138 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2139 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 2140 |     } | 
| malikakash | edb3896 | 2023-09-06 00:03:35 +0000 | [diff] [blame] | 2141 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2142 |     sp<Client> client = nullptr; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2143 |     ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId, | 
 | 2144 |             clientPackageName, /*systemNativeClient*/ false, {}, clientUid, clientPid, API_1, | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 2145 |             /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2146 |             rotationOverride, forceSlowJpegMode, cameraIdStr, /*out*/client); | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 2147 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2148 |     if (!ret.isOk()) { | 
 | 2149 |         logRejected(cameraIdStr, getCallingPid(), clientPackageName, toStdString(ret.toString8())); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2150 |         return ret; | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 2151 |     } | 
 | 2152 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2153 |     *device = client; | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 2154 |  | 
 | 2155 |     const sp<IServiceManager> sm(defaultServiceManager()); | 
 | 2156 |     const auto& mActivityManager = getActivityManager(); | 
 | 2157 |     if (mActivityManager) { | 
 | 2158 |         mActivityManager->logFgsApiBegin(LOG_FGS_CAMERA_API, | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2159 |             getCallingUid(), | 
 | 2160 |             getCallingPid()); | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 2161 |     } | 
 | 2162 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2163 |     return ret; | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 2164 | } | 
 | 2165 |  | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 2166 | bool CameraService::shouldSkipStatusUpdates(SystemCameraKind systemCameraKind, | 
 | 2167 |         bool isVendorListener, int clientPid, int clientUid) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2168 |     // If the client is not a vendor client, don't add listener if | 
 | 2169 |     //   a) the camera is a publicly hidden secure camera OR | 
 | 2170 |     //   b) the camera is a system only camera and the client doesn't | 
 | 2171 |     //      have android.permission.SYSTEM_CAMERA permissions. | 
 | 2172 |     if (!isVendorListener && (systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA || | 
 | 2173 |             (systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA && | 
| Austin Borger | 1c1bee0 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2174 |             !hasPermissionsForSystemCamera(std::string(), clientPid, clientUid)))) { | 
| Jayant Chowdhary | f949ddd | 2019-01-29 14:34:11 -0800 | [diff] [blame] | 2175 |         return true; | 
 | 2176 |     } | 
 | 2177 |     return false; | 
 | 2178 | } | 
 | 2179 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2180 | bool CameraService::shouldRejectSystemCameraConnection(const std::string& cameraId) const { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2181 |     // Rules for rejection: | 
 | 2182 |     // 1) If cameraserver tries to access this camera device, accept the | 
 | 2183 |     //    connection. | 
 | 2184 |     // 2) The camera device is a publicly hidden secure camera device AND some | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2185 |     //    non system component is trying to access it. | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2186 |     // 3) if the camera device is advertised by the camera HAL as SYSTEM_ONLY | 
 | 2187 |     //    and the serving thread is a non hwbinder thread, the client must have | 
 | 2188 |     //    android.permission.SYSTEM_CAMERA permissions to connect. | 
 | 2189 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2190 |     int cPid = getCallingPid(); | 
 | 2191 |     int cUid = getCallingUid(); | 
 | 2192 |     bool systemClient = callerHasSystemUid(); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 2193 |     SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC; | 
 | 2194 |     if (getSystemCameraKind(cameraId, &systemCameraKind) != OK) { | 
| Eino-Ville Talvala | a976df8 | 2019-06-13 18:01:58 -0700 | [diff] [blame] | 2195 |         // This isn't a known camera ID, so it's not a system camera | 
 | 2196 |         ALOGV("%s: Unknown camera id %s, ", __FUNCTION__, cameraId.c_str()); | 
 | 2197 |         return false; | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 2198 |     } | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2199 |  | 
 | 2200 |     // (1) Cameraserver trying to connect, accept. | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 2201 |     if (isCallerCameraServerNotDelegating()) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2202 |         return false; | 
 | 2203 |     } | 
 | 2204 |     // (2) | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2205 |     if (!systemClient && systemCameraKind == SystemCameraKind::HIDDEN_SECURE_CAMERA) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2206 |         ALOGW("Rejecting access to secure hidden camera %s", cameraId.c_str()); | 
 | 2207 |         return true; | 
 | 2208 |     } | 
 | 2209 |     // (3) Here we only check for permissions if it is a system only camera device. This is since | 
 | 2210 |     //     getCameraCharacteristics() allows for calls to succeed (albeit after hiding some | 
 | 2211 |     //     characteristics) even if clients don't have android.permission.CAMERA. We do not want the | 
 | 2212 |     //     same behavior for system camera devices. | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2213 |     if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA && | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 2214 |             !hasPermissionsForSystemCamera(cameraId, cPid, cUid)) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 2215 |         ALOGW("Rejecting access to system only camera %s, inadequete permissions", | 
 | 2216 |                 cameraId.c_str()); | 
 | 2217 |         return true; | 
 | 2218 |     } | 
 | 2219 |  | 
 | 2220 |     return false; | 
 | 2221 | } | 
 | 2222 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2223 | Status CameraService::connectDevice( | 
 | 2224 |         const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2225 |         const std::string& unresolvedCameraId, | 
 | 2226 |         const std::string& clientPackageName, | 
 | 2227 |         const std::optional<std::string>& clientFeatureId, | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 2228 |         int clientUid, int oomScoreOffset, int targetSdkVersion, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2229 |         int rotationOverride, int32_t deviceId, int32_t devicePolicy, | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2230 |         /*out*/ | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2231 |         sp<hardware::camera2::ICameraDeviceUser>* device) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 2232 |     ATRACE_CALL(); | 
| Emilian Peev | 31bd242 | 2024-04-23 22:24:09 +0000 | [diff] [blame] | 2233 |     RunThreadWithRealtimePriority priorityBump; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2234 |     Status ret = Status::ok(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2235 |     sp<CameraDeviceClient> client = nullptr; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2236 |     std::string clientPackageNameAdj = clientPackageName; | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2237 |     int callingPid = getCallingPid(); | 
 | 2238 |     int callingUid = getCallingUid(); | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2239 |     bool systemNativeClient = false; | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2240 |     if (callerHasSystemUid() && (clientPackageNameAdj.size() == 0)) { | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 2241 |         std::string systemClient = fmt::sprintf("client.pid<%d>", callingPid); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2242 |         clientPackageNameAdj = systemClient; | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2243 |         systemNativeClient = true; | 
| Jayant Chowdhary | 5bf11bf | 2019-06-24 19:42:56 -0700 | [diff] [blame] | 2244 |     } | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 2245 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2246 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 2247 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2248 |     if (!cameraIdOptional.has_value()) { | 
 | 2249 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 2250 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 2251 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2252 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 2253 |     } | 
 | 2254 |     std::string cameraId = cameraIdOptional.value(); | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2255 |  | 
 | 2256 |     if (oomScoreOffset < 0) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2257 |         std::string msg = | 
 | 2258 |                 fmt::sprintf("Cannot increase the priority of a client %s pid %d for " | 
 | 2259 |                         "camera id %s", clientPackageNameAdj.c_str(), callingPid, | 
 | 2260 |                         cameraId.c_str()); | 
 | 2261 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2262 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2263 |     } | 
 | 2264 |  | 
| Austin Borger | 9bfa0a7 | 2022-08-03 17:50:40 -0700 | [diff] [blame] | 2265 |     userid_t clientUserId = multiuser_get_user_id(clientUid); | 
| Austin Borger | 9bfa0a7 | 2022-08-03 17:50:40 -0700 | [diff] [blame] | 2266 |     if (clientUid == USE_CALLING_UID) { | 
 | 2267 |         clientUserId = multiuser_get_user_id(callingUid); | 
 | 2268 |     } | 
 | 2269 |  | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 2270 |     // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for use cases | 
 | 2271 |     // such as rear view and surround view cannot be disabled. | 
| Austin Borger | 1c1bee0 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2272 |     if ((!isAutomotivePrivilegedClient(callingUid) || !isAutomotiveExteriorSystemCamera(cameraId)) | 
 | 2273 |             && mCameraServiceProxyWrapper->isCameraDisabled(clientUserId)) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2274 |         std::string msg = "Camera disabled by device policy"; | 
 | 2275 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2276 |         return STATUS_ERROR(ERROR_DISABLED, msg.c_str()); | 
| Austin Borger | 5f7abe2 | 2022-04-26 15:55:10 -0700 | [diff] [blame] | 2277 |     } | 
 | 2278 |  | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2279 |     // enforce system camera permissions | 
| Austin Borger | 1c1bee0 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2280 |     if (oomScoreOffset > 0 | 
 | 2281 |             && !hasPermissionsForSystemCamera(cameraId, callingPid, | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 2282 |                     callingUid) | 
 | 2283 |             && !isTrustedCallingUid(callingUid)) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2284 |         std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for " | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2285 |                         "camera id %s without SYSTEM_CAMERA permissions", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2286 |                         clientPackageNameAdj.c_str(), callingPid, cameraId.c_str()); | 
 | 2287 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2288 |         return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str()); | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2289 |     } | 
 | 2290 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2291 |     ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, | 
 | 2292 |             cameraId, /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient, clientFeatureId, | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2293 |             clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2294 |             targetSdkVersion, rotationOverride, /*forceSlowJpegMode*/false, unresolvedCameraId, | 
| Chengfei Tao | be683db | 2023-01-31 18:52:49 +0000 | [diff] [blame] | 2295 |             /*out*/client); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2296 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2297 |     if (!ret.isOk()) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2298 |         logRejected(cameraId, callingPid, clientPackageNameAdj, toStdString(ret.toString8())); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2299 |         return ret; | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 2300 |     } | 
 | 2301 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2302 |     *device = client; | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 2303 |     Mutex::Autolock lock(mServiceLock); | 
 | 2304 |  | 
 | 2305 |     // Clear the previous cached logs and reposition the | 
 | 2306 |     // file offset to beginning of the file to log new data. | 
 | 2307 |     // If either truncate or lseek fails, close the previous file and create a new one. | 
 | 2308 |     if ((ftruncate(mMemFd, 0) == -1) || (lseek(mMemFd, 0, SEEK_SET) == -1)) { | 
 | 2309 |         ALOGE("%s: Error while truncating the file: %s", __FUNCTION__, sFileName); | 
 | 2310 |         // Close the previous memfd. | 
 | 2311 |         close(mMemFd); | 
 | 2312 |         // If failure to wipe the data, then create a new file and | 
 | 2313 |         // assign the new value to mMemFd. | 
 | 2314 |         mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING); | 
 | 2315 |         if (mMemFd == -1) { | 
 | 2316 |             ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName); | 
 | 2317 |         } | 
 | 2318 |     } | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 2319 |     const sp<IServiceManager> sm(defaultServiceManager()); | 
 | 2320 |     const auto& mActivityManager = getActivityManager(); | 
 | 2321 |     if (mActivityManager) { | 
 | 2322 |         mActivityManager->logFgsApiBegin(LOG_FGS_CAMERA_API, | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 2323 |             callingUid, | 
 | 2324 |             callingPid); | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 2325 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2326 |     return ret; | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 2327 | } | 
 | 2328 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2329 | bool CameraService::isCameraPrivacyEnabled(const String16& packageName, const std::string& cam_id, | 
 | 2330 |         int callingPid, int callingUid) { | 
 | 2331 |     if (!isAutomotiveDevice()) { | 
 | 2332 |         return mSensorPrivacyPolicy->isCameraPrivacyEnabled(); | 
 | 2333 |     } | 
 | 2334 |  | 
 | 2335 |     // Automotive privileged client AID_AUTOMOTIVE_EVS using exterior system camera for | 
 | 2336 |     // safety-critical use cases cannot be disabled and are exempt from camera privacy policy. | 
 | 2337 |     if ((isAutomotivePrivilegedClient(callingUid) && isAutomotiveExteriorSystemCamera(cam_id))) { | 
 | 2338 |         ALOGI("Camera privacy cannot be enabled for automotive privileged client %d " | 
 | 2339 |                 "using camera %s", callingUid, cam_id.c_str()); | 
 | 2340 |         return false; | 
 | 2341 |     } | 
 | 2342 |  | 
 | 2343 |     if (mSensorPrivacyPolicy->isCameraPrivacyEnabled(packageName)) { | 
 | 2344 |         return true; | 
 | 2345 |     } else if (mSensorPrivacyPolicy->getCameraPrivacyState() == SensorPrivacyManager::DISABLED) { | 
 | 2346 |         return false; | 
| Jyoti Bhayana | 54a4b00 | 2024-02-27 15:36:09 -0800 | [diff] [blame] | 2347 |     } else if (mSensorPrivacyPolicy->getCameraPrivacyState() | 
 | 2348 |             == SensorPrivacyManager::ENABLED_EXCEPT_ALLOWLISTED_APPS) { | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2349 |         if (hasPermissionsForCameraPrivacyAllowlist(callingPid, callingUid)) { | 
 | 2350 |             return false; | 
 | 2351 |         } else { | 
 | 2352 |             return true; | 
 | 2353 |         } | 
 | 2354 |     } | 
 | 2355 |     return false; | 
 | 2356 | } | 
 | 2357 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2358 | std::string CameraService::getPackageNameFromUid(int clientUid) { | 
 | 2359 |     std::string packageName(""); | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2360 |  | 
| Avichal Rakesh | 5788fec | 2024-03-15 14:39:20 -0700 | [diff] [blame] | 2361 |     sp<IPermissionController> permCtrl; | 
 | 2362 |     if (flags::cache_permission_services()) { | 
 | 2363 |         permCtrl = getPermissionController(); | 
 | 2364 |     } else { | 
 | 2365 |         sp<IServiceManager> sm = defaultServiceManager(); | 
 | 2366 | #pragma clang diagnostic push | 
 | 2367 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 
 | 2368 |         // Using deprecated function to preserve functionality until the | 
 | 2369 |         // cache_permission_services flag is removed. | 
 | 2370 |         sp<IBinder> binder = sm->getService(toString16(kPermissionServiceName)); | 
 | 2371 | #pragma clang diagnostic pop | 
 | 2372 |         if (binder == 0) { | 
 | 2373 |             ALOGE("Cannot get permission service"); | 
 | 2374 |             permCtrl = nullptr; | 
 | 2375 |         } else { | 
 | 2376 |             permCtrl = interface_cast<IPermissionController>(binder); | 
 | 2377 |         } | 
 | 2378 |     } | 
 | 2379 |  | 
 | 2380 |     if (permCtrl == nullptr) { | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2381 |         // Return empty package name and the further interaction | 
 | 2382 |         // with camera will likely fail | 
 | 2383 |         return packageName; | 
 | 2384 |     } | 
 | 2385 |  | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2386 |     Vector<String16> packages; | 
 | 2387 |  | 
 | 2388 |     permCtrl->getPackagesForUid(clientUid, packages); | 
 | 2389 |  | 
 | 2390 |     if (packages.isEmpty()) { | 
 | 2391 |         ALOGE("No packages for calling UID %d", clientUid); | 
 | 2392 |         // Return empty package name and the further interaction | 
 | 2393 |         // with camera will likely fail | 
 | 2394 |         return packageName; | 
 | 2395 |     } | 
 | 2396 |  | 
 | 2397 |     // Arbitrarily pick the first name in the list | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2398 |     packageName = toStdString(packages[0]); | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2399 |  | 
 | 2400 |     return packageName; | 
 | 2401 | } | 
 | 2402 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2403 | template<class CALLBACK, class CLIENT> | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2404 | Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId, | 
 | 2405 |         int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient, | 
 | 2406 |         const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid, | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 2407 |         apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2408 |         int rotationOverride, bool forceSlowJpegMode, | 
 | 2409 |         const std::string& originalCameraId, /*out*/sp<CLIENT>& device) { | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2410 |     binder::Status ret = binder::Status::ok(); | 
 | 2411 |  | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2412 |     bool isNonSystemNdk = false; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2413 |     std::string clientPackageName; | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 2414 |     int packageUid = (clientUid == USE_CALLING_UID) ? | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2415 |             getCallingUid() : clientUid; | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2416 |     if (clientPackageNameMaybe.size() <= 0) { | 
 | 2417 |         // NDK calls don't come with package names, but we need one for various cases. | 
 | 2418 |         // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs | 
 | 2419 |         // do exist. For all authentication cases, all packages under the same UID get the | 
 | 2420 |         // same permissions, so picking any associated package name is sufficient. For some | 
 | 2421 |         // other cases, this may give inaccurate names for clients in logs. | 
 | 2422 |         isNonSystemNdk = true; | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2423 |         clientPackageName = getPackageNameFromUid(packageUid); | 
 | 2424 |     } else { | 
 | 2425 |         clientPackageName = clientPackageNameMaybe; | 
 | 2426 |     } | 
 | 2427 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2428 |     int originalClientPid = 0; | 
 | 2429 |  | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2430 |     int packagePid = (clientPid == USE_CALLING_PID) ? | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2431 |         getCallingPid() : clientPid; | 
| Eino-Ville Talvala | a976df8 | 2019-06-13 18:01:58 -0700 | [diff] [blame] | 2432 |     ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2433 |             "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(), | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2434 |             static_cast<int>(effectiveApiLevel)); | 
 | 2435 |  | 
| Shuzhen Wang | 316781a | 2020-08-18 18:11:01 -0700 | [diff] [blame] | 2436 |     nsecs_t openTimeNs = systemTime(); | 
 | 2437 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2438 |     sp<CLIENT> client = nullptr; | 
| Shuzhen Wang | 316781a | 2020-08-18 18:11:01 -0700 | [diff] [blame] | 2439 |     int facing = -1; | 
| Emilian Peev | b91f180 | 2021-03-23 14:50:28 -0700 | [diff] [blame] | 2440 |     int orientation = 0; | 
| Eino-Ville Talvala | 58106af | 2022-09-23 16:51:06 -0700 | [diff] [blame] | 2441 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2442 |     { | 
 | 2443 |         // Acquire mServiceLock and prevent other clients from connecting | 
 | 2444 |         std::unique_ptr<AutoConditionLock> lock = | 
 | 2445 |                 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS); | 
 | 2446 |  | 
 | 2447 |         if (lock == nullptr) { | 
 | 2448 |             ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)." | 
 | 2449 |                     , clientPid); | 
 | 2450 |             return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE, | 
 | 2451 |                     "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2452 |                     cameraId.c_str(), clientPackageName.c_str(), clientPid); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2453 |         } | 
 | 2454 |  | 
| Eino-Ville Talvala | 0bdfa28 | 2020-06-19 13:54:35 -0700 | [diff] [blame] | 2455 |         // Enforce client permissions and do basic validity checks | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2456 |         if (!(ret = validateConnectLocked(cameraId, clientPackageName, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2457 |                 /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) { | 
 | 2458 |             return ret; | 
 | 2459 |         } | 
 | 2460 |  | 
 | 2461 |         // Check the shim parameters after acquiring lock, if they have already been updated and | 
 | 2462 |         // we were doing a shim update, return immediately | 
 | 2463 |         if (shimUpdateOnly) { | 
 | 2464 |             auto cameraState = getCameraState(cameraId); | 
 | 2465 |             if (cameraState != nullptr) { | 
 | 2466 |                 if (!cameraState->getShimParams().isEmpty()) return ret; | 
 | 2467 |             } | 
 | 2468 |         } | 
 | 2469 |  | 
 | 2470 |         status_t err; | 
 | 2471 |  | 
 | 2472 |         sp<BasicClient> clientTmp = nullptr; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2473 |         std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>> partial; | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2474 |         if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2475 |                 IInterface::asBinder(cameraCb), clientPackageName, oomScoreOffset, | 
 | 2476 |                 systemNativeClient, /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) { | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2477 |             switch (err) { | 
 | 2478 |                 case -ENODEV: | 
 | 2479 |                     return STATUS_ERROR_FMT(ERROR_DISCONNECTED, | 
 | 2480 |                             "No camera device with ID \"%s\" currently available", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2481 |                             cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2482 |                 case -EBUSY: | 
 | 2483 |                     return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE, | 
 | 2484 |                             "Higher-priority client using camera, ID \"%s\" currently unavailable", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2485 |                             cameraId.c_str()); | 
| Yin-Chia Yeh | 8dfe464 | 2020-06-01 11:57:45 -0700 | [diff] [blame] | 2486 |                 case -EUSERS: | 
 | 2487 |                     return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE, | 
 | 2488 |                             "Too many cameras already open, cannot open camera \"%s\"", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2489 |                             cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2490 |                 default: | 
 | 2491 |                     return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 2492 |                             "Unexpected error %s (%d) opening camera \"%s\"", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2493 |                             strerror(-err), err, cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2494 |             } | 
 | 2495 |         } | 
 | 2496 |  | 
 | 2497 |         if (clientTmp.get() != nullptr) { | 
 | 2498 |             // Handle special case for API1 MediaRecorder where the existing client is returned | 
 | 2499 |             device = static_cast<CLIENT*>(clientTmp.get()); | 
 | 2500 |             return ret; | 
 | 2501 |         } | 
 | 2502 |  | 
 | 2503 |         // give flashlight a chance to close devices if necessary. | 
 | 2504 |         mFlashlight->prepareDeviceOpen(cameraId); | 
 | 2505 |  | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 2506 |         int portraitRotation; | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 2507 |         auto deviceVersionAndTransport = | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2508 |                 getDeviceVersion(cameraId, rotationOverride, /*out*/&portraitRotation, | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 2509 |                         /*out*/&facing, /*out*/&orientation); | 
| Eino-Ville Talvala | 6963d0a | 2017-01-31 13:00:34 -0800 | [diff] [blame] | 2510 |         if (facing == -1) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2511 |             ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | 6963d0a | 2017-01-31 13:00:34 -0800 | [diff] [blame] | 2512 |             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2513 |                     "Unable to get camera device \"%s\" facing", cameraId.c_str()); | 
| Eino-Ville Talvala | 6963d0a | 2017-01-31 13:00:34 -0800 | [diff] [blame] | 2514 |         } | 
 | 2515 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2516 |         sp<BasicClient> tmp = nullptr; | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 2517 |         bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2518 |                 mPerfClassPrimaryCameraIds, cameraId, targetSdkVersion); | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2519 |  | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2520 |         if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2521 |                 clientFeatureId, cameraId, api1CameraId, facing, | 
 | 2522 |                 orientation, clientPid, clientUid, getpid(), | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 2523 |                 deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2524 |                 rotationOverride, forceSlowJpegMode, originalCameraId, | 
| Chengfei Tao | be683db | 2023-01-31 18:52:49 +0000 | [diff] [blame] | 2525 |                 /*out*/&tmp)).isOk()) { | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2526 |             return ret; | 
 | 2527 |         } | 
 | 2528 |         client = static_cast<CLIENT*>(tmp.get()); | 
 | 2529 |  | 
 | 2530 |         LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state", | 
 | 2531 |                 __FUNCTION__); | 
 | 2532 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2533 |         std::string monitorTags = isClientWatched(client.get()) ? mMonitorTags : std::string(); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 2534 |         err = client->initialize(mCameraProviderManager, monitorTags); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 2535 |         if (err != OK) { | 
 | 2536 |             ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2537 |             // Errors could be from the HAL module open call or from AppOpsManager | 
| Kwangkyu Park | b1aaf9a | 2023-07-08 00:42:03 +0900 | [diff] [blame] | 2538 |             mServiceLock.unlock(); | 
 | 2539 |             client->disconnect(); | 
 | 2540 |             mServiceLock.lock(); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2541 |             switch(err) { | 
 | 2542 |                 case BAD_VALUE: | 
 | 2543 |                     return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2544 |                             "Illegal argument to HAL module for camera \"%s\"", cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2545 |                 case -EBUSY: | 
 | 2546 |                     return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2547 |                             "Camera \"%s\" is already open", cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2548 |                 case -EUSERS: | 
 | 2549 |                     return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE, | 
 | 2550 |                             "Too many cameras already open, cannot open camera \"%s\"", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2551 |                             cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2552 |                 case PERMISSION_DENIED: | 
 | 2553 |                     return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2554 |                             "No permission to open camera \"%s\"", cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2555 |                 case -EACCES: | 
 | 2556 |                     return STATUS_ERROR_FMT(ERROR_DISABLED, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2557 |                             "Camera \"%s\" disabled by policy", cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2558 |                 case -ENODEV: | 
 | 2559 |                 default: | 
 | 2560 |                     return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2561 |                             "Failed to initialize camera \"%s\": %s (%d)", cameraId.c_str(), | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2562 |                             strerror(-err), err); | 
 | 2563 |             } | 
 | 2564 |         } | 
 | 2565 |  | 
 | 2566 |         // Update shim paremeters for legacy clients | 
 | 2567 |         if (effectiveApiLevel == API_1) { | 
 | 2568 |             // Assume we have always received a Client subclass for API1 | 
 | 2569 |             sp<Client> shimClient = reinterpret_cast<Client*>(client.get()); | 
 | 2570 |             String8 rawParams = shimClient->getParameters(); | 
 | 2571 |             CameraParameters params(rawParams); | 
 | 2572 |  | 
 | 2573 |             auto cameraState = getCameraState(cameraId); | 
 | 2574 |             if (cameraState != nullptr) { | 
 | 2575 |                 cameraState->setShimParams(params); | 
 | 2576 |             } else { | 
 | 2577 |                 ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2578 |                         __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2579 |             } | 
 | 2580 |         } | 
 | 2581 |  | 
| Ravneet | aeb20dc | 2022-03-30 05:33:03 +0000 | [diff] [blame] | 2582 |         // Enable/disable camera service watchdog | 
 | 2583 |         client->setCameraServiceWatchdog(mCameraServiceWatchdogEnabled); | 
 | 2584 |  | 
| Emilian Peev | 6d45db8 | 2024-01-18 20:11:54 +0000 | [diff] [blame] | 2585 |         CameraMetadata chars; | 
 | 2586 |         bool rotateAndCropSupported = true; | 
 | 2587 |         err = mCameraProviderManager->getCameraCharacteristics(cameraId, overrideForPerfClass, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2588 |                 &chars, rotationOverride); | 
| Emilian Peev | 6d45db8 | 2024-01-18 20:11:54 +0000 | [diff] [blame] | 2589 |         if (err == OK) { | 
 | 2590 |             auto availableRotateCropEntry = chars.find( | 
 | 2591 |                     ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES); | 
 | 2592 |             if (availableRotateCropEntry.count <= 1) { | 
 | 2593 |                 rotateAndCropSupported = false; | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 2594 |             } | 
| Emilian Peev | 13f35ad | 2022-04-27 11:28:48 -0700 | [diff] [blame] | 2595 |         } else { | 
| Emilian Peev | 6d45db8 | 2024-01-18 20:11:54 +0000 | [diff] [blame] | 2596 |             ALOGE("%s: Unable to query static metadata for camera %s: %s (%d)", __FUNCTION__, | 
 | 2597 |                     cameraId.c_str(), strerror(-err), err); | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 2598 |         } | 
 | 2599 |  | 
| Emilian Peev | 6d45db8 | 2024-01-18 20:11:54 +0000 | [diff] [blame] | 2600 |         if (rotateAndCropSupported) { | 
 | 2601 |             // Set rotate-and-crop override behavior | 
 | 2602 |             if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { | 
 | 2603 |                 client->setRotateAndCropOverride(mOverrideRotateAndCropMode); | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2604 |             } else if (rotationOverride != hardware::ICameraService::ROTATION_OVERRIDE_NONE && | 
 | 2605 |                     portraitRotation != 0) { | 
| Emilian Peev | 6d45db8 | 2024-01-18 20:11:54 +0000 | [diff] [blame] | 2606 |                 uint8_t rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_AUTO; | 
 | 2607 |                 switch (portraitRotation) { | 
 | 2608 |                     case 90: | 
 | 2609 |                         rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_90; | 
 | 2610 |                         break; | 
 | 2611 |                     case 180: | 
 | 2612 |                         rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_180; | 
 | 2613 |                         break; | 
 | 2614 |                     case 270: | 
 | 2615 |                         rotateAndCropMode = ANDROID_SCALER_ROTATE_AND_CROP_270; | 
 | 2616 |                         break; | 
 | 2617 |                     default: | 
 | 2618 |                         ALOGE("Unexpected portrait rotation: %d", portraitRotation); | 
 | 2619 |                         break; | 
 | 2620 |                 } | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 2621 |                 // Here we're communicating to the client the chosen rotate | 
 | 2622 |                 // and crop mode to send to the HAL | 
| Emilian Peev | 6d45db8 | 2024-01-18 20:11:54 +0000 | [diff] [blame] | 2623 |                 client->setRotateAndCropOverride(rotateAndCropMode); | 
 | 2624 |             } else { | 
 | 2625 |                 client->setRotateAndCropOverride( | 
 | 2626 |                     mCameraServiceProxyWrapper->getRotateAndCropOverride( | 
 | 2627 |                         clientPackageName, facing, multiuser_get_user_id(clientUid))); | 
 | 2628 |             } | 
 | 2629 |         } | 
 | 2630 |  | 
 | 2631 |         bool autoframingSupported = true; | 
 | 2632 |         auto availableAutoframingEntry = chars.find(ANDROID_CONTROL_AUTOFRAMING_AVAILABLE); | 
 | 2633 |         if ((availableAutoframingEntry.count == 1) && (availableAutoframingEntry.data.u8[0] == | 
 | 2634 |                     ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE)) { | 
 | 2635 |             autoframingSupported = false; | 
 | 2636 |         } | 
 | 2637 |  | 
 | 2638 |         if (autoframingSupported) { | 
 | 2639 |             // Set autoframing override behaviour | 
 | 2640 |             if (mOverrideAutoframingMode != ANDROID_CONTROL_AUTOFRAMING_AUTO) { | 
 | 2641 |                 client->setAutoframingOverride(mOverrideAutoframingMode); | 
 | 2642 |             } else { | 
 | 2643 |                 client->setAutoframingOverride( | 
 | 2644 |                     mCameraServiceProxyWrapper->getAutoframingOverride( | 
 | 2645 |                         clientPackageName)); | 
 | 2646 |             } | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 2647 |         } | 
 | 2648 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2649 |         bool isCameraPrivacyEnabled; | 
 | 2650 |         if (flags::camera_privacy_allowlist()) { | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 2651 |             // Set camera muting behavior. | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2652 |             isCameraPrivacyEnabled = this->isCameraPrivacyEnabled( | 
 | 2653 |                     toString16(client->getPackageName()), cameraId, packagePid, packageUid); | 
 | 2654 |         } else { | 
 | 2655 |             isCameraPrivacyEnabled = | 
| Jyoti Bhayana | feb7392 | 2023-03-16 13:01:38 -0700 | [diff] [blame] | 2656 |                     mSensorPrivacyPolicy->isCameraPrivacyEnabled(); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2657 |         } | 
| Valentin Iftime | c0b8d47 | 2021-07-23 20:21:06 +0200 | [diff] [blame] | 2658 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2659 |         if (client->supportsCameraMute()) { | 
 | 2660 |             client->setCameraMute( | 
 | 2661 |                     mOverrideCameraMuteMode || isCameraPrivacyEnabled); | 
 | 2662 |         } else if (isCameraPrivacyEnabled) { | 
 | 2663 |             // no camera mute supported, but privacy is on! => disconnect | 
 | 2664 |             ALOGI("Camera mute not supported for package: %s, camera id: %s", | 
 | 2665 |                     client->getPackageName().c_str(), cameraId.c_str()); | 
 | 2666 |             // Do not hold mServiceLock while disconnecting clients, but | 
 | 2667 |             // retain the condition blocking other clients from connecting | 
 | 2668 |             // in mServiceLockWrapper if held. | 
 | 2669 |             mServiceLock.unlock(); | 
 | 2670 |             // Clear caller identity temporarily so client disconnect PID | 
 | 2671 |             // checks work correctly | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2672 |             int64_t token = clearCallingIdentity(); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2673 |             // Note AppOp to trigger the "Unblock" dialog | 
 | 2674 |             client->noteAppOp(); | 
 | 2675 |             client->disconnect(); | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2676 |             restoreCallingIdentity(token); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 2677 |             // Reacquire mServiceLock | 
 | 2678 |             mServiceLock.lock(); | 
 | 2679 |  | 
 | 2680 |             return STATUS_ERROR_FMT(ERROR_DISABLED, | 
 | 2681 |                     "Camera \"%s\" disabled due to camera mute", cameraId.c_str()); | 
| Eino-Ville Talvala | 305cec6 | 2020-11-12 14:18:17 -0800 | [diff] [blame] | 2682 |         } | 
 | 2683 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2684 |         if (shimUpdateOnly) { | 
 | 2685 |             // If only updating legacy shim parameters, immediately disconnect client | 
 | 2686 |             mServiceLock.unlock(); | 
 | 2687 |             client->disconnect(); | 
 | 2688 |             mServiceLock.lock(); | 
 | 2689 |         } else { | 
 | 2690 |             // Otherwise, add client to active clients list | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2691 |             finishConnectLocked(client, partial, oomScoreOffset, systemNativeClient); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2692 |         } | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 2693 |  | 
 | 2694 |         client->setImageDumpMask(mImageDumpMask); | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 2695 |         client->setStreamUseCaseOverrides(mStreamUseCaseOverrides); | 
| Shuzhen Wang | af22e91 | 2023-04-11 16:03:17 -0700 | [diff] [blame] | 2696 |         client->setZoomOverride(mZoomOverrideValue); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2697 |     } // lock is destroyed, allow further connect calls | 
 | 2698 |  | 
 | 2699 |     // Important: release the mutex here so the client can call back into the service from its | 
 | 2700 |     // destructor (can be at the end of the call) | 
 | 2701 |     device = client; | 
| Shuzhen Wang | 316781a | 2020-08-18 18:11:01 -0700 | [diff] [blame] | 2702 |  | 
 | 2703 |     int32_t openLatencyMs = ns2ms(systemTime() - openTimeNs); | 
| Austin Borger | 74fca04 | 2022-05-23 12:41:21 -0700 | [diff] [blame] | 2704 |     mCameraServiceProxyWrapper->logOpen(cameraId, facing, clientPackageName, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2705 |             effectiveApiLevel, isNonSystemNdk, openLatencyMs); | 
| Shuzhen Wang | 316781a | 2020-08-18 18:11:01 -0700 | [diff] [blame] | 2706 |  | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 2707 |     { | 
 | 2708 |         Mutex::Autolock lock(mInjectionParametersLock); | 
 | 2709 |         if (cameraId == mInjectionInternalCamId && mInjectionInitPending) { | 
 | 2710 |             mInjectionInitPending = false; | 
 | 2711 |             status_t res = NO_ERROR; | 
 | 2712 |             auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId); | 
 | 2713 |             if (clientDescriptor != nullptr) { | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 2714 |                 sp<BasicClient> clientSp = clientDescriptor->getValue(); | 
 | 2715 |                 res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp); | 
 | 2716 |                 if(res != OK) { | 
 | 2717 |                     return STATUS_ERROR_FMT(ERROR_DISCONNECTED, | 
 | 2718 |                             "No camera device with ID \"%s\" currently available", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2719 |                             mInjectionExternalCamId.c_str()); | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 2720 |                 } | 
 | 2721 |                 res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 2722 |                 if (res != OK) { | 
 | 2723 |                     mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); | 
 | 2724 |                 } | 
 | 2725 |             } else { | 
 | 2726 |                 ALOGE("%s: Internal camera ID = %s 's client does not exist!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2727 |                         __FUNCTION__, mInjectionInternalCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 2728 |                 res = NO_INIT; | 
 | 2729 |                 mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); | 
 | 2730 |             } | 
 | 2731 |         } | 
 | 2732 |     } | 
 | 2733 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2734 |     return ret; | 
 | 2735 | } | 
 | 2736 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2737 | status_t CameraService::addOfflineClient(const std::string &cameraId, | 
 | 2738 |         sp<BasicClient> offlineClient) { | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 2739 |     if (offlineClient.get() == nullptr) { | 
 | 2740 |         return BAD_VALUE; | 
 | 2741 |     } | 
 | 2742 |  | 
 | 2743 |     { | 
 | 2744 |         // Acquire mServiceLock and prevent other clients from connecting | 
 | 2745 |         std::unique_ptr<AutoConditionLock> lock = | 
 | 2746 |                 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS); | 
 | 2747 |  | 
 | 2748 |         if (lock == nullptr) { | 
 | 2749 |             ALOGE("%s: (PID %d) rejected (too many other clients connecting)." | 
 | 2750 |                     , __FUNCTION__, offlineClient->getClientPid()); | 
 | 2751 |             return TIMED_OUT; | 
 | 2752 |         } | 
 | 2753 |  | 
 | 2754 |         auto onlineClientDesc = mActiveClientManager.get(cameraId); | 
 | 2755 |         if (onlineClientDesc.get() == nullptr) { | 
 | 2756 |             ALOGE("%s: No active online client using camera id: %s", __FUNCTION__, | 
 | 2757 |                     cameraId.c_str()); | 
 | 2758 |             return BAD_VALUE; | 
 | 2759 |         } | 
 | 2760 |  | 
 | 2761 |         // Offline clients do not evict or conflict with other online devices. Resource sharing | 
 | 2762 |         // conflicts are handled by the camera provider which will either succeed or fail before | 
 | 2763 |         // reaching this method. | 
 | 2764 |         const auto& onlinePriority = onlineClientDesc->getPriority(); | 
 | 2765 |         auto offlineClientDesc = CameraClientManager::makeClientDescriptor( | 
 | 2766 |                 kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2767 |                 /*conflictingKeys*/ std::set<std::string>(), onlinePriority.getScore(), | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 2768 |                 onlineClientDesc->getOwnerId(), onlinePriority.getState(), | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 2769 |                 // native clients don't have offline processing support. | 
 | 2770 |                 /*ommScoreOffset*/ 0, /*systemNativeClient*/false); | 
| Guillaume Bailey | 417e43d | 2022-11-02 15:30:24 +0100 | [diff] [blame] | 2771 |         if (offlineClientDesc == nullptr) { | 
 | 2772 |             ALOGE("%s: Offline client descriptor was NULL", __FUNCTION__); | 
 | 2773 |             return BAD_VALUE; | 
 | 2774 |         } | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 2775 |  | 
 | 2776 |         // Allow only one offline device per camera | 
 | 2777 |         auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc); | 
 | 2778 |         if (!incompatibleClients.empty()) { | 
 | 2779 |             ALOGE("%s: Incompatible offline clients present!", __FUNCTION__); | 
 | 2780 |             return BAD_VALUE; | 
 | 2781 |         } | 
 | 2782 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2783 |         std::string monitorTags = isClientWatched(offlineClient.get()) | 
 | 2784 |                 ? mMonitorTags : std::string(); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 2785 |         auto err = offlineClient->initialize(mCameraProviderManager, monitorTags); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 2786 |         if (err != OK) { | 
 | 2787 |             ALOGE("%s: Could not initialize offline client.", __FUNCTION__); | 
 | 2788 |             return err; | 
 | 2789 |         } | 
 | 2790 |  | 
 | 2791 |         auto evicted = mActiveClientManager.addAndEvict(offlineClientDesc); | 
 | 2792 |         if (evicted.size() > 0) { | 
 | 2793 |             for (auto& i : evicted) { | 
 | 2794 |                 ALOGE("%s: Invalid state: Offline client for camera %s was not removed ", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2795 |                         __FUNCTION__, i->getKey().c_str()); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 2796 |             } | 
 | 2797 |  | 
 | 2798 |             LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, offline clients not evicted " | 
 | 2799 |                     "properly", __FUNCTION__); | 
 | 2800 |  | 
 | 2801 |             return BAD_VALUE; | 
 | 2802 |         } | 
 | 2803 |  | 
 | 2804 |         logConnectedOffline(offlineClientDesc->getKey(), | 
 | 2805 |                 static_cast<int>(offlineClientDesc->getOwnerId()), | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2806 |                 offlineClient->getPackageName()); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 2807 |  | 
 | 2808 |         sp<IBinder> remoteCallback = offlineClient->getRemote(); | 
 | 2809 |         if (remoteCallback != nullptr) { | 
 | 2810 |             remoteCallback->linkToDeath(this); | 
 | 2811 |         } | 
 | 2812 |     } // lock is destroyed, allow further connect calls | 
 | 2813 |  | 
 | 2814 |     return OK; | 
 | 2815 | } | 
 | 2816 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2817 | Status CameraService::turnOnTorchWithStrengthLevel(const std::string& unresolvedCameraId, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2818 |         int32_t torchStrength, const sp<IBinder>& clientBinder, int32_t deviceId, | 
 | 2819 |         int32_t devicePolicy) { | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2820 |     Mutex::Autolock lock(mServiceLock); | 
 | 2821 |  | 
 | 2822 |     ATRACE_CALL(); | 
 | 2823 |     if (clientBinder == nullptr) { | 
 | 2824 |         ALOGE("%s: torch client binder is NULL", __FUNCTION__); | 
 | 2825 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, | 
 | 2826 |                 "Torch client binder in null."); | 
 | 2827 |     } | 
 | 2828 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2829 |     int uid = getCallingUid(); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2830 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 2831 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2832 |     if (!cameraIdOptional.has_value()) { | 
 | 2833 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 2834 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 2835 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2836 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 2837 |     } | 
 | 2838 |     std::string cameraId = cameraIdOptional.value(); | 
 | 2839 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2840 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2841 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to change the strength level" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2842 |                 "for system only device %s: ", cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2843 |     } | 
 | 2844 |  | 
 | 2845 |     // verify id is valid | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2846 |     auto state = getCameraState(cameraId); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2847 |     if (state == nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2848 |         ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2849 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2850 |             "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2851 |     } | 
 | 2852 |  | 
 | 2853 |     StatusInternal cameraStatus = state->getStatus(); | 
 | 2854 |     if (cameraStatus != StatusInternal::NOT_AVAILABLE && | 
 | 2855 |             cameraStatus != StatusInternal::PRESENT) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2856 |         ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(), | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2857 |             (int)cameraStatus); | 
 | 2858 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2859 |                 "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2860 |     } | 
 | 2861 |  | 
 | 2862 |     { | 
 | 2863 |         Mutex::Autolock al(mTorchStatusMutex); | 
 | 2864 |         TorchModeStatus status; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2865 |         status_t err = getTorchStatusLocked(cameraId, &status); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2866 |         if (err != OK) { | 
 | 2867 |             if (err == NAME_NOT_FOUND) { | 
 | 2868 |              return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2869 |                     "Camera \"%s\" does not have a flash unit", cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2870 |             } | 
 | 2871 |             ALOGE("%s: getting current torch status failed for camera %s", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2872 |                     __FUNCTION__, cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2873 |             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
 | 2874 |                     "Error changing torch strength level for camera \"%s\": %s (%d)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2875 |                     cameraId.c_str(), strerror(-err), err); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2876 |         } | 
 | 2877 |  | 
 | 2878 |         if (status == TorchModeStatus::NOT_AVAILABLE) { | 
 | 2879 |             if (cameraStatus == StatusInternal::NOT_AVAILABLE) { | 
 | 2880 |                 ALOGE("%s: torch mode of camera %s is not available because " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2881 |                         "camera is in use.", __FUNCTION__, cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2882 |                 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE, | 
 | 2883 |                         "Torch for camera \"%s\" is not available due to an existing camera user", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2884 |                         cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2885 |             } else { | 
 | 2886 |                 ALOGE("%s: torch mode of camera %s is not available due to " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2887 |                        "insufficient resources", __FUNCTION__, cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2888 |                 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE, | 
 | 2889 |                         "Torch for camera \"%s\" is not available due to insufficient resources", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2890 |                         cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2891 |             } | 
 | 2892 |         } | 
 | 2893 |     } | 
 | 2894 |  | 
 | 2895 |     { | 
 | 2896 |         Mutex::Autolock al(mTorchUidMapMutex); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2897 |         updateTorchUidMapLocked(cameraId, uid); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2898 |     } | 
 | 2899 |     // Check if the current torch strength level is same as the new one. | 
 | 2900 |     bool shouldSkipTorchStrengthUpdates = mCameraProviderManager->shouldSkipTorchStrengthUpdate( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2901 |             cameraId, torchStrength); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2902 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2903 |     status_t err = mFlashlight->turnOnTorchWithStrengthLevel(cameraId, torchStrength); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2904 |  | 
 | 2905 |     if (err != OK) { | 
 | 2906 |         int32_t errorCode; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2907 |         std::string msg; | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2908 |         switch (err) { | 
 | 2909 |             case -ENOSYS: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2910 |                 msg = fmt::sprintf("Camera \"%s\" has no flashlight.", | 
 | 2911 |                     cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2912 |                 errorCode = ERROR_ILLEGAL_ARGUMENT; | 
 | 2913 |                 break; | 
 | 2914 |             case -EBUSY: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2915 |                 msg = fmt::sprintf("Camera \"%s\" is in use", | 
 | 2916 |                     cameraId.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2917 |                 errorCode = ERROR_CAMERA_IN_USE; | 
 | 2918 |                 break; | 
| Rucha Katakwar | 922fa9c | 2022-02-25 17:46:49 -0800 | [diff] [blame] | 2919 |             case -EINVAL: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2920 |                 msg = fmt::sprintf("Torch strength level %d is not within the " | 
| Rucha Katakwar | 922fa9c | 2022-02-25 17:46:49 -0800 | [diff] [blame] | 2921 |                         "valid range.", torchStrength); | 
 | 2922 |                 errorCode = ERROR_ILLEGAL_ARGUMENT; | 
 | 2923 |                 break; | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2924 |             default: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2925 |                 msg = "Changing torch strength level failed."; | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2926 |                 errorCode = ERROR_INVALID_OPERATION; | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2927 |         } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2928 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2929 |         return STATUS_ERROR(errorCode, msg.c_str()); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2930 |     } | 
 | 2931 |  | 
 | 2932 |     { | 
 | 2933 |         // update the link to client's death | 
 | 2934 |         // Store the last client that turns on each camera's torch mode. | 
 | 2935 |         Mutex::Autolock al(mTorchClientMapMutex); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2936 |         ssize_t index = mTorchClientMap.indexOfKey(cameraId); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2937 |         if (index == NAME_NOT_FOUND) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2938 |             mTorchClientMap.add(cameraId, clientBinder); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2939 |         } else { | 
 | 2940 |             mTorchClientMap.valueAt(index)->unlinkToDeath(this); | 
 | 2941 |             mTorchClientMap.replaceValueAt(index, clientBinder); | 
 | 2942 |         } | 
 | 2943 |         clientBinder->linkToDeath(this); | 
 | 2944 |     } | 
 | 2945 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2946 |     int clientPid = getCallingPid(); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2947 |     ALOGI("%s: Torch strength for camera id %s changed to %d for client PID %d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2948 |             __FUNCTION__, cameraId.c_str(), torchStrength, clientPid); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2949 |     if (!shouldSkipTorchStrengthUpdates) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2950 |         broadcastTorchStrengthLevel(cameraId, torchStrength); | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 2951 |     } | 
 | 2952 |     return Status::ok(); | 
 | 2953 | } | 
 | 2954 |  | 
| malikakash | 73125c6 | 2023-07-21 22:44:34 +0000 | [diff] [blame] | 2955 | Status CameraService::setTorchMode(const std::string& unresolvedCameraId, bool enabled, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2956 |         const sp<IBinder>& clientBinder, int32_t deviceId, int32_t devicePolicy) { | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 2957 |     Mutex::Autolock lock(mServiceLock); | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 2958 |  | 
 | 2959 |     ATRACE_CALL(); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 2960 |     if (enabled && clientBinder == nullptr) { | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 2961 |         ALOGE("%s: torch client binder is NULL", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2962 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, | 
 | 2963 |                 "Torch client Binder is null"); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 2964 |     } | 
 | 2965 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 2966 |     int uid = getCallingUid(); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2967 |     std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 2968 |             devicePolicy); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 2969 |     if (!cameraIdOptional.has_value()) { | 
 | 2970 |         std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 2971 |                 unresolvedCameraId.c_str(), deviceId); | 
 | 2972 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 2973 |         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 2974 |     } | 
 | 2975 |     std::string cameraId = cameraIdOptional.value(); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 2976 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2977 |     if (shouldRejectSystemCameraConnection(cameraId)) { | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 2978 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to set torch mode" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2979 |                 " for system only device %s: ", cameraId.c_str()); | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 2980 |     } | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 2981 |     // verify id is valid. | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2982 |     auto state = getCameraState(cameraId); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2983 |     if (state == nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2984 |         ALOGE("%s: camera id is invalid %s", __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2985 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2986 |                 "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 2987 |     } | 
 | 2988 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 2989 |     StatusInternal cameraStatus = state->getStatus(); | 
 | 2990 |     if (cameraStatus != StatusInternal::PRESENT && | 
| Yin-Chia Yeh | 52778d4 | 2016-12-22 18:20:43 -0800 | [diff] [blame] | 2991 |             cameraStatus != StatusInternal::NOT_AVAILABLE) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2992 |         ALOGE("%s: camera id is invalid %s, status %d", __FUNCTION__, cameraId.c_str(), | 
 | 2993 |                 (int)cameraStatus); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 2994 |         return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 2995 |                 "Camera ID \"%s\" is a not valid camera ID", cameraId.c_str()); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 2996 |     } | 
 | 2997 |  | 
 | 2998 |     { | 
 | 2999 |         Mutex::Autolock al(mTorchStatusMutex); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 3000 |         TorchModeStatus status; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3001 |         status_t err = getTorchStatusLocked(cameraId, &status); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3002 |         if (err != OK) { | 
 | 3003 |             if (err == NAME_NOT_FOUND) { | 
 | 3004 |                 return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3005 |                         "Camera \"%s\" does not have a flash unit", cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3006 |             } | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3007 |             ALOGE("%s: getting current torch status failed for camera %s", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3008 |                     __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3009 |             return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3010 |                     "Error updating torch status for camera \"%s\": %s (%d)", cameraId.c_str(), | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3011 |                     strerror(-err), err); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3012 |         } | 
 | 3013 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 3014 |         if (status == TorchModeStatus::NOT_AVAILABLE) { | 
| Yin-Chia Yeh | 52778d4 | 2016-12-22 18:20:43 -0800 | [diff] [blame] | 3015 |             if (cameraStatus == StatusInternal::NOT_AVAILABLE) { | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3016 |                 ALOGE("%s: torch mode of camera %s is not available because " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3017 |                         "camera is in use", __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3018 |                 return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE, | 
 | 3019 |                         "Torch for camera \"%s\" is not available due to an existing camera user", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3020 |                         cameraId.c_str()); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3021 |             } else { | 
 | 3022 |                 ALOGE("%s: torch mode of camera %s is not available due to " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3023 |                         "insufficient resources", __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3024 |                 return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE, | 
 | 3025 |                         "Torch for camera \"%s\" is not available due to insufficient resources", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3026 |                         cameraId.c_str()); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3027 |             } | 
 | 3028 |         } | 
 | 3029 |     } | 
 | 3030 |  | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 3031 |     { | 
 | 3032 |         // Update UID map - this is used in the torch status changed callbacks, so must be done | 
 | 3033 |         // before setTorchMode | 
| Chien-Yu Chen | fe751be | 2015-09-01 14:16:44 -0700 | [diff] [blame] | 3034 |         Mutex::Autolock al(mTorchUidMapMutex); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3035 |         updateTorchUidMapLocked(cameraId, uid); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 3036 |     } | 
 | 3037 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3038 |     status_t err = mFlashlight->setTorchMode(cameraId, enabled); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 3039 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3040 |     if (err != OK) { | 
 | 3041 |         int32_t errorCode; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3042 |         std::string msg; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3043 |         switch (err) { | 
 | 3044 |             case -ENOSYS: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3045 |                 msg = fmt::sprintf("Camera \"%s\" has no flashlight", | 
 | 3046 |                     cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3047 |                 errorCode = ERROR_ILLEGAL_ARGUMENT; | 
 | 3048 |                 break; | 
| Dijack Dong | c8a6f25 | 2021-09-17 16:21:16 +0800 | [diff] [blame] | 3049 |             case -EBUSY: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3050 |                 msg = fmt::sprintf("Camera \"%s\" is in use", | 
 | 3051 |                     cameraId.c_str()); | 
| Dijack Dong | c8a6f25 | 2021-09-17 16:21:16 +0800 | [diff] [blame] | 3052 |                 errorCode = ERROR_CAMERA_IN_USE; | 
 | 3053 |                 break; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3054 |             default: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3055 |                 msg = fmt::sprintf( | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3056 |                     "Setting torch mode of camera \"%s\" to %d failed: %s (%d)", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3057 |                     cameraId.c_str(), enabled, strerror(-err), err); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3058 |                 errorCode = ERROR_INVALID_OPERATION; | 
 | 3059 |         } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3060 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3061 |         logServiceError(msg, errorCode); | 
 | 3062 |         return STATUS_ERROR(errorCode, msg.c_str()); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3063 |     } | 
 | 3064 |  | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3065 |     { | 
 | 3066 |         // update the link to client's death | 
 | 3067 |         Mutex::Autolock al(mTorchClientMapMutex); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3068 |         ssize_t index = mTorchClientMap.indexOfKey(cameraId); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3069 |         if (enabled) { | 
 | 3070 |             if (index == NAME_NOT_FOUND) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3071 |                 mTorchClientMap.add(cameraId, clientBinder); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3072 |             } else { | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 3073 |                 mTorchClientMap.valueAt(index)->unlinkToDeath(this); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 3074 |                 mTorchClientMap.replaceValueAt(index, clientBinder); | 
 | 3075 |             } | 
 | 3076 |             clientBinder->linkToDeath(this); | 
 | 3077 |         } else if (index != NAME_NOT_FOUND) { | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 3078 |             mTorchClientMap.valueAt(index)->unlinkToDeath(this); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3079 |         } | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3080 |     } | 
 | 3081 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3082 |     int clientPid = getCallingPid(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3083 |     std::string torchState = enabled ? "on" : "off"; | 
 | 3084 |     ALOGI("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(), | 
 | 3085 |             torchState.c_str(), clientPid); | 
 | 3086 |     logTorchEvent(cameraId, torchState, clientPid); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3087 |     return Status::ok(); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3088 | } | 
 | 3089 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3090 | void CameraService::updateTorchUidMapLocked(const std::string& cameraId, int uid) { | 
 | 3091 |     if (mTorchUidMap.find(cameraId) == mTorchUidMap.end()) { | 
 | 3092 |         mTorchUidMap[cameraId].first = uid; | 
 | 3093 |         mTorchUidMap[cameraId].second = uid; | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 3094 |     } else { | 
 | 3095 |         // Set the pending UID | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3096 |         mTorchUidMap[cameraId].first = uid; | 
| Rucha Katakwar | 3828452 | 2021-11-10 11:25:21 -0800 | [diff] [blame] | 3097 |     } | 
 | 3098 | } | 
 | 3099 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3100 | Status CameraService::notifySystemEvent(int32_t eventId, | 
 | 3101 |         const std::vector<int32_t>& args) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3102 |     const int pid = getCallingPid(); | 
| Jeongik Cha | aa5e64c | 2018-11-17 05:08:04 +0900 | [diff] [blame] | 3103 |     const int selfPid = getpid(); | 
 | 3104 |  | 
 | 3105 |     // Permission checks | 
 | 3106 |     if (pid != selfPid) { | 
 | 3107 |         // Ensure we're being called by system_server, or similar process with | 
 | 3108 |         // permissions to notify the camera service about system events | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3109 |         if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3110 |             const int uid = getCallingUid(); | 
| Jeongik Cha | aa5e64c | 2018-11-17 05:08:04 +0900 | [diff] [blame] | 3111 |             ALOGE("Permission Denial: cannot send updates to camera service about system" | 
 | 3112 |                     " events from pid=%d, uid=%d", pid, uid); | 
 | 3113 |             return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
| Jeongik Cha | aa1b815 | 2018-11-21 10:02:25 +0900 | [diff] [blame] | 3114 |                     "No permission to send updates to camera service about system events" | 
 | 3115 |                     " from pid=%d, uid=%d", pid, uid); | 
| Jeongik Cha | aa5e64c | 2018-11-17 05:08:04 +0900 | [diff] [blame] | 3116 |         } | 
 | 3117 |     } | 
 | 3118 |  | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 3119 |     ATRACE_CALL(); | 
 | 3120 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3121 |     switch(eventId) { | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3122 |         case ICameraService::EVENT_USER_SWITCHED: { | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 3123 |             // Try to register for UID and sensor privacy policy updates, in case we're recovering | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 3124 |             // from a system server crash | 
 | 3125 |             mUidPolicy->registerSelf(); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 3126 |             mSensorPrivacyPolicy->registerSelf(); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3127 |             doUserSwitch(/*newUserIds*/ args); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3128 |             break; | 
 | 3129 |         } | 
| Valentin Iftime | 29e2e15 | 2021-08-13 15:17:33 +0200 | [diff] [blame] | 3130 |         case ICameraService::EVENT_USB_DEVICE_ATTACHED: | 
 | 3131 |         case ICameraService::EVENT_USB_DEVICE_DETACHED: { | 
| Pawan Wagh | 99f44e2 | 2023-07-05 21:26:43 +0000 | [diff] [blame] | 3132 |             if (args.size() != 1) { | 
 | 3133 |                 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, | 
 | 3134 |                     "USB Device Event requires 1 argument"); | 
 | 3135 |             } | 
 | 3136 |  | 
| Valentin Iftime | 29e2e15 | 2021-08-13 15:17:33 +0200 | [diff] [blame] | 3137 |             // Notify CameraProviderManager for lazy HALs | 
 | 3138 |             mCameraProviderManager->notifyUsbDeviceEvent(eventId, | 
 | 3139 |                                                         std::to_string(args[0])); | 
 | 3140 |             break; | 
 | 3141 |         } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3142 |         case ICameraService::EVENT_NONE: | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3143 |         default: { | 
 | 3144 |             ALOGW("%s: Received invalid system event from system_server: %d", __FUNCTION__, | 
 | 3145 |                     eventId); | 
 | 3146 |             break; | 
 | 3147 |         } | 
 | 3148 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3149 |     return Status::ok(); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3150 | } | 
 | 3151 |  | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 3152 | void CameraService::notifyMonitoredUids() { | 
 | 3153 |     Mutex::Autolock lock(mStatusListenerLock); | 
 | 3154 |  | 
 | 3155 |     for (const auto& it : mListenerList) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3156 |         auto ret = it->getListener()->onCameraAccessPrioritiesChanged(); | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 3157 |         it->handleBinderStatus(ret, "%s: Failed to trigger permission callback for %d:%d: %d", | 
 | 3158 |                 __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode()); | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 3159 |     } | 
 | 3160 | } | 
 | 3161 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 3162 | void CameraService::notifyMonitoredUids(const std::unordered_set<uid_t> ¬ifyUidSet) { | 
 | 3163 |     Mutex::Autolock lock(mStatusListenerLock); | 
 | 3164 |  | 
 | 3165 |     for (const auto& it : mListenerList) { | 
 | 3166 |         if (notifyUidSet.find(it->getListenerUid()) != notifyUidSet.end()) { | 
 | 3167 |             ALOGV("%s: notifying uid %d", __FUNCTION__, it->getListenerUid()); | 
 | 3168 |             auto ret = it->getListener()->onCameraAccessPrioritiesChanged(); | 
 | 3169 |             it->handleBinderStatus(ret, "%s: Failed to trigger permission callback for %d:%d: %d", | 
 | 3170 |                     __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode()); | 
 | 3171 |         } | 
 | 3172 |     } | 
 | 3173 | } | 
 | 3174 |  | 
| Eino-Ville Talvala | 63f3611 | 2018-12-06 14:57:03 -0800 | [diff] [blame] | 3175 | Status CameraService::notifyDeviceStateChange(int64_t newState) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3176 |     const int pid = getCallingPid(); | 
| Eino-Ville Talvala | 63f3611 | 2018-12-06 14:57:03 -0800 | [diff] [blame] | 3177 |     const int selfPid = getpid(); | 
 | 3178 |  | 
 | 3179 |     // Permission checks | 
 | 3180 |     if (pid != selfPid) { | 
 | 3181 |         // Ensure we're being called by system_server, or similar process with | 
 | 3182 |         // permissions to notify the camera service about system events | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3183 |         if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3184 |             const int uid = getCallingUid(); | 
| Eino-Ville Talvala | 63f3611 | 2018-12-06 14:57:03 -0800 | [diff] [blame] | 3185 |             ALOGE("Permission Denial: cannot send updates to camera service about device" | 
 | 3186 |                     " state changes from pid=%d, uid=%d", pid, uid); | 
 | 3187 |             return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 3188 |                     "No permission to send updates to camera service about device state" | 
 | 3189 |                     " changes from pid=%d, uid=%d", pid, uid); | 
 | 3190 |         } | 
 | 3191 |     } | 
 | 3192 |  | 
 | 3193 |     ATRACE_CALL(); | 
 | 3194 |  | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 3195 |     { | 
 | 3196 |         Mutex::Autolock lock(mServiceLock); | 
 | 3197 |         mDeviceState = newState; | 
 | 3198 |     } | 
 | 3199 |  | 
| Jayant Chowdhary | 0bd3852 | 2021-11-05 17:49:27 -0700 | [diff] [blame] | 3200 |     mCameraProviderManager->notifyDeviceStateChange(newState); | 
| Eino-Ville Talvala | 63f3611 | 2018-12-06 14:57:03 -0800 | [diff] [blame] | 3201 |  | 
 | 3202 |     return Status::ok(); | 
 | 3203 | } | 
 | 3204 |  | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 3205 | Status CameraService::notifyDisplayConfigurationChange() { | 
 | 3206 |     ATRACE_CALL(); | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3207 |     const int callingPid = getCallingPid(); | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 3208 |     const int selfPid = getpid(); | 
 | 3209 |  | 
 | 3210 |     // Permission checks | 
 | 3211 |     if (callingPid != selfPid) { | 
 | 3212 |         // Ensure we're being called by system_server, or similar process with | 
 | 3213 |         // permissions to notify the camera service about system events | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3214 |         if (!checkCallingPermission(toString16(sCameraSendSystemEventsPermission))) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3215 |             const int uid = getCallingUid(); | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 3216 |             ALOGE("Permission Denial: cannot send updates to camera service about orientation" | 
 | 3217 |                     " changes from pid=%d, uid=%d", callingPid, uid); | 
 | 3218 |             return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED, | 
 | 3219 |                     "No permission to send updates to camera service about orientation" | 
 | 3220 |                     " changes from pid=%d, uid=%d", callingPid, uid); | 
 | 3221 |         } | 
 | 3222 |     } | 
 | 3223 |  | 
 | 3224 |     Mutex::Autolock lock(mServiceLock); | 
 | 3225 |  | 
 | 3226 |     // Don't do anything if rotate-and-crop override via cmd is active | 
 | 3227 |     if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return Status::ok(); | 
 | 3228 |  | 
 | 3229 |     const auto clients = mActiveClientManager.getAll(); | 
 | 3230 |     for (auto& current : clients) { | 
 | 3231 |         if (current != nullptr) { | 
 | 3232 |             const auto basicClient = current->getValue(); | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 3233 |             if (basicClient.get() != nullptr && !basicClient->getOverrideToPortrait()) { | 
 | 3234 |                 basicClient->setRotateAndCropOverride( | 
 | 3235 |                         mCameraServiceProxyWrapper->getRotateAndCropOverride( | 
 | 3236 |                                 basicClient->getPackageName(), | 
 | 3237 |                                 basicClient->getCameraFacing(), | 
 | 3238 |                                 multiuser_get_user_id(basicClient->getClientUid()))); | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 3239 |             } | 
 | 3240 |         } | 
 | 3241 |     } | 
 | 3242 |  | 
 | 3243 |     return Status::ok(); | 
 | 3244 | } | 
 | 3245 |  | 
 | 3246 | Status CameraService::getConcurrentCameraIds( | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3247 |         std::vector<ConcurrentCameraIdCombination>* concurrentCameraIds) { | 
 | 3248 |     ATRACE_CALL(); | 
 | 3249 |     if (!concurrentCameraIds) { | 
 | 3250 |         ALOGE("%s: concurrentCameraIds is NULL", __FUNCTION__); | 
 | 3251 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "concurrentCameraIds is NULL"); | 
 | 3252 |     } | 
 | 3253 |  | 
 | 3254 |     if (!mInitialized) { | 
 | 3255 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3256 |         logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED); | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3257 |         return STATUS_ERROR(ERROR_DISCONNECTED, | 
 | 3258 |                 "Camera subsystem is not available"); | 
 | 3259 |     } | 
 | 3260 |     // First call into the provider and get the set of concurrent camera | 
 | 3261 |     // combinations | 
 | 3262 |     std::vector<std::unordered_set<std::string>> concurrentCameraCombinations = | 
| Jayant Chowdhary | cad23c2 | 2020-03-10 15:04:59 -0700 | [diff] [blame] | 3263 |             mCameraProviderManager->getConcurrentCameraIds(); | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3264 |     for (auto &combination : concurrentCameraCombinations) { | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 3265 |         std::vector<std::pair<std::string, int32_t>> validCombination; | 
 | 3266 |         int32_t firstDeviceId = kInvalidDeviceId; | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3267 |         for (auto &cameraId : combination) { | 
 | 3268 |             // if the camera state is not present, skip | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3269 |             auto state = getCameraState(cameraId); | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3270 |             if (state == nullptr) { | 
 | 3271 |                 ALOGW("%s: camera id %s does not exist", __FUNCTION__, cameraId.c_str()); | 
 | 3272 |                 continue; | 
 | 3273 |             } | 
 | 3274 |             StatusInternal status = state->getStatus(); | 
 | 3275 |             if (status == StatusInternal::NOT_PRESENT || status == StatusInternal::ENUMERATING) { | 
 | 3276 |                 continue; | 
 | 3277 |             } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3278 |             if (shouldRejectSystemCameraConnection(cameraId)) { | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3279 |                 continue; | 
 | 3280 |             } | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 3281 |             auto [cameraOwnerDeviceId, mappedCameraId] = | 
 | 3282 |                     mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
 | 3283 |             if (firstDeviceId == kInvalidDeviceId) { | 
 | 3284 |                 firstDeviceId = cameraOwnerDeviceId; | 
 | 3285 |             } else if (firstDeviceId != cameraOwnerDeviceId) { | 
 | 3286 |                 // Found an invalid combination which contains cameras with different device id's, | 
 | 3287 |                 // hence discard it. | 
 | 3288 |                 validCombination.clear(); | 
 | 3289 |                 break; | 
 | 3290 |             } | 
 | 3291 |             validCombination.push_back({mappedCameraId, cameraOwnerDeviceId}); | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3292 |         } | 
 | 3293 |         if (validCombination.size() != 0) { | 
 | 3294 |             concurrentCameraIds->push_back(std::move(validCombination)); | 
 | 3295 |         } | 
 | 3296 |     } | 
 | 3297 |     return Status::ok(); | 
 | 3298 | } | 
 | 3299 |  | 
 | 3300 | Status CameraService::isConcurrentSessionConfigurationSupported( | 
 | 3301 |         const std::vector<CameraIdAndSessionConfiguration>& cameraIdsAndSessionConfigurations, | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 3302 |         int targetSdkVersion, int32_t deviceId, int32_t devicePolicy, | 
 | 3303 |         /*out*/bool* isSupported) { | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3304 |     if (!isSupported) { | 
 | 3305 |         ALOGE("%s: isSupported is NULL", __FUNCTION__); | 
 | 3306 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "isSupported is NULL"); | 
 | 3307 |     } | 
 | 3308 |  | 
 | 3309 |     if (!mInitialized) { | 
 | 3310 |         ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__); | 
 | 3311 |         return STATUS_ERROR(ERROR_DISCONNECTED, | 
 | 3312 |                 "Camera subsystem is not available"); | 
 | 3313 |     } | 
 | 3314 |  | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 3315 |     for (auto cameraIdAndSessionConfiguration : cameraIdsAndSessionConfigurations) { | 
 | 3316 |         std::optional<std::string> cameraIdOptional = | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 3317 |                 resolveCameraId(cameraIdAndSessionConfiguration.mCameraId, deviceId, devicePolicy); | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 3318 |         if (!cameraIdOptional.has_value()) { | 
 | 3319 |             std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d", | 
 | 3320 |                     cameraIdAndSessionConfiguration.mCameraId.c_str(), deviceId); | 
 | 3321 |             ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3322 |             return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
 | 3323 |         } | 
 | 3324 |         cameraIdAndSessionConfiguration.mCameraId = cameraIdOptional.value(); | 
 | 3325 |     } | 
 | 3326 |  | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3327 |     // Check for camera permissions | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3328 |     int callingPid = getCallingPid(); | 
 | 3329 |     int callingUid = getCallingUid(); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 3330 |     bool hasCameraPermission = ((callingPid == getpid()) || | 
| Biswarup Pal | 7d07286 | 2024-04-17 15:24:47 +0000 | [diff] [blame] | 3331 |             hasPermissionsForCamera(callingPid, callingUid, | 
 | 3332 |                     devicePolicy == IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT | 
 | 3333 |                         ? kDefaultDeviceId : deviceId)); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 3334 |     if (!hasCameraPermission) { | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3335 |         return STATUS_ERROR(ERROR_PERMISSION_DENIED, | 
 | 3336 |                 "android.permission.CAMERA needed to call" | 
 | 3337 |                 "isConcurrentSessionConfigurationSupported"); | 
 | 3338 |     } | 
 | 3339 |  | 
 | 3340 |     status_t res = | 
 | 3341 |             mCameraProviderManager->isConcurrentSessionConfigurationSupported( | 
| Shuzhen Wang | d4abdf7 | 2021-05-28 11:22:50 -0700 | [diff] [blame] | 3342 |                     cameraIdsAndSessionConfigurations, mPerfClassPrimaryCameraIds, | 
 | 3343 |                     targetSdkVersion, isSupported); | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3344 |     if (res != OK) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3345 |         logServiceError("Unable to query session configuration support", | 
| Rucha Katakwar | d9ea645 | 2021-05-06 11:57:16 -0700 | [diff] [blame] | 3346 |             ERROR_INVALID_OPERATION); | 
| Jayant Chowdhary | 2bbdce4 | 2020-01-12 14:55:41 -0800 | [diff] [blame] | 3347 |         return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query session configuration " | 
 | 3348 |                 "support %s (%d)", strerror(-res), res); | 
 | 3349 |     } | 
 | 3350 |     return Status::ok(); | 
 | 3351 | } | 
 | 3352 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 3353 | Status CameraService::addListener(const sp<ICameraServiceListener>& listener, | 
 | 3354 |         /*out*/ | 
 | 3355 |         std::vector<hardware::CameraStatus> *cameraStatuses) { | 
| Jayant Chowdhary | f949ddd | 2019-01-29 14:34:11 -0800 | [diff] [blame] | 3356 |     return addListenerHelper(listener, cameraStatuses); | 
 | 3357 | } | 
 | 3358 |  | 
| Jayant Chowdhary | 32ced0e | 2021-04-09 14:00:22 -0700 | [diff] [blame] | 3359 | binder::Status CameraService::addListenerTest(const sp<hardware::ICameraServiceListener>& listener, | 
 | 3360 |             std::vector<hardware::CameraStatus>* cameraStatuses) { | 
 | 3361 |     return addListenerHelper(listener, cameraStatuses, false, true); | 
 | 3362 | } | 
 | 3363 |  | 
| Jayant Chowdhary | f949ddd | 2019-01-29 14:34:11 -0800 | [diff] [blame] | 3364 | Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listener, | 
 | 3365 |         /*out*/ | 
 | 3366 |         std::vector<hardware::CameraStatus> *cameraStatuses, | 
| Jayant Chowdhary | 32ced0e | 2021-04-09 14:00:22 -0700 | [diff] [blame] | 3367 |         bool isVendorListener, bool isProcessLocalTest) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 3368 |     ATRACE_CALL(); | 
 | 3369 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3370 |     ALOGV("%s: Add listener %p", __FUNCTION__, listener.get()); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3371 |  | 
| Ruben Brunk | 3450ba7 | 2015-06-16 11:00:37 -0700 | [diff] [blame] | 3372 |     if (listener == nullptr) { | 
| Igor Murashkin | bd3e2e0 | 2014-03-17 13:01:41 -0700 | [diff] [blame] | 3373 |         ALOGE("%s: Listener must not be null", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3374 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener"); | 
| Igor Murashkin | bd3e2e0 | 2014-03-17 13:01:41 -0700 | [diff] [blame] | 3375 |     } | 
 | 3376 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3377 |     auto clientPid = getCallingPid(); | 
 | 3378 |     auto clientUid = getCallingUid(); | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 3379 |     bool openCloseCallbackAllowed = hasPermissionsForOpenCloseListener(clientPid, clientUid); | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3380 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3381 |     Mutex::Autolock lock(mServiceLock); | 
 | 3382 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3383 |     { | 
 | 3384 |         Mutex::Autolock lock(mStatusListenerLock); | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 3385 |         for (const auto &it : mListenerList) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3386 |             if (IInterface::asBinder(it->getListener()) == IInterface::asBinder(listener)) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3387 |                 ALOGW("%s: Tried to add listener %p which was already subscribed", | 
 | 3388 |                       __FUNCTION__, listener.get()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3389 |                 return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered"); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3390 |             } | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3391 |         } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3392 |  | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3393 |         sp<ServiceListener> serviceListener = | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 3394 |                 new ServiceListener(this, listener, clientUid, clientPid, isVendorListener, | 
 | 3395 |                         openCloseCallbackAllowed); | 
| Jayant Chowdhary | 32ced0e | 2021-04-09 14:00:22 -0700 | [diff] [blame] | 3396 |         auto ret = serviceListener->initialize(isProcessLocalTest); | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 3397 |         if (ret != NO_ERROR) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3398 |             std::string msg = fmt::sprintf("Failed to initialize service listener: %s (%d)", | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 3399 |                     strerror(-ret), ret); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3400 |             logServiceError(msg, ERROR_ILLEGAL_ARGUMENT); | 
 | 3401 |             ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3402 |             return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 3403 |         } | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3404 |         // The listener still needs to be added to the list of listeners, regardless of what | 
 | 3405 |         // permissions the listener process has / whether it is a vendor listener. Since it might be | 
 | 3406 |         // eligible to listen to other camera ids. | 
 | 3407 |         mListenerList.emplace_back(serviceListener); | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 3408 |         mUidPolicy->registerMonitorUid(clientUid, /*openCamera*/false); | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3409 |     } | 
 | 3410 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 3411 |     /* Collect current devices and status */ | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 3412 |     { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3413 |         Mutex::Autolock lock(mCameraStatesLock); | 
 | 3414 |         for (auto& i : mCameraStates) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3415 |             // Get the device id and app-visible camera id for the given HAL-visible camera id. | 
 | 3416 |             auto [deviceId, mappedCameraId] = | 
 | 3417 |                     mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(i.first); | 
 | 3418 |  | 
 | 3419 |             cameraStatuses->emplace_back(mappedCameraId, | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 3420 |                     mapToInterface(i.second->getStatus()), i.second->getUnavailablePhysicalIds(), | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3421 |                     openCloseCallbackAllowed ? i.second->getClientPackage() : std::string(), | 
 | 3422 |                     deviceId); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 3423 |         } | 
 | 3424 |     } | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 3425 |     // Remove the camera statuses that should be hidden from the client, we do | 
 | 3426 |     // this after collecting the states in order to avoid holding | 
 | 3427 |     // mCameraStatesLock and mInterfaceLock (held in getSystemCameraKind()) at | 
 | 3428 |     // the same time. | 
 | 3429 |     cameraStatuses->erase(std::remove_if(cameraStatuses->begin(), cameraStatuses->end(), | 
 | 3430 |                 [this, &isVendorListener, &clientPid, &clientUid](const hardware::CameraStatus& s) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3431 |                         std::string cameraId = s.cameraId; | 
 | 3432 |                         std::optional<std::string> cameraIdOptional = resolveCameraId(s.cameraId, | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 3433 |                                 s.deviceId, IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3434 |                         if (!cameraIdOptional.has_value()) { | 
 | 3435 |                             std::string msg = | 
 | 3436 |                                     fmt::sprintf( | 
 | 3437 |                                             "Camera %s: Invalid camera id for device id %d", | 
 | 3438 |                                             s.cameraId.c_str(), s.deviceId); | 
 | 3439 |                             ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3440 |                             return true; | 
 | 3441 |                         } | 
 | 3442 |                         cameraId = cameraIdOptional.value(); | 
 | 3443 |                         SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
 | 3444 |                         if (getSystemCameraKind(cameraId, &deviceKind) != OK) { | 
 | 3445 |                             ALOGE("%s: Invalid camera id %s, skipping status update", | 
 | 3446 |                                     __FUNCTION__, s.cameraId.c_str()); | 
 | 3447 |                             return true; | 
 | 3448 |                         } | 
 | 3449 |                         return shouldSkipStatusUpdates(deviceKind, isVendorListener, clientPid, | 
 | 3450 |                                 clientUid); | 
 | 3451 |                      }), cameraStatuses->end()); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 3452 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3453 |     // cameraStatuses will have non-eligible camera ids removed. | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3454 |     std::set<std::string> idsChosenForCallback; | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 3455 |     for (const auto &s : *cameraStatuses) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3456 |         // Add only default device cameras here, as virtual cameras currently don't support torch | 
 | 3457 |         // anyway. Note that this is a simplification of the implementation here, and we should | 
 | 3458 |         // change this when virtual cameras support torch. | 
 | 3459 |         if (s.deviceId == kDefaultDeviceId) { | 
 | 3460 |             idsChosenForCallback.insert(s.cameraId); | 
 | 3461 |         } | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 3462 |     } | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 3463 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 3464 |     /* | 
 | 3465 |      * Immediately signal current torch status to this listener only | 
 | 3466 |      * This may be a subset of all the devices, so don't include it in the response directly | 
 | 3467 |      */ | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3468 |     { | 
 | 3469 |         Mutex::Autolock al(mTorchStatusMutex); | 
 | 3470 |         for (size_t i = 0; i < mTorchStatusMap.size(); i++ ) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3471 |             const std::string &id = mTorchStatusMap.keyAt(i); | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 3472 |             // The camera id is visible to the client. Fine to send torch | 
 | 3473 |             // callback. | 
 | 3474 |             if (idsChosenForCallback.find(id) != idsChosenForCallback.end()) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3475 |                 listener->onTorchStatusChanged(mapToInterface(mTorchStatusMap.valueAt(i)), id, | 
 | 3476 |                         kDefaultDeviceId); | 
| Jayant Chowdhary | 8c62d89 | 2021-03-31 02:13:46 -0700 | [diff] [blame] | 3477 |             } | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3478 |         } | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 3479 |     } | 
 | 3480 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3481 |     return Status::ok(); | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3482 | } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3483 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3484 | Status CameraService::removeListener(const sp<ICameraServiceListener>& listener) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 3485 |     ATRACE_CALL(); | 
 | 3486 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3487 |     ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get()); | 
 | 3488 |  | 
| Igor Murashkin | bd3e2e0 | 2014-03-17 13:01:41 -0700 | [diff] [blame] | 3489 |     if (listener == 0) { | 
 | 3490 |         ALOGE("%s: Listener must not be null", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3491 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to removeListener"); | 
| Igor Murashkin | bd3e2e0 | 2014-03-17 13:01:41 -0700 | [diff] [blame] | 3492 |     } | 
 | 3493 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3494 |     Mutex::Autolock lock(mServiceLock); | 
 | 3495 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3496 |     { | 
 | 3497 |         Mutex::Autolock lock(mStatusListenerLock); | 
 | 3498 |         for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) { | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3499 |             if (IInterface::asBinder((*it)->getListener()) == IInterface::asBinder(listener)) { | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 3500 |                 mUidPolicy->unregisterMonitorUid((*it)->getListenerUid(), /*closeCamera*/false); | 
| Jayant Chowdhary | 5216b21 | 2019-07-17 09:26:23 -0700 | [diff] [blame] | 3501 |                 IInterface::asBinder(listener)->unlinkToDeath(*it); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3502 |                 mListenerList.erase(it); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3503 |                 return Status::ok(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3504 |             } | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 3505 |         } | 
 | 3506 |     } | 
 | 3507 |  | 
 | 3508 |     ALOGW("%s: Tried to remove a listener %p which was not subscribed", | 
 | 3509 |           __FUNCTION__, listener.get()); | 
 | 3510 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3511 |     return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Unregistered listener given to removeListener"); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3512 | } | 
 | 3513 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3514 | Status CameraService::getLegacyParameters(int cameraId, /*out*/std::string* parameters) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 3515 |  | 
 | 3516 |     ATRACE_CALL(); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3517 |     ALOGV("%s: for camera ID = %d", __FUNCTION__, cameraId); | 
 | 3518 |  | 
 | 3519 |     if (parameters == NULL) { | 
 | 3520 |         ALOGE("%s: parameters must not be null", __FUNCTION__); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3521 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Parameters must not be null"); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3522 |     } | 
 | 3523 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3524 |     Status ret = Status::ok(); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3525 |  | 
 | 3526 |     CameraParameters shimParams; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3527 |     if (!(ret = getLegacyParametersLazy(cameraId, /*out*/&shimParams)).isOk()) { | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3528 |         // Error logged by caller | 
 | 3529 |         return ret; | 
 | 3530 |     } | 
 | 3531 |  | 
 | 3532 |     String8 shimParamsString8 = shimParams.flatten(); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3533 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3534 |     *parameters = toStdString(shimParamsString8); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3535 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3536 |     return ret; | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3537 | } | 
 | 3538 |  | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 3539 | Status CameraService::supportsCameraApi(const std::string& cameraId, int apiVersion, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 3540 |         /*out*/ bool *isSupported) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 3541 |     ATRACE_CALL(); | 
 | 3542 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3543 |     ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str()); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3544 |  | 
 | 3545 |     switch (apiVersion) { | 
 | 3546 |         case API_VERSION_1: | 
 | 3547 |         case API_VERSION_2: | 
 | 3548 |             break; | 
 | 3549 |         default: | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3550 |             std::string msg = fmt::sprintf("Unknown API version %d", apiVersion); | 
 | 3551 |             ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3552 |             return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3553 |     } | 
 | 3554 |  | 
| Austin Borger | 18b30a7 | 2022-10-27 12:20:29 -0700 | [diff] [blame] | 3555 |     int portraitRotation; | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 3556 |     auto deviceVersionAndTransport = | 
 | 3557 |             getDeviceVersion(cameraId, | 
 | 3558 |                     /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE, | 
 | 3559 |                     &portraitRotation); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 3560 |     if (deviceVersionAndTransport.first == -1) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3561 |         std::string msg = fmt::sprintf("Unknown camera ID %s", cameraId.c_str()); | 
 | 3562 |         ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3563 |         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str()); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 3564 |     } | 
 | 3565 |     if (deviceVersionAndTransport.second == IPCTransport::HIDL) { | 
 | 3566 |         int deviceVersion = deviceVersionAndTransport.first; | 
 | 3567 |         switch (deviceVersion) { | 
 | 3568 |             case CAMERA_DEVICE_API_VERSION_1_0: | 
 | 3569 |             case CAMERA_DEVICE_API_VERSION_3_0: | 
 | 3570 |             case CAMERA_DEVICE_API_VERSION_3_1: | 
 | 3571 |                 if (apiVersion == API_VERSION_2) { | 
 | 3572 |                     ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3573 |                             "shim", __FUNCTION__, cameraId.c_str(), deviceVersion); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 3574 |                     *isSupported = false; | 
 | 3575 |                 } else { // if (apiVersion == API_VERSION_1) { | 
 | 3576 |                     ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3577 |                             "supported", __FUNCTION__, cameraId.c_str()); | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 3578 |                     *isSupported = true; | 
 | 3579 |                 } | 
 | 3580 |                 break; | 
 | 3581 |             case CAMERA_DEVICE_API_VERSION_3_2: | 
 | 3582 |             case CAMERA_DEVICE_API_VERSION_3_3: | 
 | 3583 |             case CAMERA_DEVICE_API_VERSION_3_4: | 
 | 3584 |             case CAMERA_DEVICE_API_VERSION_3_5: | 
 | 3585 |             case CAMERA_DEVICE_API_VERSION_3_6: | 
 | 3586 |             case CAMERA_DEVICE_API_VERSION_3_7: | 
 | 3587 |                 ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3588 |                         __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3589 |                 *isSupported = true; | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 3590 |                 break; | 
 | 3591 |             default: { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3592 |                 std::string msg = fmt::sprintf("Unknown device version %x for device %s", | 
 | 3593 |                         deviceVersion, cameraId.c_str()); | 
 | 3594 |                 ALOGE("%s: %s", __FUNCTION__, msg.c_str()); | 
 | 3595 |                 return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.c_str()); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3596 |             } | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3597 |         } | 
| Jayant Chowdhary | ffc5d68 | 2022-05-12 18:34:34 +0000 | [diff] [blame] | 3598 |     } else { | 
 | 3599 |         *isSupported = true; | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3600 |     } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3601 |     return Status::ok(); | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 3602 | } | 
 | 3603 |  | 
| malikakash | 98260df | 2024-05-10 23:33:57 +0000 | [diff] [blame] | 3604 | Status CameraService::isHiddenPhysicalCamera(const std::string& cameraId, | 
| Shuzhen Wang | f9d2c02 | 2018-08-21 12:07:35 -0700 | [diff] [blame] | 3605 |         /*out*/ bool *isSupported) { | 
 | 3606 |     ATRACE_CALL(); | 
 | 3607 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3608 |     ALOGV("%s: for camera ID = %s", __FUNCTION__, cameraId.c_str()); | 
 | 3609 |     *isSupported = mCameraProviderManager->isHiddenPhysicalCamera(cameraId); | 
| Shuzhen Wang | f9d2c02 | 2018-08-21 12:07:35 -0700 | [diff] [blame] | 3610 |  | 
 | 3611 |     return Status::ok(); | 
 | 3612 | } | 
 | 3613 |  | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3614 | Status CameraService::injectCamera( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3615 |         const std::string& packageName, const std::string& internalCamId, | 
 | 3616 |         const std::string& externalCamId, | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3617 |         const sp<ICameraInjectionCallback>& callback, | 
 | 3618 |         /*out*/ | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 3619 |         sp<ICameraInjectionSession>* cameraInjectionSession) { | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3620 |     ATRACE_CALL(); | 
 | 3621 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3622 |     if (!checkCallingPermission(toString16(sCameraInjectExternalCameraPermission))) { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3623 |         const int pid = getCallingPid(); | 
 | 3624 |         const int uid = getCallingUid(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3625 |         ALOGE("Permission Denial: can't inject camera pid=%d, uid=%d", pid, uid); | 
 | 3626 |         return STATUS_ERROR(ERROR_PERMISSION_DENIED, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3627 |                 "Permission Denial: no permission to inject camera"); | 
 | 3628 |     } | 
 | 3629 |  | 
 | 3630 |     // Do not allow any camera injection that injects or replaces a virtual camera. | 
 | 3631 |     auto [deviceIdForInternalCamera, _] = | 
 | 3632 |             mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(internalCamId); | 
 | 3633 |     if (deviceIdForInternalCamera != kDefaultDeviceId) { | 
 | 3634 |         return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED, | 
 | 3635 |                 "Cannot replace a virtual camera"); | 
 | 3636 |     } | 
 | 3637 |     [[maybe_unused]] auto [deviceIdForExternalCamera, unusedMappedCameraId] = | 
 | 3638 |             mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(externalCamId); | 
 | 3639 |     if (deviceIdForExternalCamera != kDefaultDeviceId) { | 
 | 3640 |         return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED, | 
 | 3641 |                 "Cannot inject a virtual camera to replace an internal camera"); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3642 |     } | 
 | 3643 |  | 
 | 3644 |     ALOGV( | 
 | 3645 |         "%s: Package name = %s, Internal camera ID = %s, External camera ID = " | 
 | 3646 |         "%s", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3647 |         __FUNCTION__, packageName.c_str(), | 
 | 3648 |         internalCamId.c_str(), externalCamId.c_str()); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3649 |  | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 3650 |     { | 
 | 3651 |         Mutex::Autolock lock(mInjectionParametersLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3652 |         mInjectionInternalCamId = internalCamId; | 
 | 3653 |         mInjectionExternalCamId = externalCamId; | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 3654 |         mInjectionStatusListener->addListener(callback); | 
 | 3655 |         *cameraInjectionSession = new CameraInjectionSession(this); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 3656 |         status_t res = NO_ERROR; | 
 | 3657 |         auto clientDescriptor = mActiveClientManager.get(mInjectionInternalCamId); | 
 | 3658 |         // If the client already exists, we can directly connect to the camera device through the | 
 | 3659 |         // client's injectCamera(), otherwise we need to wait until the client is established | 
 | 3660 |         // (execute connectHelper()) before injecting the camera to the camera device. | 
 | 3661 |         if (clientDescriptor != nullptr) { | 
 | 3662 |             mInjectionInitPending = false; | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 3663 |             sp<BasicClient> clientSp = clientDescriptor->getValue(); | 
 | 3664 |             res = checkIfInjectionCameraIsPresent(mInjectionExternalCamId, clientSp); | 
 | 3665 |             if(res != OK) { | 
 | 3666 |                 return STATUS_ERROR_FMT(ERROR_DISCONNECTED, | 
 | 3667 |                         "No camera device with ID \"%s\" currently available", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3668 |                         mInjectionExternalCamId.c_str()); | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 3669 |             } | 
 | 3670 |             res = clientSp->injectCamera(mInjectionExternalCamId, mCameraProviderManager); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 3671 |             if (res != OK) { | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 3672 |                 mInjectionStatusListener->notifyInjectionError(mInjectionExternalCamId, res); | 
 | 3673 |             } | 
 | 3674 |         } else { | 
 | 3675 |             mInjectionInitPending = true; | 
 | 3676 |         } | 
 | 3677 |     } | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3678 |  | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 3679 |     return binder::Status::ok(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 3680 | } | 
 | 3681 |  | 
| Avichal Rakesh | 6e57a2b | 2023-05-01 17:53:37 -0700 | [diff] [blame] | 3682 | Status CameraService::reportExtensionSessionStats( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3683 |         const hardware::CameraExtensionSessionStats& stats, std::string* sessionKey /*out*/) { | 
| Avichal Rakesh | 6e57a2b | 2023-05-01 17:53:37 -0700 | [diff] [blame] | 3684 |     ALOGV("%s: reported %s", __FUNCTION__, stats.toString().c_str()); | 
 | 3685 |     *sessionKey = mCameraServiceProxyWrapper->updateExtensionStats(stats); | 
 | 3686 |     return Status::ok(); | 
 | 3687 | } | 
 | 3688 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3689 | void CameraService::removeByClient(const BasicClient* client) { | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 3690 |     Mutex::Autolock lock(mServiceLock); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3691 |     for (auto& i : mActiveClientManager.getAll()) { | 
 | 3692 |         auto clientSp = i->getValue(); | 
 | 3693 |         if (clientSp.get() == client) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 3694 |             cacheClientTagDumpIfNeeded(client->mCameraIdStr, clientSp.get()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3695 |             mActiveClientManager.remove(i); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3696 |         } | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 3697 |     } | 
| Yin-Chia Yeh | dba0323 | 2019-08-19 15:54:28 -0700 | [diff] [blame] | 3698 |     updateAudioRestrictionLocked(); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3699 | } | 
 | 3700 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3701 | bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3702 |     bool ret = false; | 
 | 3703 |     { | 
 | 3704 |         // Acquire mServiceLock and prevent other clients from connecting | 
 | 3705 |         std::unique_ptr<AutoConditionLock> lock = | 
 | 3706 |                 AutoConditionLock::waitAndAcquire(mServiceLockWrapper); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3707 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3708 |         std::vector<sp<BasicClient>> evicted; | 
 | 3709 |         for (auto& i : mActiveClientManager.getAll()) { | 
 | 3710 |             auto clientSp = i->getValue(); | 
 | 3711 |             if (clientSp.get() == nullptr) { | 
 | 3712 |                 ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__); | 
 | 3713 |                 mActiveClientManager.remove(i); | 
 | 3714 |                 continue; | 
 | 3715 |             } | 
| Yin-Chia Yeh | dbfcb38 | 2018-02-16 11:17:36 -0800 | [diff] [blame] | 3716 |             if (remote == clientSp->getRemote()) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3717 |                 mActiveClientManager.remove(i); | 
 | 3718 |                 evicted.push_back(clientSp); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3719 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3720 |                 // Notify the client of disconnection | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3721 |                 clientSp->notifyError( | 
 | 3722 |                         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3723 |                         CaptureResultExtras()); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3724 |             } | 
 | 3725 |         } | 
 | 3726 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3727 |         // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking | 
 | 3728 |         // other clients from connecting in mServiceLockWrapper if held | 
 | 3729 |         mServiceLock.unlock(); | 
 | 3730 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3731 |         // Do not clear caller identity, remote caller should be client proccess | 
 | 3732 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3733 |         for (auto& i : evicted) { | 
 | 3734 |             if (i.get() != nullptr) { | 
 | 3735 |                 i->disconnect(); | 
 | 3736 |                 ret = true; | 
 | 3737 |             } | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3738 |         } | 
 | 3739 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3740 |         // Reacquire mServiceLock | 
 | 3741 |         mServiceLock.lock(); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 3742 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3743 |     } // lock is destroyed, allow further connect calls | 
 | 3744 |  | 
 | 3745 |     return ret; | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 3746 | } | 
 | 3747 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3748 | std::shared_ptr<CameraService::CameraState> CameraService::getCameraState( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3749 |         const std::string& cameraId) const { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3750 |     std::shared_ptr<CameraState> state; | 
 | 3751 |     { | 
 | 3752 |         Mutex::Autolock lock(mCameraStatesLock); | 
 | 3753 |         auto iter = mCameraStates.find(cameraId); | 
 | 3754 |         if (iter != mCameraStates.end()) { | 
 | 3755 |             state = iter->second; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3756 |         } | 
 | 3757 |     } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3758 |     return state; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3759 | } | 
 | 3760 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3761 | sp<CameraService::BasicClient> CameraService::removeClientLocked(const std::string& cameraId) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3762 |     // Remove from active clients list | 
 | 3763 |     auto clientDescriptorPtr = mActiveClientManager.remove(cameraId); | 
 | 3764 |     if (clientDescriptorPtr == nullptr) { | 
 | 3765 |         ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3766 |                 cameraId.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3767 |         return sp<BasicClient>{nullptr}; | 
 | 3768 |     } | 
 | 3769 |  | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 3770 |     sp<BasicClient> client = clientDescriptorPtr->getValue(); | 
 | 3771 |     if (client.get() != nullptr) { | 
 | 3772 |         cacheClientTagDumpIfNeeded(clientDescriptorPtr->getKey(), client.get()); | 
 | 3773 |     } | 
 | 3774 |     return client; | 
| Keun young Park | d8973a7 | 2012-03-28 14:13:09 -0700 | [diff] [blame] | 3775 | } | 
 | 3776 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3777 | void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) { | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3778 |     // Acquire mServiceLock and prevent other clients from connecting | 
 | 3779 |     std::unique_ptr<AutoConditionLock> lock = | 
 | 3780 |             AutoConditionLock::waitAndAcquire(mServiceLockWrapper); | 
 | 3781 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 3782 |     std::set<userid_t> newAllowedUsers; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3783 |     for (size_t i = 0; i < newUserIds.size(); i++) { | 
 | 3784 |         if (newUserIds[i] < 0) { | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 3785 |             ALOGE("%s: Bad user ID %d given during user switch, ignoring.", | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3786 |                     __FUNCTION__, newUserIds[i]); | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 3787 |             return; | 
 | 3788 |         } | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 3789 |         newAllowedUsers.insert(static_cast<userid_t>(newUserIds[i])); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3790 |     } | 
 | 3791 |  | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3792 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 3793 |     if (newAllowedUsers == mAllowedUsers) { | 
 | 3794 |         ALOGW("%s: Received notification of user switch with no updated user IDs.", __FUNCTION__); | 
 | 3795 |         return; | 
 | 3796 |     } | 
 | 3797 |  | 
 | 3798 |     logUserSwitch(mAllowedUsers, newAllowedUsers); | 
 | 3799 |  | 
 | 3800 |     mAllowedUsers = std::move(newAllowedUsers); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3801 |  | 
 | 3802 |     // Current user has switched, evict all current clients. | 
 | 3803 |     std::vector<sp<BasicClient>> evicted; | 
 | 3804 |     for (auto& i : mActiveClientManager.getAll()) { | 
 | 3805 |         auto clientSp = i->getValue(); | 
 | 3806 |  | 
 | 3807 |         if (clientSp.get() == nullptr) { | 
 | 3808 |             ALOGE("%s: Dead client still in mActiveClientManager.", __FUNCTION__); | 
 | 3809 |             continue; | 
 | 3810 |         } | 
 | 3811 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 3812 |         // Don't evict clients that are still allowed. | 
 | 3813 |         uid_t clientUid = clientSp->getClientUid(); | 
 | 3814 |         userid_t clientUserId = multiuser_get_user_id(clientUid); | 
 | 3815 |         if (mAllowedUsers.find(clientUserId) != mAllowedUsers.end()) { | 
 | 3816 |             continue; | 
 | 3817 |         } | 
 | 3818 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3819 |         evicted.push_back(clientSp); | 
 | 3820 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3821 |         ALOGE("Evicting conflicting client for camera ID %s due to user change", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3822 |                 i->getKey().c_str()); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3823 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3824 |         // Log the clients evicted | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3825 |         logEvent(fmt::sprintf("EVICT device %s client held by package %s (PID %" | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 3826 |                 PRId32 ", score %" PRId32 ", state %" PRId32 ")\n   - Evicted due" | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3827 |                 " to user switch.", i->getKey().c_str(), | 
 | 3828 |                 clientSp->getPackageName().c_str(), | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 3829 |                 i->getOwnerId(), i->getPriority().getScore(), | 
 | 3830 |                 i->getPriority().getState())); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3831 |  | 
 | 3832 |     } | 
 | 3833 |  | 
 | 3834 |     // Do not hold mServiceLock while disconnecting clients, but retain the condition | 
 | 3835 |     // blocking other clients from connecting in mServiceLockWrapper if held. | 
 | 3836 |     mServiceLock.unlock(); | 
 | 3837 |  | 
 | 3838 |     // Clear caller identity temporarily so client disconnect PID checks work correctly | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3839 |     int64_t token = clearCallingIdentity(); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3840 |  | 
 | 3841 |     for (auto& i : evicted) { | 
 | 3842 |         i->disconnect(); | 
 | 3843 |     } | 
 | 3844 |  | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 3845 |     restoreCallingIdentity(token); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3846 |  | 
 | 3847 |     // Reacquire mServiceLock | 
 | 3848 |     mServiceLock.lock(); | 
 | 3849 | } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3850 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3851 | void CameraService::logEvent(const std::string &event) { | 
 | 3852 |     std::string curTime = getFormattedCurrentTime(); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3853 |     Mutex::Autolock l(mLogLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3854 |     std::string msg = curTime + " : " + event; | 
| Rucha Katakwar | d9ea645 | 2021-05-06 11:57:16 -0700 | [diff] [blame] | 3855 |     // For service error events, print the msg only once. | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3856 |     if (msg.find("SERVICE ERROR") != std::string::npos) { | 
| Rucha Katakwar | d9ea645 | 2021-05-06 11:57:16 -0700 | [diff] [blame] | 3857 |         mEventLog.add(msg); | 
 | 3858 |     } else if(sServiceErrorEventSet.find(msg) == sServiceErrorEventSet.end()) { | 
 | 3859 |         // Error event not added to the dumpsys log before | 
 | 3860 |         mEventLog.add(msg); | 
 | 3861 |         sServiceErrorEventSet.insert(msg); | 
 | 3862 |     } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3863 | } | 
 | 3864 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3865 | void CameraService::logDisconnected(const std::string &cameraId, int clientPid, | 
 | 3866 |         const std::string &clientPackage) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 3867 |     // Log the clients evicted | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3868 |     logEvent(fmt::sprintf("DISCONNECT device %s client for package %s (PID %d)", cameraId.c_str(), | 
 | 3869 |             clientPackage.c_str(), clientPid)); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3870 | } | 
 | 3871 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3872 | void CameraService::logDisconnectedOffline(const std::string &cameraId, int clientPid, | 
 | 3873 |         const std::string &clientPackage) { | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 3874 |     // Log the clients evicted | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3875 |     logEvent(fmt::sprintf("DISCONNECT offline device %s client for package %s (PID %d)", | 
 | 3876 |             cameraId.c_str(), clientPackage.c_str(), clientPid)); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 3877 | } | 
 | 3878 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3879 | void CameraService::logConnected(const std::string &cameraId, int clientPid, | 
 | 3880 |         const std::string &clientPackage) { | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3881 |     // Log the clients evicted | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3882 |     logEvent(fmt::sprintf("CONNECT device %s client for package %s (PID %d)", cameraId.c_str(), | 
 | 3883 |             clientPackage.c_str(), clientPid)); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3884 | } | 
 | 3885 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3886 | void CameraService::logConnectedOffline(const std::string &cameraId, int clientPid, | 
 | 3887 |         const std::string &clientPackage) { | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 3888 |     // Log the clients evicted | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3889 |     logEvent(fmt::sprintf("CONNECT offline device %s client for package %s (PID %d)", | 
 | 3890 |             cameraId.c_str(), clientPackage.c_str(), clientPid)); | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 3891 | } | 
 | 3892 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3893 | void CameraService::logRejected(const std::string &cameraId, int clientPid, | 
 | 3894 |         const std::string &clientPackage, const std::string &reason) { | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3895 |     // Log the client rejected | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3896 |     logEvent(fmt::sprintf("REJECT device %s client for package %s (PID %d), reason: (%s)", | 
 | 3897 |             cameraId.c_str(), clientPackage.c_str(), clientPid, reason.c_str())); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3898 | } | 
 | 3899 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3900 | void CameraService::logTorchEvent(const std::string &cameraId, const std::string &torchState, | 
 | 3901 |         int clientPid) { | 
| Jayant Chowdhary | 0e2eefd | 2019-04-18 14:05:43 -0700 | [diff] [blame] | 3902 |     // Log torch event | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3903 |     logEvent(fmt::sprintf("Torch for camera id %s turned %s for client PID %d", cameraId.c_str(), | 
 | 3904 |             torchState.c_str(), clientPid)); | 
| Jayant Chowdhary | 0e2eefd | 2019-04-18 14:05:43 -0700 | [diff] [blame] | 3905 | } | 
 | 3906 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 3907 | void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds, | 
 | 3908 |         const std::set<userid_t>& newUserIds) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3909 |     std::string newUsers = toString(newUserIds); | 
 | 3910 |     std::string oldUsers = toString(oldUserIds); | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 3911 |     if (oldUsers.size() == 0) { | 
 | 3912 |         oldUsers = "<None>"; | 
 | 3913 |     } | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3914 |     // Log the new and old users | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3915 |     logEvent(fmt::sprintf("USER_SWITCH previous allowed user IDs: %s, current allowed user IDs: %s", | 
 | 3916 |             oldUsers.c_str(), newUsers.c_str())); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3917 | } | 
 | 3918 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3919 | void CameraService::logDeviceRemoved(const std::string &cameraId, const std::string &reason) { | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3920 |     // Log the device removal | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3921 |     logEvent(fmt::sprintf("REMOVE device %s, reason: (%s)", cameraId.c_str(), reason.c_str())); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3922 | } | 
 | 3923 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3924 | void CameraService::logDeviceAdded(const std::string &cameraId, const std::string &reason) { | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3925 |     // Log the device removal | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3926 |     logEvent(fmt::sprintf("ADD device %s, reason: (%s)", cameraId.c_str(), reason.c_str())); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3927 | } | 
 | 3928 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3929 | void CameraService::logClientDied(int clientPid, const std::string &reason) { | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 3930 |     // Log the device removal | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3931 |     logEvent(fmt::sprintf("DIED client(s) with PID %d, reason: (%s)", clientPid, reason.c_str())); | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 3932 | } | 
 | 3933 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 3934 | void CameraService::logServiceError(const std::string &msg, int errorCode) { | 
 | 3935 |     logEvent(fmt::sprintf("SERVICE ERROR: %s : %d (%s)", msg.c_str(), errorCode, | 
 | 3936 |             strerror(-errorCode))); | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 3937 | } | 
 | 3938 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 3939 | status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, | 
 | 3940 |         uint32_t flags) { | 
 | 3941 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3942 |     // Permission checks | 
 | 3943 |     switch (code) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 3944 |         case SHELL_COMMAND_TRANSACTION: { | 
 | 3945 |             int in = data.readFileDescriptor(); | 
 | 3946 |             int out = data.readFileDescriptor(); | 
 | 3947 |             int err = data.readFileDescriptor(); | 
 | 3948 |             int argc = data.readInt32(); | 
 | 3949 |             Vector<String16> args; | 
 | 3950 |             for (int i = 0; i < argc && data.dataAvail() > 0; i++) { | 
 | 3951 |                args.add(data.readString16()); | 
 | 3952 |             } | 
 | 3953 |             sp<IBinder> unusedCallback; | 
 | 3954 |             sp<IResultReceiver> resultReceiver; | 
 | 3955 |             status_t status; | 
 | 3956 |             if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) { | 
 | 3957 |                 return status; | 
 | 3958 |             } | 
 | 3959 |             if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) { | 
 | 3960 |                 return status; | 
 | 3961 |             } | 
 | 3962 |             status = shellCommand(in, out, err, args); | 
 | 3963 |             if (resultReceiver != nullptr) { | 
 | 3964 |                 resultReceiver->send(status); | 
 | 3965 |             } | 
 | 3966 |             return NO_ERROR; | 
 | 3967 |         } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3968 |     } | 
 | 3969 |  | 
 | 3970 |     return BnCameraService::onTransact(code, data, reply, flags); | 
 | 3971 | } | 
 | 3972 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3973 | // We share the media players for shutter and recording sound for all clients. | 
 | 3974 | // A reference count is kept to determine when we will actually release the | 
 | 3975 | // media players. | 
| Jaekyun Seok | ef49805 | 2018-03-23 13:09:44 +0900 | [diff] [blame] | 3976 | sp<MediaPlayer> CameraService::newMediaPlayer(const char *file) { | 
 | 3977 |     sp<MediaPlayer> mp = new MediaPlayer(); | 
 | 3978 |     status_t error; | 
 | 3979 |     if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) { | 
| Eino-Ville Talvala | 60a78ac | 2012-01-05 15:34:53 -0800 | [diff] [blame] | 3980 |         mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); | 
| Jaekyun Seok | ef49805 | 2018-03-23 13:09:44 +0900 | [diff] [blame] | 3981 |         error = mp->prepare(); | 
 | 3982 |     } | 
 | 3983 |     if (error != NO_ERROR) { | 
| Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 3984 |         ALOGE("Failed to load CameraService sounds: %s", file); | 
| Jaekyun Seok | ef49805 | 2018-03-23 13:09:44 +0900 | [diff] [blame] | 3985 |         mp->disconnect(); | 
 | 3986 |         mp.clear(); | 
| Jaekyun Seok | 59a8ef0 | 2018-01-15 14:49:05 +0900 | [diff] [blame] | 3987 |         return nullptr; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 3988 |     } | 
 | 3989 |     return mp; | 
 | 3990 | } | 
 | 3991 |  | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 3992 | void CameraService::increaseSoundRef() { | 
 | 3993 |     Mutex::Autolock lock(mSoundLock); | 
 | 3994 |     mSoundRef++; | 
 | 3995 | } | 
 | 3996 |  | 
 | 3997 | void CameraService::loadSoundLocked(sound_kind kind) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 3998 |     ATRACE_CALL(); | 
 | 3999 |  | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4000 |     LOG1("CameraService::loadSoundLocked ref=%d", mSoundRef); | 
 | 4001 |     if (SOUND_SHUTTER == kind && mSoundPlayer[SOUND_SHUTTER] == NULL) { | 
 | 4002 |         mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg"); | 
 | 4003 |         if (mSoundPlayer[SOUND_SHUTTER] == nullptr) { | 
 | 4004 |             mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); | 
 | 4005 |         } | 
 | 4006 |     } else if (SOUND_RECORDING_START == kind && mSoundPlayer[SOUND_RECORDING_START] ==  NULL) { | 
 | 4007 |         mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg"); | 
 | 4008 |         if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) { | 
 | 4009 |             mSoundPlayer[SOUND_RECORDING_START] = | 
| Jaekyun Seok | 59a8ef0 | 2018-01-15 14:49:05 +0900 | [diff] [blame] | 4010 |                 newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4011 |         } | 
 | 4012 |     } else if (SOUND_RECORDING_STOP == kind && mSoundPlayer[SOUND_RECORDING_STOP] == NULL) { | 
 | 4013 |         mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg"); | 
 | 4014 |         if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) { | 
 | 4015 |             mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg"); | 
 | 4016 |         } | 
| Jaekyun Seok | 59a8ef0 | 2018-01-15 14:49:05 +0900 | [diff] [blame] | 4017 |     } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4018 | } | 
 | 4019 |  | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4020 | void CameraService::decreaseSoundRef() { | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4021 |     Mutex::Autolock lock(mSoundLock); | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4022 |     LOG1("CameraService::decreaseSoundRef ref=%d", mSoundRef); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4023 |     if (--mSoundRef) return; | 
 | 4024 |  | 
 | 4025 |     for (int i = 0; i < NUM_SOUNDS; i++) { | 
 | 4026 |         if (mSoundPlayer[i] != 0) { | 
 | 4027 |             mSoundPlayer[i]->disconnect(); | 
 | 4028 |             mSoundPlayer[i].clear(); | 
 | 4029 |         } | 
 | 4030 |     } | 
 | 4031 | } | 
 | 4032 |  | 
 | 4033 | void CameraService::playSound(sound_kind kind) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 4034 |     ATRACE_CALL(); | 
 | 4035 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4036 |     LOG1("playSound(%d)", kind); | 
| Eino-Ville Talvala | 139ca75 | 2021-04-23 15:40:34 -0700 | [diff] [blame] | 4037 |     if (kind < 0 || kind >= NUM_SOUNDS) { | 
 | 4038 |         ALOGE("%s: Invalid sound id requested: %d", __FUNCTION__, kind); | 
 | 4039 |         return; | 
 | 4040 |     } | 
 | 4041 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4042 |     Mutex::Autolock lock(mSoundLock); | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4043 |     loadSoundLocked(kind); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4044 |     sp<MediaPlayer> player = mSoundPlayer[kind]; | 
 | 4045 |     if (player != 0) { | 
| Chih-Chung Chang | 8888a75 | 2011-10-20 10:47:26 +0800 | [diff] [blame] | 4046 |         player->seekTo(0); | 
 | 4047 |         player->start(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4048 |     } | 
 | 4049 | } | 
 | 4050 |  | 
 | 4051 | // ---------------------------------------------------------------------------- | 
 | 4052 |  | 
 | 4053 | CameraService::Client::Client(const sp<CameraService>& cameraService, | 
| Wu-cheng Li | b7a6794 | 2010-08-17 15:45:37 -0700 | [diff] [blame] | 4054 |         const sp<ICameraClient>& cameraClient, | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 4055 |         std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4056 |         const std::string& clientPackageName, bool systemNativeClient, | 
 | 4057 |         const std::optional<std::string>& clientFeatureId, | 
 | 4058 |         const std::string& cameraIdStr, | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 4059 |         int api1CameraId, int cameraFacing, int sensorOrientation, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4060 |         int clientPid, uid_t clientUid, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 4061 |         int servicePid, int rotationOverride) : | 
| Eino-Ville Talvala | e992e75 | 2014-11-07 16:17:48 -0800 | [diff] [blame] | 4062 |         CameraService::BasicClient(cameraService, | 
| Marco Nelissen | f888020 | 2014-11-14 07:58:25 -0800 | [diff] [blame] | 4063 |                 IInterface::asBinder(cameraClient), | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 4064 |                 attributionAndPermissionUtils, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 4065 |                 clientPackageName, systemNativeClient, clientFeatureId, | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 4066 |                 cameraIdStr, cameraFacing, sensorOrientation, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4067 |                 clientPid, clientUid, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 4068 |                 servicePid, rotationOverride), | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 4069 |         mCameraId(api1CameraId) | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4070 | { | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 4071 |     int callingPid = getCallingPid(); | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4072 |     LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4073 |  | 
| Igor Murashkin | 44cfcf0 | 2013-03-01 16:22:28 -0800 | [diff] [blame] | 4074 |     mRemoteCallback = cameraClient; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4075 |  | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4076 |     cameraService->increaseSoundRef(); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4077 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4078 |     LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4079 | } | 
 | 4080 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4081 | // tear down the client | 
 | 4082 | CameraService::Client::~Client() { | 
| Eino-Ville Talvala | d09801b | 2013-04-23 15:16:57 -0700 | [diff] [blame] | 4083 |     ALOGV("~Client"); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4084 |     mDestructionStarted = true; | 
 | 4085 |  | 
| username | 5755fea | 2018-12-27 09:48:08 +0800 | [diff] [blame] | 4086 |     sCameraService->decreaseSoundRef(); | 
| Igor Murashkin | 036bc3e | 2012-10-08 15:09:46 -0700 | [diff] [blame] | 4087 |     // unconditionally disconnect. function is idempotent | 
 | 4088 |     Client::disconnect(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4089 | } | 
 | 4090 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4091 | sp<CameraService> CameraService::BasicClient::BasicClient::sCameraService; | 
 | 4092 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4093 | CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4094 |         const sp<IBinder>& remoteCallback, | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 4095 |         std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4096 |         const std::string& clientPackageName, bool nativeClient, | 
 | 4097 |         const std::optional<std::string>& clientFeatureId, const std::string& cameraIdStr, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 4098 |         int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid, | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 4099 |         int servicePid, int rotationOverride): | 
| Austin Borger | 249e659 | 2024-03-10 22:28:11 -0700 | [diff] [blame] | 4100 |         AttributionAndPermissionUtilsEncapsulator(attributionAndPermissionUtils), | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4101 |         mDestructionStarted(false), | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 4102 |         mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation), | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 4103 |         mClientPackageName(clientPackageName), mSystemNativeClient(nativeClient), | 
 | 4104 |         mClientFeatureId(clientFeatureId), | 
| Philip P. Moltmann | 9e648f6 | 2019-11-04 12:52:45 -0800 | [diff] [blame] | 4105 |         mClientPid(clientPid), mClientUid(clientUid), | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4106 |         mServicePid(servicePid), | 
| Shuzhen Wang | 2c65679 | 2020-04-13 17:36:49 -0700 | [diff] [blame] | 4107 |         mDisconnected(false), mUidIsTrusted(false), | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 4108 |         mRotationOverride(rotationOverride), | 
| Yin-Chia Yeh | dba0323 | 2019-08-19 15:54:28 -0700 | [diff] [blame] | 4109 |         mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE), | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4110 |         mRemoteBinder(remoteCallback), | 
 | 4111 |         mOpsActive(false), | 
 | 4112 |         mOpsStreaming(false) | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4113 | { | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4114 |     if (sCameraService == nullptr) { | 
 | 4115 |         sCameraService = cameraService; | 
 | 4116 |     } | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 4117 |  | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 4118 |     // There are 2 scenarios in which a client won't have AppOps operations | 
 | 4119 |     // (both scenarios : native clients) | 
 | 4120 |     //    1) It's an system native client*, the package name will be empty | 
 | 4121 |     //       and it will return from this function in the previous if condition | 
 | 4122 |     //       (This is the same as the previously existing behavior). | 
 | 4123 |     //    2) It is a system native client, but its package name has been | 
 | 4124 |     //       modified for debugging, however it still must not use AppOps since | 
 | 4125 |     //       the package name is not a real one. | 
 | 4126 |     // | 
 | 4127 |     //       * system native client - native client with UID < AID_APP_START. It | 
 | 4128 |     //         doesn't exclude clients not on the system partition. | 
 | 4129 |     if (!mSystemNativeClient) { | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4130 |         mAppOpsManager = std::make_unique<AppOpsManager>(); | 
 | 4131 |     } | 
| Shuzhen Wang | 2c65679 | 2020-04-13 17:36:49 -0700 | [diff] [blame] | 4132 |  | 
| Charles Chen | f075f08 | 2024-03-04 23:32:55 +0000 | [diff] [blame] | 4133 |     mUidIsTrusted = isTrustedCallingUid(mClientUid); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4134 | } | 
 | 4135 |  | 
 | 4136 | CameraService::BasicClient::~BasicClient() { | 
| Eino-Ville Talvala | d09801b | 2013-04-23 15:16:57 -0700 | [diff] [blame] | 4137 |     ALOGV("~BasicClient"); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4138 |     mDestructionStarted = true; | 
 | 4139 | } | 
 | 4140 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4141 | binder::Status CameraService::BasicClient::disconnect() { | 
 | 4142 |     binder::Status res = Status::ok(); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 4143 |     if (mDisconnected) { | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4144 |         return res; | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 4145 |     } | 
| Eino-Ville Talvala | 24901c8 | 2015-09-04 14:15:58 -0700 | [diff] [blame] | 4146 |     mDisconnected = true; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4147 |  | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4148 |     sCameraService->removeByClient(this); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4149 |     sCameraService->logDisconnected(mCameraIdStr, mClientPid, mClientPackageName); | 
| Peter Kalauskas | a29c135 | 2018-10-10 12:05:42 -0700 | [diff] [blame] | 4150 |     sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4151 |             mCameraIdStr); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4152 |  | 
 | 4153 |     sp<IBinder> remote = getRemote(); | 
 | 4154 |     if (remote != nullptr) { | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4155 |         remote->unlinkToDeath(sCameraService); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4156 |     } | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 4157 |  | 
 | 4158 |     finishCameraOps(); | 
| Chien-Yu Chen | e4fe21b | 2016-08-04 12:42:40 -0700 | [diff] [blame] | 4159 |     // Notify flashlight that a camera device is closed. | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4160 |     sCameraService->mFlashlight->deviceClosed(mCameraIdStr); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4161 |     ALOGI("%s: Disconnected client for camera %s for PID %d", __FUNCTION__, mCameraIdStr.c_str(), | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4162 |             mClientPid); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4163 |  | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 4164 |     // client shouldn't be able to call into us anymore | 
 | 4165 |     mClientPid = 0; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4166 |  | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 4167 |     const auto& mActivityManager = getActivityManager(); | 
 | 4168 |     if (mActivityManager) { | 
 | 4169 |         mActivityManager->logFgsApiEnd(LOG_FGS_CAMERA_API, | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 4170 |             getCallingUid(), | 
 | 4171 |             getCallingPid()); | 
| Kunal Malhotra | bfc9605 | 2023-02-28 23:25:34 +0000 | [diff] [blame] | 4172 |     } | 
 | 4173 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4174 |     return res; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 4175 | } | 
 | 4176 |  | 
| Eino-Ville Talvala | c400396 | 2016-01-13 10:07:04 -0800 | [diff] [blame] | 4177 | status_t CameraService::BasicClient::dump(int, const Vector<String16>&) { | 
 | 4178 |     // No dumping of clients directly over Binder, | 
 | 4179 |     // must go through CameraService::dump | 
 | 4180 |     android_errorWriteWithInfoLog(SN_EVENT_LOG_ID, "26265403", | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 4181 |             getCallingUid(), NULL, 0); | 
| Eino-Ville Talvala | c400396 | 2016-01-13 10:07:04 -0800 | [diff] [blame] | 4182 |     return OK; | 
 | 4183 | } | 
 | 4184 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4185 | status_t CameraService::BasicClient::startWatchingTags(const std::string&, int) { | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 4186 |     // Can't watch tags directly, must go through CameraService::startWatchingTags | 
 | 4187 |     return OK; | 
 | 4188 | } | 
 | 4189 |  | 
 | 4190 | status_t CameraService::BasicClient::stopWatchingTags(int) { | 
 | 4191 |     // Can't watch tags directly, must go through CameraService::stopWatchingTags | 
 | 4192 |     return OK; | 
 | 4193 | } | 
 | 4194 |  | 
 | 4195 | status_t CameraService::BasicClient::dumpWatchedEventsToVector(std::vector<std::string> &) { | 
 | 4196 |     // Can't watch tags directly, must go through CameraService::dumpWatchedEventsToVector | 
 | 4197 |     return OK; | 
 | 4198 | } | 
 | 4199 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4200 | std::string CameraService::BasicClient::getPackageName() const { | 
| Svetoslav Ganov | 280405a | 2015-05-12 02:19:27 +0000 | [diff] [blame] | 4201 |     return mClientPackageName; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4202 | } | 
 | 4203 |  | 
| Emilian Peev | 8b64f28 | 2021-03-25 16:49:57 -0700 | [diff] [blame] | 4204 | int CameraService::BasicClient::getCameraFacing() const { | 
 | 4205 |     return mCameraFacing; | 
 | 4206 | } | 
 | 4207 |  | 
 | 4208 | int CameraService::BasicClient::getCameraOrientation() const { | 
 | 4209 |     return mOrientation; | 
 | 4210 | } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4211 |  | 
 | 4212 | int CameraService::BasicClient::getClientPid() const { | 
 | 4213 |     return mClientPid; | 
 | 4214 | } | 
 | 4215 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 4216 | uid_t CameraService::BasicClient::getClientUid() const { | 
 | 4217 |     return mClientUid; | 
 | 4218 | } | 
 | 4219 |  | 
| Ruben Brunk | 0bbf8b2 | 2015-04-30 14:35:42 -0700 | [diff] [blame] | 4220 | bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const { | 
 | 4221 |     // Defaults to API2. | 
 | 4222 |     return level == API_2; | 
 | 4223 | } | 
 | 4224 |  | 
| Yin-Chia Yeh | cfab4e1 | 2019-09-09 13:08:28 -0700 | [diff] [blame] | 4225 | status_t CameraService::BasicClient::setAudioRestriction(int32_t mode) { | 
| Yin-Chia Yeh | dba0323 | 2019-08-19 15:54:28 -0700 | [diff] [blame] | 4226 |     { | 
 | 4227 |         Mutex::Autolock l(mAudioRestrictionLock); | 
 | 4228 |         mAudioRestriction = mode; | 
 | 4229 |     } | 
| Yin-Chia Yeh | cfab4e1 | 2019-09-09 13:08:28 -0700 | [diff] [blame] | 4230 |     sCameraService->updateAudioRestriction(); | 
 | 4231 |     return OK; | 
 | 4232 | } | 
 | 4233 |  | 
 | 4234 | int32_t CameraService::BasicClient::getServiceAudioRestriction() const { | 
| Yin-Chia Yeh | dba0323 | 2019-08-19 15:54:28 -0700 | [diff] [blame] | 4235 |     return sCameraService->updateAudioRestriction(); | 
 | 4236 | } | 
 | 4237 |  | 
 | 4238 | int32_t CameraService::BasicClient::getAudioRestriction() const { | 
 | 4239 |     Mutex::Autolock l(mAudioRestrictionLock); | 
 | 4240 |     return mAudioRestriction; | 
 | 4241 | } | 
 | 4242 |  | 
 | 4243 | bool CameraService::BasicClient::isValidAudioRestriction(int32_t mode) { | 
 | 4244 |     switch (mode) { | 
 | 4245 |         case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE: | 
 | 4246 |         case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_VIBRATION: | 
 | 4247 |         case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_VIBRATION_SOUND: | 
 | 4248 |             return true; | 
 | 4249 |         default: | 
 | 4250 |             return false; | 
 | 4251 |     } | 
 | 4252 | } | 
 | 4253 |  | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4254 | status_t CameraService::BasicClient::handleAppOpMode(int32_t mode) { | 
 | 4255 |     if (mode == AppOpsManager::MODE_ERRORED) { | 
 | 4256 |         ALOGI("Camera %s: Access for \"%s\" has been revoked", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4257 |                 mCameraIdStr.c_str(), mClientPackageName.c_str()); | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4258 |         return PERMISSION_DENIED; | 
 | 4259 |     } else if (!mUidIsTrusted && mode == AppOpsManager::MODE_IGNORED) { | 
 | 4260 |         // If the calling Uid is trusted (a native service), the AppOpsManager could | 
 | 4261 |         // return MODE_IGNORED. Do not treat such case as error. | 
 | 4262 |         bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, | 
 | 4263 |                 mClientPackageName); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4264 |  | 
 | 4265 |         bool isCameraPrivacyEnabled; | 
 | 4266 |         if (flags::camera_privacy_allowlist()) { | 
 | 4267 |             isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled( | 
 | 4268 |                     toString16(mClientPackageName), std::string(), mClientPid, mClientUid); | 
 | 4269 |         } else { | 
 | 4270 |             isCameraPrivacyEnabled = | 
| Evan Severson | d0b6992 | 2022-01-27 10:47:34 -0800 | [diff] [blame] | 4271 |                 sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4272 |         } | 
| Jyoti Bhayana | 8143e57 | 2023-01-09 08:46:49 -0800 | [diff] [blame] | 4273 |         // We don't want to return EACCESS if the CameraPrivacy is enabled. | 
 | 4274 |         // We prefer to successfully open the camera and perform camera muting | 
 | 4275 |         // or blocking in connectHelper as handleAppOpMode can be called before the | 
 | 4276 |         // connection has been fully established and at that time camera muting | 
 | 4277 |         // capabilities are unknown. | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4278 |         if (!isUidActive || !isCameraPrivacyEnabled) { | 
| Austin Borger | fd05d98 | 2024-04-22 15:54:50 -0700 | [diff] [blame] | 4279 |             ALOGI("Camera %s: Access for \"%s\" has been restricted." | 
 | 4280 |                     "uid active: %s, privacy enabled: %s", mCameraIdStr.c_str(), | 
 | 4281 |                     mClientPackageName.c_str(), isUidActive ? "true" : "false", | 
 | 4282 |                     isCameraPrivacyEnabled ? "true" : "false"); | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4283 |             // Return the same error as for device policy manager rejection | 
 | 4284 |             return -EACCES; | 
 | 4285 |         } | 
 | 4286 |     } | 
 | 4287 |     return OK; | 
 | 4288 | } | 
 | 4289 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4290 | status_t CameraService::BasicClient::startCameraOps() { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 4291 |     ATRACE_CALL(); | 
 | 4292 |  | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 4293 |     { | 
 | 4294 |         ALOGV("%s: Start camera ops, package name = %s, client UID = %d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4295 |               __FUNCTION__, mClientPackageName.c_str(), mClientUid); | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 4296 |     } | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4297 |     if (mAppOpsManager != nullptr) { | 
 | 4298 |         // Notify app ops that the camera is not available | 
 | 4299 |         mOpsCallback = new OpsCallback(this); | 
| Austin Borger | ca1e006 | 2023-06-28 11:32:55 -0700 | [diff] [blame] | 4300 |  | 
 | 4301 |         if (flags::watch_foreground_changes()) { | 
 | 4302 |             mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, | 
 | 4303 |                 toString16(mClientPackageName), | 
 | 4304 |                 AppOpsManager::WATCH_FOREGROUND_CHANGES, mOpsCallback); | 
 | 4305 |         } else { | 
 | 4306 |             mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4307 |                 toString16(mClientPackageName), mOpsCallback); | 
| Austin Borger | ca1e006 | 2023-06-28 11:32:55 -0700 | [diff] [blame] | 4308 |         } | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 4309 |  | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4310 |         // Just check for camera acccess here on open - delay startOp until | 
 | 4311 |         // camera frames start streaming in startCameraStreamingOps | 
 | 4312 |         int32_t mode = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, mClientUid, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4313 |                 toString16(mClientPackageName)); | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4314 |         status_t res = handleAppOpMode(mode); | 
 | 4315 |         if (res != OK) { | 
 | 4316 |             return res; | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4317 |         } | 
| Svetoslav | 28e8ef7 | 2015-05-11 19:21:31 -0700 | [diff] [blame] | 4318 |     } | 
 | 4319 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4320 |     mOpsActive = true; | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 4321 |  | 
 | 4322 |     // Transition device availability listeners from PRESENT -> NOT_AVAILABLE | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4323 |     sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr); | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 4324 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4325 |     sCameraService->mUidPolicy->registerMonitorUid(mClientUid, /*openCamera*/true); | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4326 |  | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 4327 |     // Notify listeners of camera open/close status | 
 | 4328 |     sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName); | 
 | 4329 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4330 |     return OK; | 
 | 4331 | } | 
 | 4332 |  | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4333 | status_t CameraService::BasicClient::startCameraStreamingOps() { | 
 | 4334 |     ATRACE_CALL(); | 
 | 4335 |  | 
 | 4336 |     if (!mOpsActive) { | 
 | 4337 |         ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__); | 
 | 4338 |         return INVALID_OPERATION; | 
 | 4339 |     } | 
 | 4340 |     if (mOpsStreaming) { | 
 | 4341 |         ALOGV("%s: Streaming already active!", __FUNCTION__); | 
 | 4342 |         return OK; | 
 | 4343 |     } | 
 | 4344 |  | 
 | 4345 |     ALOGV("%s: Start camera streaming ops, package name = %s, client UID = %d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4346 |             __FUNCTION__, mClientPackageName.c_str(), mClientUid); | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4347 |  | 
 | 4348 |     if (mAppOpsManager != nullptr) { | 
 | 4349 |         int32_t mode = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, mClientUid, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4350 |                 toString16(mClientPackageName), /*startIfModeDefault*/ false, | 
 | 4351 |                 toString16(mClientFeatureId), | 
 | 4352 |                 toString16("start camera ") + toString16(mCameraIdStr)); | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4353 |         status_t res = handleAppOpMode(mode); | 
 | 4354 |         if (res != OK) { | 
 | 4355 |             return res; | 
 | 4356 |         } | 
 | 4357 |     } | 
 | 4358 |  | 
 | 4359 |     mOpsStreaming = true; | 
 | 4360 |  | 
 | 4361 |     return OK; | 
 | 4362 | } | 
 | 4363 |  | 
| Valentin Iftime | c0b8d47 | 2021-07-23 20:21:06 +0200 | [diff] [blame] | 4364 | status_t CameraService::BasicClient::noteAppOp() { | 
 | 4365 |     ATRACE_CALL(); | 
 | 4366 |  | 
 | 4367 |     ALOGV("%s: Start camera noteAppOp, package name = %s, client UID = %d", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4368 |             __FUNCTION__, mClientPackageName.c_str(), mClientUid); | 
| Valentin Iftime | c0b8d47 | 2021-07-23 20:21:06 +0200 | [diff] [blame] | 4369 |  | 
 | 4370 |     // noteAppOp is only used for when camera mute is not supported, in order | 
 | 4371 |     // to trigger the sensor privacy "Unblock" dialog | 
 | 4372 |     if (mAppOpsManager != nullptr) { | 
 | 4373 |         int32_t mode = mAppOpsManager->noteOp(AppOpsManager::OP_CAMERA, mClientUid, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4374 |                 toString16(mClientPackageName), toString16(mClientFeatureId), | 
 | 4375 |                 toString16("start camera ") + toString16(mCameraIdStr)); | 
| Valentin Iftime | c0b8d47 | 2021-07-23 20:21:06 +0200 | [diff] [blame] | 4376 |         status_t res = handleAppOpMode(mode); | 
 | 4377 |         if (res != OK) { | 
 | 4378 |             return res; | 
 | 4379 |         } | 
 | 4380 |     } | 
 | 4381 |  | 
 | 4382 |     return OK; | 
 | 4383 | } | 
 | 4384 |  | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4385 | status_t CameraService::BasicClient::finishCameraStreamingOps() { | 
 | 4386 |     ATRACE_CALL(); | 
 | 4387 |  | 
 | 4388 |     if (!mOpsActive) { | 
 | 4389 |         ALOGE("%s: Calling streaming start when not yet active", __FUNCTION__); | 
 | 4390 |         return INVALID_OPERATION; | 
 | 4391 |     } | 
 | 4392 |     if (!mOpsStreaming) { | 
 | 4393 |         ALOGV("%s: Streaming not active!", __FUNCTION__); | 
 | 4394 |         return OK; | 
 | 4395 |     } | 
 | 4396 |  | 
 | 4397 |     if (mAppOpsManager != nullptr) { | 
 | 4398 |         mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4399 |                 toString16(mClientPackageName), toString16(mClientFeatureId)); | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4400 |         mOpsStreaming = false; | 
 | 4401 |     } | 
 | 4402 |  | 
 | 4403 |     return OK; | 
 | 4404 | } | 
 | 4405 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4406 | status_t CameraService::BasicClient::finishCameraOps() { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 4407 |     ATRACE_CALL(); | 
 | 4408 |  | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4409 |     if (mOpsStreaming) { | 
 | 4410 |         // Make sure we've notified everyone about camera stopping | 
 | 4411 |         finishCameraStreamingOps(); | 
 | 4412 |     } | 
 | 4413 |  | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 4414 |     // Check if startCameraOps succeeded, and if so, finish the camera op | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4415 |     if (mOpsActive) { | 
| Eino-Ville Talvala | 178e823 | 2021-04-16 18:41:39 -0700 | [diff] [blame] | 4416 |         mOpsActive = false; | 
 | 4417 |  | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 4418 |         // This function is called when a client disconnects. This should | 
 | 4419 |         // release the camera, but actually only if it was in a proper | 
 | 4420 |         // functional state, i.e. with status NOT_AVAILABLE | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 4421 |         std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT, | 
| Guennadi Liakhovetski | 151e3be | 2017-11-28 16:34:18 +0100 | [diff] [blame] | 4422 |                 StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT}; | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 4423 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 4424 |         // Transition to PRESENT if the camera is not in either of the rejected states | 
| Eino-Ville Talvala | 2f09bac | 2016-12-13 11:29:54 -0800 | [diff] [blame] | 4425 |         sCameraService->updateStatus(StatusInternal::PRESENT, | 
 | 4426 |                 mCameraIdStr, rejected); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4427 |     } | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 4428 |     // Always stop watching, even if no camera op is active | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4429 |     if (mOpsCallback != nullptr && mAppOpsManager != nullptr) { | 
 | 4430 |         mAppOpsManager->stopWatchingMode(mOpsCallback); | 
| Eino-Ville Talvala | e992e75 | 2014-11-07 16:17:48 -0800 | [diff] [blame] | 4431 |     } | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4432 |     mOpsCallback.clear(); | 
 | 4433 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4434 |     sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid, /*closeCamera*/true); | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4435 |  | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 4436 |     // Notify listeners of camera open/close status | 
 | 4437 |     sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName); | 
 | 4438 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4439 |     return OK; | 
 | 4440 | } | 
 | 4441 |  | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4442 | void CameraService::BasicClient::opChanged(int32_t op, const String16&) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 4443 |     ATRACE_CALL(); | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4444 |     if (mAppOpsManager == nullptr) { | 
 | 4445 |         return; | 
 | 4446 |     } | 
| Emilian Peev | b2bc5a4 | 2019-11-20 16:02:14 -0800 | [diff] [blame] | 4447 |     // TODO : add offline camera session case | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4448 |     if (op != AppOpsManager::OP_CAMERA) { | 
 | 4449 |         ALOGW("Unexpected app ops notification received: %d", op); | 
 | 4450 |         return; | 
 | 4451 |     } | 
 | 4452 |  | 
 | 4453 |     int32_t res; | 
| Jayant Chowdhary | b61526c | 2019-05-13 19:37:42 -0700 | [diff] [blame] | 4454 |     res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4455 |             mClientUid, toString16(mClientPackageName)); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4456 |     ALOGV("checkOp returns: %d, %s ", res, | 
 | 4457 |             res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" : | 
 | 4458 |             res == AppOpsManager::MODE_IGNORED ? "IGNORED" : | 
 | 4459 |             res == AppOpsManager::MODE_ERRORED ? "ERRORED" : | 
 | 4460 |             "UNKNOWN"); | 
 | 4461 |  | 
| Shuzhen Wang | 6490085 | 2021-02-05 09:03:29 -0800 | [diff] [blame] | 4462 |     if (res == AppOpsManager::MODE_ERRORED) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4463 |         ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.c_str(), | 
 | 4464 |               mClientPackageName.c_str()); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4465 |         block(); | 
| Shuzhen Wang | 6490085 | 2021-02-05 09:03:29 -0800 | [diff] [blame] | 4466 |     } else if (res == AppOpsManager::MODE_IGNORED) { | 
 | 4467 |         bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4468 |  | 
| Austin Borger | ca1e006 | 2023-06-28 11:32:55 -0700 | [diff] [blame] | 4469 |         // Uid may be active, but not visible to the user (e.g. PROCESS_STATE_FOREGROUND_SERVICE). | 
 | 4470 |         // If not visible, but still active, then we want to block instead of muting the camera. | 
 | 4471 |         int32_t procState = sCameraService->mUidPolicy->getProcState(mClientUid); | 
 | 4472 |         bool isUidVisible = (procState <= ActivityManager::PROCESS_STATE_BOUND_TOP); | 
 | 4473 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4474 |         bool isCameraPrivacyEnabled; | 
 | 4475 |         if (flags::camera_privacy_allowlist()) { | 
 | 4476 |             isCameraPrivacyEnabled = sCameraService->isCameraPrivacyEnabled( | 
 | 4477 |                     toString16(mClientPackageName),std::string(),mClientPid,mClientUid); | 
 | 4478 |         } else { | 
 | 4479 |             isCameraPrivacyEnabled = | 
| Evan Severson | d0b6992 | 2022-01-27 10:47:34 -0800 | [diff] [blame] | 4480 |                 sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4481 |         } | 
 | 4482 |  | 
 | 4483 |         ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d" | 
| Austin Borger | ca1e006 | 2023-06-28 11:32:55 -0700 | [diff] [blame] | 4484 |                 " isUidVisible %d, isCameraPrivacyEnabled %d", mCameraIdStr.c_str(), | 
 | 4485 |                 mClientPackageName.c_str(), mUidIsTrusted, isUidActive, isUidVisible, | 
 | 4486 |                 isCameraPrivacyEnabled); | 
 | 4487 |         // If the calling Uid is trusted (a native service), or the client Uid is active / visible | 
 | 4488 |         // (WAR for b/175320666)the AppOpsManager could return MODE_IGNORED. Do not treat such | 
 | 4489 |         // cases as error. | 
| Valentin Iftime | c0b8d47 | 2021-07-23 20:21:06 +0200 | [diff] [blame] | 4490 |         if (!mUidIsTrusted) { | 
| Austin Borger | ca1e006 | 2023-06-28 11:32:55 -0700 | [diff] [blame] | 4491 |             if (flags::watch_foreground_changes()) { | 
 | 4492 |                 if (isUidVisible && isCameraPrivacyEnabled && supportsCameraMute()) { | 
 | 4493 |                     setCameraMute(true); | 
 | 4494 |                 } else { | 
 | 4495 |                     block(); | 
 | 4496 |                 } | 
 | 4497 |             } else { | 
 | 4498 |                 if (isUidActive && isCameraPrivacyEnabled && supportsCameraMute()) { | 
 | 4499 |                     setCameraMute(true); | 
 | 4500 |                 } else if (!isUidActive | 
 | 4501 |                     || (isCameraPrivacyEnabled && !supportsCameraMute())) { | 
 | 4502 |                     block(); | 
 | 4503 |                 } | 
| Valentin Iftime | c0b8d47 | 2021-07-23 20:21:06 +0200 | [diff] [blame] | 4504 |             } | 
| Shuzhen Wang | 6490085 | 2021-02-05 09:03:29 -0800 | [diff] [blame] | 4505 |         } | 
| Evan Severson | 09ab400 | 2021-02-10 14:15:19 -0800 | [diff] [blame] | 4506 |     } else if (res == AppOpsManager::MODE_ALLOWED) { | 
 | 4507 |         setCameraMute(sCameraService->mOverrideCameraMuteMode); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4508 |     } | 
 | 4509 | } | 
 | 4510 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4511 | void CameraService::BasicClient::block() { | 
 | 4512 |     ATRACE_CALL(); | 
 | 4513 |  | 
 | 4514 |     // Reset the client PID to allow server-initiated disconnect, | 
 | 4515 |     // and to prevent further calls by client. | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 4516 |     mClientPid = getCallingPid(); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4517 |     CaptureResultExtras resultExtras; // a dummy result (invalid) | 
 | 4518 |     notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED, resultExtras); | 
 | 4519 |     disconnect(); | 
 | 4520 | } | 
 | 4521 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4522 | // ---------------------------------------------------------------------------- | 
 | 4523 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4524 | void CameraService::Client::notifyError(int32_t errorCode, | 
| Jing Mike | c7f9b13 | 2023-03-12 11:12:04 +0800 | [diff] [blame] | 4525 |         [[maybe_unused]] const CaptureResultExtras& resultExtras) { | 
| Ranjith Kagathi Ananda | 3e60089 | 2015-10-08 16:00:33 -0700 | [diff] [blame] | 4526 |     if (mRemoteCallback != NULL) { | 
| Yin-Chia Yeh | f13bda5 | 2018-05-31 12:12:59 -0700 | [diff] [blame] | 4527 |         int32_t api1ErrorCode = CAMERA_ERROR_RELEASED; | 
 | 4528 |         if (errorCode == hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISABLED) { | 
 | 4529 |             api1ErrorCode = CAMERA_ERROR_DISABLED; | 
 | 4530 |         } | 
 | 4531 |         mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, api1ErrorCode, 0); | 
| Ranjith Kagathi Ananda | 3e60089 | 2015-10-08 16:00:33 -0700 | [diff] [blame] | 4532 |     } else { | 
 | 4533 |         ALOGE("mRemoteCallback is NULL!!"); | 
 | 4534 |     } | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4535 | } | 
 | 4536 |  | 
| Igor Murashkin | 036bc3e | 2012-10-08 15:09:46 -0700 | [diff] [blame] | 4537 | // NOTE: function is idempotent | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4538 | binder::Status CameraService::Client::disconnect() { | 
| Eino-Ville Talvala | d09801b | 2013-04-23 15:16:57 -0700 | [diff] [blame] | 4539 |     ALOGV("Client::disconnect"); | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 4540 |     return BasicClient::disconnect(); | 
| Wu-cheng Li | e09591e | 2010-10-14 20:17:44 +0800 | [diff] [blame] | 4541 | } | 
 | 4542 |  | 
| Ruben Brunk | 0bbf8b2 | 2015-04-30 14:35:42 -0700 | [diff] [blame] | 4543 | bool CameraService::Client::canCastToApiClient(apiLevel level) const { | 
 | 4544 |     return level == API_1; | 
 | 4545 | } | 
 | 4546 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 4547 | CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client): | 
 | 4548 |         mClient(client) { | 
 | 4549 | } | 
 | 4550 |  | 
 | 4551 | void CameraService::Client::OpsCallback::opChanged(int32_t op, | 
 | 4552 |         const String16& packageName) { | 
 | 4553 |     sp<BasicClient> client = mClient.promote(); | 
 | 4554 |     if (client != NULL) { | 
 | 4555 |         client->opChanged(op, packageName); | 
 | 4556 |     } | 
 | 4557 | } | 
 | 4558 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 4559 | // ---------------------------------------------------------------------------- | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4560 | //                  UidPolicy | 
 | 4561 | // ---------------------------------------------------------------------------- | 
 | 4562 |  | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4563 | void CameraService::UidPolicy::registerWithActivityManager() { | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4564 |     Mutex::Autolock _l(mUidLock); | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4565 |     int32_t emptyUidArray[] = { }; | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4566 |  | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4567 |     if (mRegistered) return; | 
| Steven Moreland | 2f34814 | 2019-07-02 15:59:07 -0700 | [diff] [blame] | 4568 |     status_t res = mAm.linkToDeath(this); | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4569 |     mAm.registerUidObserverForUids(this, ActivityManager::UID_OBSERVER_GONE | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4570 |             | ActivityManager::UID_OBSERVER_IDLE | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4571 |             | ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE | 
 | 4572 |             | ActivityManager::UID_OBSERVER_PROC_OOM_ADJ, | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4573 |             ActivityManager::PROCESS_STATE_UNKNOWN, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4574 |             toString16(kServiceName), emptyUidArray, 0, mObserverToken); | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4575 |     if (res == OK) { | 
 | 4576 |         mRegistered = true; | 
 | 4577 |         ALOGV("UidPolicy: Registered with ActivityManager"); | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4578 |     } else { | 
 | 4579 |         ALOGE("UidPolicy: Failed to register with ActivityManager: 0x%08x", res); | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4580 |     } | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4581 | } | 
 | 4582 |  | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4583 | void CameraService::UidPolicy::onServiceRegistration(const String16& name, const sp<IBinder>&) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4584 |     if (name != toString16(kActivityServiceName)) { | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4585 |         return; | 
 | 4586 |     } | 
 | 4587 |  | 
 | 4588 |     registerWithActivityManager(); | 
 | 4589 | } | 
 | 4590 |  | 
 | 4591 | void CameraService::UidPolicy::registerSelf() { | 
 | 4592 |     // Use check service to see if the activity service is available | 
 | 4593 |     // If not available then register for notifications, instead of blocking | 
 | 4594 |     // till the service is ready | 
 | 4595 |     sp<IServiceManager> sm = defaultServiceManager(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4596 |     sp<IBinder> binder = sm->checkService(toString16(kActivityServiceName)); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4597 |     if (!binder) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4598 |         sm->registerForNotifications(toString16(kActivityServiceName), this); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4599 |     } else { | 
 | 4600 |         registerWithActivityManager(); | 
 | 4601 |     } | 
 | 4602 | } | 
 | 4603 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4604 | void CameraService::UidPolicy::unregisterSelf() { | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4605 |     Mutex::Autolock _l(mUidLock); | 
 | 4606 |  | 
| Steven Moreland | 2f34814 | 2019-07-02 15:59:07 -0700 | [diff] [blame] | 4607 |     mAm.unregisterUidObserver(this); | 
 | 4608 |     mAm.unlinkToDeath(this); | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4609 |     mRegistered = false; | 
 | 4610 |     mActiveUids.clear(); | 
 | 4611 |     ALOGV("UidPolicy: Unregistered with ActivityManager"); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4612 | } | 
 | 4613 |  | 
 | 4614 | void CameraService::UidPolicy::onUidGone(uid_t uid, bool disabled) { | 
 | 4615 |     onUidIdle(uid, disabled); | 
 | 4616 | } | 
 | 4617 |  | 
 | 4618 | void CameraService::UidPolicy::onUidActive(uid_t uid) { | 
 | 4619 |     Mutex::Autolock _l(mUidLock); | 
 | 4620 |     mActiveUids.insert(uid); | 
 | 4621 | } | 
 | 4622 |  | 
 | 4623 | void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) { | 
 | 4624 |     bool deleted = false; | 
 | 4625 |     { | 
 | 4626 |         Mutex::Autolock _l(mUidLock); | 
 | 4627 |         if (mActiveUids.erase(uid) > 0) { | 
 | 4628 |             deleted = true; | 
 | 4629 |         } | 
 | 4630 |     } | 
 | 4631 |     if (deleted) { | 
 | 4632 |         sp<CameraService> service = mService.promote(); | 
 | 4633 |         if (service != nullptr) { | 
 | 4634 |             service->blockClientsForUid(uid); | 
 | 4635 |         } | 
 | 4636 |     } | 
 | 4637 | } | 
 | 4638 |  | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4639 | void CameraService::UidPolicy::onUidStateChanged(uid_t uid, int32_t procState, | 
| Hui Yu | 13ad0eb | 2019-09-09 10:27:07 -0700 | [diff] [blame] | 4640 |         int64_t procStateSeq __unused, int32_t capability __unused) { | 
| Austin Borger | c5585dc | 2022-05-12 00:48:17 +0000 | [diff] [blame] | 4641 |     bool procStateChange = false; | 
 | 4642 |     { | 
 | 4643 |         Mutex::Autolock _l(mUidLock); | 
 | 4644 |         if (mMonitoredUids.find(uid) != mMonitoredUids.end() && | 
 | 4645 |                 mMonitoredUids[uid].procState != procState) { | 
 | 4646 |             mMonitoredUids[uid].procState = procState; | 
 | 4647 |             procStateChange = true; | 
 | 4648 |         } | 
 | 4649 |     } | 
 | 4650 |  | 
 | 4651 |     if (procStateChange) { | 
 | 4652 |         sp<CameraService> service = mService.promote(); | 
 | 4653 |         if (service != nullptr) { | 
 | 4654 |             service->notifyMonitoredUids(); | 
 | 4655 |         } | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4656 |     } | 
 | 4657 | } | 
 | 4658 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4659 | /** | 
 | 4660 |  * When the OOM adj of the uid owning the camera changes, a different uid waiting on camera | 
 | 4661 |  * privileges may take precedence if the owner's new OOM adj is greater than the waiting package. | 
 | 4662 |  * Here, we track which monitoredUid has the camera, and track its adj relative to other | 
 | 4663 |  * monitoredUids. If it is revised above some other monitoredUid, signal | 
 | 4664 |  * onCameraAccessPrioritiesChanged. This only needs to capture the case where there are two | 
 | 4665 |  * foreground apps in split screen - state changes will capture all other cases. | 
 | 4666 |  */ | 
 | 4667 | void CameraService::UidPolicy::onUidProcAdjChanged(uid_t uid, int32_t adj) { | 
 | 4668 |     std::unordered_set<uid_t> notifyUidSet; | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4669 |     { | 
 | 4670 |         Mutex::Autolock _l(mUidLock); | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4671 |         auto it = mMonitoredUids.find(uid); | 
 | 4672 |  | 
 | 4673 |         if (it != mMonitoredUids.end()) { | 
 | 4674 |             if (it->second.hasCamera) { | 
 | 4675 |                 for (auto &monitoredUid : mMonitoredUids) { | 
 | 4676 |                     if (monitoredUid.first != uid && adj > monitoredUid.second.procAdj) { | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4677 |                         ALOGV("%s: notify uid %d", __FUNCTION__, monitoredUid.first); | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4678 |                         notifyUidSet.emplace(monitoredUid.first); | 
 | 4679 |                     } | 
 | 4680 |                 } | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4681 |                 ALOGV("%s: notify uid %d", __FUNCTION__, uid); | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4682 |                 notifyUidSet.emplace(uid); | 
 | 4683 |             } else { | 
 | 4684 |                 for (auto &monitoredUid : mMonitoredUids) { | 
 | 4685 |                     if (monitoredUid.second.hasCamera && adj < monitoredUid.second.procAdj) { | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4686 |                         ALOGV("%s: notify uid %d", __FUNCTION__, uid); | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4687 |                         notifyUidSet.emplace(uid); | 
 | 4688 |                     } | 
 | 4689 |                 } | 
 | 4690 |             } | 
 | 4691 |             it->second.procAdj = adj; | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4692 |         } | 
 | 4693 |     } | 
 | 4694 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4695 |     if (notifyUidSet.size() > 0) { | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4696 |         sp<CameraService> service = mService.promote(); | 
 | 4697 |         if (service != nullptr) { | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4698 |             service->notifyMonitoredUids(notifyUidSet); | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4699 |         } | 
 | 4700 |     } | 
 | 4701 | } | 
 | 4702 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4703 | /** | 
 | 4704 |  * Register a uid for monitoring, and note whether it owns a camera. | 
 | 4705 |  */ | 
 | 4706 | void CameraService::UidPolicy::registerMonitorUid(uid_t uid, bool openCamera) { | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4707 |     Mutex::Autolock _l(mUidLock); | 
 | 4708 |     auto it = mMonitoredUids.find(uid); | 
 | 4709 |     if (it != mMonitoredUids.end()) { | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4710 |         it->second.refCount++; | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4711 |     } else { | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4712 |         MonitoredUid monitoredUid; | 
 | 4713 |         monitoredUid.procState = ActivityManager::PROCESS_STATE_NONEXISTENT; | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4714 |         monitoredUid.procAdj = resource_policy::UNKNOWN_ADJ; | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4715 |         monitoredUid.refCount = 1; | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4716 |         it = mMonitoredUids.emplace(std::pair<uid_t, MonitoredUid>(uid, monitoredUid)).first; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4717 |         status_t res = mAm.addUidToObserver(mObserverToken, toString16(kServiceName), uid); | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4718 |         if (res != OK) { | 
 | 4719 |             ALOGE("UidPolicy: Failed to add uid to observer: 0x%08x", res); | 
 | 4720 |         } | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4721 |     } | 
 | 4722 |  | 
 | 4723 |     if (openCamera) { | 
 | 4724 |         it->second.hasCamera = true; | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4725 |     } | 
 | 4726 | } | 
 | 4727 |  | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4728 | /** | 
 | 4729 |  * Unregister a uid for monitoring, and note whether it lost ownership of a camera. | 
 | 4730 |  */ | 
 | 4731 | void CameraService::UidPolicy::unregisterMonitorUid(uid_t uid, bool closeCamera) { | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4732 |     Mutex::Autolock _l(mUidLock); | 
 | 4733 |     auto it = mMonitoredUids.find(uid); | 
 | 4734 |     if (it != mMonitoredUids.end()) { | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4735 |         it->second.refCount--; | 
 | 4736 |         if (it->second.refCount == 0) { | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4737 |             mMonitoredUids.erase(it); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4738 |             status_t res = mAm.removeUidFromObserver(mObserverToken, toString16(kServiceName), uid); | 
| Austin Borger | d0309d4 | 2023-04-21 20:07:18 -0700 | [diff] [blame] | 4739 |             if (res != OK) { | 
 | 4740 |                 ALOGE("UidPolicy: Failed to remove uid from observer: 0x%08x", res); | 
 | 4741 |             } | 
| Austin Borger | dddb755 | 2023-03-30 17:53:01 -0700 | [diff] [blame] | 4742 |         } else if (closeCamera) { | 
 | 4743 |             it->second.hasCamera = false; | 
| Emilian Peev | 53722fa | 2019-02-22 17:47:20 -0800 | [diff] [blame] | 4744 |         } | 
 | 4745 |     } else { | 
 | 4746 |         ALOGE("%s: Trying to unregister uid: %d which is not monitored!", __FUNCTION__, uid); | 
 | 4747 |     } | 
 | 4748 | } | 
 | 4749 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4750 | bool CameraService::UidPolicy::isUidActive(uid_t uid, const std::string &callingPackage) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4751 |     Mutex::Autolock _l(mUidLock); | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4752 |     return isUidActiveLocked(uid, callingPackage); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4753 | } | 
 | 4754 |  | 
| Eino-Ville Talvala | 32b8c20 | 2018-08-20 10:27:58 -0700 | [diff] [blame] | 4755 | static const int64_t kPollUidActiveTimeoutTotalMillis = 300; | 
 | 4756 | static const int64_t kPollUidActiveTimeoutMillis = 50; | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 4757 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4758 | bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, const std::string &callingPackage) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4759 |     // Non-app UIDs are considered always active | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4760 |     // If activity manager is unreachable, assume everything is active | 
 | 4761 |     if (uid < FIRST_APPLICATION_UID || !mRegistered) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4762 |         return true; | 
 | 4763 |     } | 
 | 4764 |     auto it = mOverrideUids.find(uid); | 
 | 4765 |     if (it != mOverrideUids.end()) { | 
 | 4766 |         return it->second; | 
 | 4767 |     } | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4768 |     bool active = mActiveUids.find(uid) != mActiveUids.end(); | 
 | 4769 |     if (!active) { | 
 | 4770 |         // We want active UIDs to always access camera with their first attempt since | 
 | 4771 |         // there is no guarantee the app is robustly written and would retry getting | 
 | 4772 |         // the camera on failure. The inverse case is not a problem as we would take | 
 | 4773 |         // camera away soon once we get the callback that the uid is no longer active. | 
 | 4774 |         ActivityManager am; | 
 | 4775 |         // Okay to access with a lock held as UID changes are dispatched without | 
 | 4776 |         // a lock and we are a higher level component. | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 4777 |         int64_t startTimeMillis = 0; | 
 | 4778 |         do { | 
 | 4779 |             // TODO: Fix this b/109950150! | 
 | 4780 |             // Okay this is a hack. There is a race between the UID turning active and | 
 | 4781 |             // activity being resumed. The proper fix is very risky, so we temporary add | 
 | 4782 |             // some polling which should happen pretty rarely anyway as the race is hard | 
 | 4783 |             // to hit. | 
| Eino-Ville Talvala | 32b8c20 | 2018-08-20 10:27:58 -0700 | [diff] [blame] | 4784 |             active = mActiveUids.find(uid) != mActiveUids.end(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4785 |             if (!active) active = am.isUidActive(uid, toString16(callingPackage)); | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 4786 |             if (active) { | 
 | 4787 |                 break; | 
 | 4788 |             } | 
 | 4789 |             if (startTimeMillis <= 0) { | 
 | 4790 |                 startTimeMillis = uptimeMillis(); | 
 | 4791 |             } | 
 | 4792 |             int64_t ellapsedTimeMillis = uptimeMillis() - startTimeMillis; | 
| Eino-Ville Talvala | 32b8c20 | 2018-08-20 10:27:58 -0700 | [diff] [blame] | 4793 |             int64_t remainingTimeMillis = kPollUidActiveTimeoutTotalMillis - ellapsedTimeMillis; | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 4794 |             if (remainingTimeMillis <= 0) { | 
 | 4795 |                 break; | 
 | 4796 |             } | 
| Eino-Ville Talvala | 32b8c20 | 2018-08-20 10:27:58 -0700 | [diff] [blame] | 4797 |             remainingTimeMillis = std::min(kPollUidActiveTimeoutMillis, remainingTimeMillis); | 
 | 4798 |  | 
 | 4799 |             mUidLock.unlock(); | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 4800 |             usleep(remainingTimeMillis * 1000); | 
| Eino-Ville Talvala | 32b8c20 | 2018-08-20 10:27:58 -0700 | [diff] [blame] | 4801 |             mUidLock.lock(); | 
| Svet Ganov | 94ec46f | 2018-06-08 15:03:46 -0700 | [diff] [blame] | 4802 |         } while (true); | 
 | 4803 |  | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4804 |         if (active) { | 
 | 4805 |             // Now that we found out the UID is actually active, cache that | 
 | 4806 |             mActiveUids.insert(uid); | 
 | 4807 |         } | 
 | 4808 |     } | 
 | 4809 |     return active; | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4810 | } | 
 | 4811 |  | 
| Varun Shah | b42f1eb | 2019-04-16 14:45:13 -0700 | [diff] [blame] | 4812 | int32_t CameraService::UidPolicy::getProcState(uid_t uid) { | 
 | 4813 |     Mutex::Autolock _l(mUidLock); | 
 | 4814 |     return getProcStateLocked(uid); | 
 | 4815 | } | 
 | 4816 |  | 
 | 4817 | int32_t CameraService::UidPolicy::getProcStateLocked(uid_t uid) { | 
 | 4818 |     int32_t procState = ActivityManager::PROCESS_STATE_UNKNOWN; | 
 | 4819 |     if (mMonitoredUids.find(uid) != mMonitoredUids.end()) { | 
| Austin Borger | 6557768 | 2022-02-17 00:25:43 +0000 | [diff] [blame] | 4820 |         procState = mMonitoredUids[uid].procState; | 
| Varun Shah | b42f1eb | 2019-04-16 14:45:13 -0700 | [diff] [blame] | 4821 |     } | 
 | 4822 |     return procState; | 
 | 4823 | } | 
 | 4824 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4825 | void CameraService::UidPolicy::addOverrideUid(uid_t uid, | 
 | 4826 |         const std::string &callingPackage, bool active) { | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4827 |     updateOverrideUid(uid, callingPackage, active, true); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4828 | } | 
 | 4829 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4830 | void CameraService::UidPolicy::removeOverrideUid(uid_t uid, const std::string &callingPackage) { | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4831 |     updateOverrideUid(uid, callingPackage, false, false); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4832 | } | 
 | 4833 |  | 
| Eino-Ville Talvala | 8abec3f | 2018-03-20 11:07:00 -0700 | [diff] [blame] | 4834 | void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) { | 
 | 4835 |     Mutex::Autolock _l(mUidLock); | 
 | 4836 |     ALOGV("UidPolicy: ActivityManager has died"); | 
 | 4837 |     mRegistered = false; | 
 | 4838 |     mActiveUids.clear(); | 
 | 4839 | } | 
 | 4840 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4841 | void CameraService::UidPolicy::updateOverrideUid(uid_t uid, const std::string &callingPackage, | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4842 |         bool active, bool insert) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4843 |     bool wasActive = false; | 
 | 4844 |     bool isActive = false; | 
 | 4845 |     { | 
 | 4846 |         Mutex::Autolock _l(mUidLock); | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4847 |         wasActive = isUidActiveLocked(uid, callingPackage); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4848 |         mOverrideUids.erase(uid); | 
 | 4849 |         if (insert) { | 
 | 4850 |             mOverrideUids.insert(std::pair<uid_t, bool>(uid, active)); | 
 | 4851 |         } | 
| Svet Ganov | 7b4ab78 | 2018-03-25 12:48:10 -0700 | [diff] [blame] | 4852 |         isActive = isUidActiveLocked(uid, callingPackage); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 4853 |     } | 
 | 4854 |     if (wasActive != isActive && !isActive) { | 
 | 4855 |         sp<CameraService> service = mService.promote(); | 
 | 4856 |         if (service != nullptr) { | 
 | 4857 |             service->blockClientsForUid(uid); | 
 | 4858 |         } | 
 | 4859 |     } | 
 | 4860 | } | 
 | 4861 |  | 
 | 4862 | // ---------------------------------------------------------------------------- | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4863 | //                  SensorPrivacyPolicy | 
 | 4864 | // ---------------------------------------------------------------------------- | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4865 |  | 
 | 4866 | void CameraService::SensorPrivacyPolicy::registerWithSensorPrivacyManager() | 
 | 4867 | { | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4868 |     Mutex::Autolock _l(mSensorPrivacyLock); | 
 | 4869 |     if (mRegistered) { | 
 | 4870 |         return; | 
 | 4871 |     } | 
| Evan Severson | 09ab400 | 2021-02-10 14:15:19 -0800 | [diff] [blame] | 4872 |     hasCameraPrivacyFeature(); // Called so the result is cached | 
| Steven Moreland | 3cf6717 | 2020-01-29 11:44:22 -0800 | [diff] [blame] | 4873 |     mSpm.addSensorPrivacyListener(this); | 
| Charles Chen | f075f08 | 2024-03-04 23:32:55 +0000 | [diff] [blame] | 4874 |     if (isAutomotiveDevice()) { | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4875 |         mSpm.addToggleSensorPrivacyListener(this); | 
 | 4876 |     } | 
| Steven Moreland | 3cf6717 | 2020-01-29 11:44:22 -0800 | [diff] [blame] | 4877 |     mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled(); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4878 |     if (flags::camera_privacy_allowlist()) { | 
 | 4879 |         mCameraPrivacyState = mSpm.getToggleSensorPrivacyState( | 
 | 4880 |                 SensorPrivacyManager::TOGGLE_TYPE_SOFTWARE, | 
 | 4881 |                 SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); | 
 | 4882 |     } | 
| Steven Moreland | 3cf6717 | 2020-01-29 11:44:22 -0800 | [diff] [blame] | 4883 |     status_t res = mSpm.linkToDeath(this); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4884 |     if (res == OK) { | 
 | 4885 |         mRegistered = true; | 
 | 4886 |         ALOGV("SensorPrivacyPolicy: Registered with SensorPrivacyManager"); | 
 | 4887 |     } | 
 | 4888 | } | 
 | 4889 |  | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4890 | void CameraService::SensorPrivacyPolicy::onServiceRegistration(const String16& name, | 
 | 4891 |                                                                const sp<IBinder>&) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4892 |     if (name != toString16(kSensorPrivacyServiceName)) { | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4893 |         return; | 
 | 4894 |     } | 
 | 4895 |  | 
 | 4896 |     registerWithSensorPrivacyManager(); | 
 | 4897 | } | 
 | 4898 |  | 
 | 4899 | void CameraService::SensorPrivacyPolicy::registerSelf() { | 
 | 4900 |     // Use checkservice to see if the sensor_privacy service is available | 
 | 4901 |     // If service is not available then register for notification | 
 | 4902 |     sp<IServiceManager> sm = defaultServiceManager(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4903 |     sp<IBinder> binder = sm->checkService(toString16(kSensorPrivacyServiceName)); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4904 |     if (!binder) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 4905 |         sm->registerForNotifications(toString16(kSensorPrivacyServiceName),this); | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4906 |     } else { | 
 | 4907 |         registerWithSensorPrivacyManager(); | 
 | 4908 |     } | 
 | 4909 | } | 
 | 4910 |  | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4911 | void CameraService::SensorPrivacyPolicy::unregisterSelf() { | 
 | 4912 |     Mutex::Autolock _l(mSensorPrivacyLock); | 
| Steven Moreland | 3cf6717 | 2020-01-29 11:44:22 -0800 | [diff] [blame] | 4913 |     mSpm.removeSensorPrivacyListener(this); | 
| Charles Chen | f075f08 | 2024-03-04 23:32:55 +0000 | [diff] [blame] | 4914 |     if (isAutomotiveDevice()) { | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4915 |         mSpm.removeToggleSensorPrivacyListener(this); | 
 | 4916 |     } | 
| Steven Moreland | 3cf6717 | 2020-01-29 11:44:22 -0800 | [diff] [blame] | 4917 |     mSpm.unlinkToDeath(this); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4918 |     mRegistered = false; | 
 | 4919 |     ALOGV("SensorPrivacyPolicy: Unregistered with SensorPrivacyManager"); | 
 | 4920 | } | 
 | 4921 |  | 
 | 4922 | bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() { | 
| Jyoti Bhayana | cde601c | 2022-12-07 10:03:42 -0800 | [diff] [blame] | 4923 |     if (!mRegistered) { | 
 | 4924 |       registerWithSensorPrivacyManager(); | 
 | 4925 |     } | 
 | 4926 |  | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4927 |     Mutex::Autolock _l(mSensorPrivacyLock); | 
 | 4928 |     return mSensorPrivacyEnabled; | 
 | 4929 | } | 
 | 4930 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4931 | int CameraService::SensorPrivacyPolicy::getCameraPrivacyState() { | 
 | 4932 |     if (!mRegistered) { | 
 | 4933 |         registerWithSensorPrivacyManager(); | 
 | 4934 |     } | 
 | 4935 |  | 
 | 4936 |     Mutex::Autolock _l(mSensorPrivacyLock); | 
 | 4937 |     return mCameraPrivacyState; | 
 | 4938 | } | 
 | 4939 |  | 
| Evan Severson | d0b6992 | 2022-01-27 10:47:34 -0800 | [diff] [blame] | 4940 | bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled() { | 
| Evan Severson | 09ab400 | 2021-02-10 14:15:19 -0800 | [diff] [blame] | 4941 |     if (!hasCameraPrivacyFeature()) { | 
 | 4942 |         return false; | 
 | 4943 |     } | 
| Evan Severson | d0b6992 | 2022-01-27 10:47:34 -0800 | [diff] [blame] | 4944 |     return mSpm.isToggleSensorPrivacyEnabled(SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); | 
| Evan Severson | 09ab400 | 2021-02-10 14:15:19 -0800 | [diff] [blame] | 4945 | } | 
 | 4946 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4947 | bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled(const String16& packageName) { | 
 | 4948 |     if (!hasCameraPrivacyFeature()) { | 
| Jyoti Bhayana | 5882b03 | 2024-04-26 11:18:58 -0700 | [diff] [blame] | 4949 |         return false; | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4950 |     } | 
 | 4951 |     return mSpm.isCameraPrivacyEnabled(packageName); | 
 | 4952 | } | 
 | 4953 |  | 
| Evan Severson | d0b6992 | 2022-01-27 10:47:34 -0800 | [diff] [blame] | 4954 | binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged( | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4955 |     int toggleType, int sensor, bool enabled) { | 
 | 4956 |     if ((toggleType == SensorPrivacyManager::TOGGLE_TYPE_UNKNOWN) | 
 | 4957 |             && (sensor == SensorPrivacyManager::TOGGLE_SENSOR_UNKNOWN)) { | 
 | 4958 |         { | 
 | 4959 |             Mutex::Autolock _l(mSensorPrivacyLock); | 
 | 4960 |             mSensorPrivacyEnabled = enabled; | 
 | 4961 |         } | 
 | 4962 |         // if sensor privacy is enabled then block all clients from accessing the camera | 
 | 4963 |         if (enabled) { | 
 | 4964 |             sp<CameraService> service = mService.promote(); | 
 | 4965 |             if (service != nullptr) { | 
 | 4966 |                 service->blockAllClients(); | 
 | 4967 |             } | 
 | 4968 |         } | 
 | 4969 |     } | 
 | 4970 |     return binder::Status::ok(); | 
 | 4971 | } | 
 | 4972 |  | 
 | 4973 | binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyStateChanged( | 
 | 4974 |     int, int sensor, int state) { | 
 | 4975 |     if (!flags::camera_privacy_allowlist() | 
 | 4976 |             || (sensor != SensorPrivacyManager::TOGGLE_SENSOR_CAMERA)) { | 
 | 4977 |         return binder::Status::ok(); | 
 | 4978 |     } | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4979 |     { | 
 | 4980 |         Mutex::Autolock _l(mSensorPrivacyLock); | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4981 |         mCameraPrivacyState = state; | 
 | 4982 |     } | 
 | 4983 |     sp<CameraService> service = mService.promote(); | 
 | 4984 |     if (!service) { | 
 | 4985 |         return binder::Status::ok(); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4986 |     } | 
 | 4987 |     // if sensor privacy is enabled then block all clients from accessing the camera | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4988 |     if (state == SensorPrivacyManager::ENABLED) { | 
 | 4989 |         service->blockAllClients(); | 
| Jyoti Bhayana | 54a4b00 | 2024-02-27 15:36:09 -0800 | [diff] [blame] | 4990 |     } else if (state == SensorPrivacyManager::ENABLED_EXCEPT_ALLOWLISTED_APPS) { | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 4991 |         service->blockPrivacyEnabledClients(); | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 4992 |     } | 
 | 4993 |     return binder::Status::ok(); | 
 | 4994 | } | 
 | 4995 |  | 
 | 4996 | void CameraService::SensorPrivacyPolicy::binderDied(const wp<IBinder>& /*who*/) { | 
 | 4997 |     Mutex::Autolock _l(mSensorPrivacyLock); | 
 | 4998 |     ALOGV("SensorPrivacyPolicy: SensorPrivacyManager has died"); | 
 | 4999 |     mRegistered = false; | 
 | 5000 | } | 
 | 5001 |  | 
| Evan Severson | 09ab400 | 2021-02-10 14:15:19 -0800 | [diff] [blame] | 5002 | bool CameraService::SensorPrivacyPolicy::hasCameraPrivacyFeature() { | 
| Evan Severson | d0b6992 | 2022-01-27 10:47:34 -0800 | [diff] [blame] | 5003 |     bool supportsSoftwareToggle = mSpm.supportsSensorToggle( | 
 | 5004 |             SensorPrivacyManager::TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); | 
 | 5005 |     bool supportsHardwareToggle = mSpm.supportsSensorToggle( | 
 | 5006 |             SensorPrivacyManager::TOGGLE_TYPE_HARDWARE, SensorPrivacyManager::TOGGLE_SENSOR_CAMERA); | 
 | 5007 |     return supportsSoftwareToggle || supportsHardwareToggle; | 
| Evan Severson | 09ab400 | 2021-02-10 14:15:19 -0800 | [diff] [blame] | 5008 | } | 
 | 5009 |  | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 5010 | // ---------------------------------------------------------------------------- | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5011 | //                  CameraState | 
 | 5012 | // ---------------------------------------------------------------------------- | 
 | 5013 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5014 | CameraService::CameraState::CameraState(const std::string& id, int cost, | 
 | 5015 |         const std::set<std::string>& conflicting, SystemCameraKind systemCameraKind, | 
| Shuzhen Wang | 403af6d | 2021-12-21 00:08:43 +0000 | [diff] [blame] | 5016 |         const std::vector<std::string>& physicalCameras) : mId(id), | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 5017 |         mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting), | 
| Shuzhen Wang | 403af6d | 2021-12-21 00:08:43 +0000 | [diff] [blame] | 5018 |         mSystemCameraKind(systemCameraKind), mPhysicalCameras(physicalCameras) {} | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5019 |  | 
 | 5020 | CameraService::CameraState::~CameraState() {} | 
 | 5021 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5022 | CameraService::StatusInternal CameraService::CameraState::getStatus() const { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5023 |     Mutex::Autolock lock(mStatusLock); | 
 | 5024 |     return mStatus; | 
 | 5025 | } | 
 | 5026 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5027 | std::vector<std::string> CameraService::CameraState::getUnavailablePhysicalIds() const { | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5028 |     Mutex::Autolock lock(mStatusLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5029 |     std::vector<std::string> res(mUnavailablePhysicalIds.begin(), mUnavailablePhysicalIds.end()); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5030 |     return res; | 
 | 5031 | } | 
 | 5032 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5033 | CameraParameters CameraService::CameraState::getShimParams() const { | 
 | 5034 |     return mShimParams; | 
 | 5035 | } | 
 | 5036 |  | 
 | 5037 | void CameraService::CameraState::setShimParams(const CameraParameters& params) { | 
 | 5038 |     mShimParams = params; | 
 | 5039 | } | 
 | 5040 |  | 
 | 5041 | int CameraService::CameraState::getCost() const { | 
 | 5042 |     return mCost; | 
 | 5043 | } | 
 | 5044 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5045 | std::set<std::string> CameraService::CameraState::getConflicting() const { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5046 |     return mConflicting; | 
 | 5047 | } | 
 | 5048 |  | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 5049 | SystemCameraKind CameraService::CameraState::getSystemCameraKind() const { | 
 | 5050 |     return mSystemCameraKind; | 
 | 5051 | } | 
 | 5052 |  | 
| Shuzhen Wang | 403af6d | 2021-12-21 00:08:43 +0000 | [diff] [blame] | 5053 | bool CameraService::CameraState::containsPhysicalCamera(const std::string& physicalCameraId) const { | 
 | 5054 |     return std::find(mPhysicalCameras.begin(), mPhysicalCameras.end(), physicalCameraId) | 
 | 5055 |             != mPhysicalCameras.end(); | 
 | 5056 | } | 
 | 5057 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5058 | bool CameraService::CameraState::addUnavailablePhysicalId(const std::string& physicalId) { | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5059 |     Mutex::Autolock lock(mStatusLock); | 
 | 5060 |     auto result = mUnavailablePhysicalIds.insert(physicalId); | 
 | 5061 |     return result.second; | 
 | 5062 | } | 
 | 5063 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5064 | bool CameraService::CameraState::removeUnavailablePhysicalId(const std::string& physicalId) { | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5065 |     Mutex::Autolock lock(mStatusLock); | 
 | 5066 |     auto count = mUnavailablePhysicalIds.erase(physicalId); | 
 | 5067 |     return count > 0; | 
 | 5068 | } | 
 | 5069 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5070 | void CameraService::CameraState::setClientPackage(const std::string& clientPackage) { | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 5071 |     Mutex::Autolock lock(mStatusLock); | 
 | 5072 |     mClientPackage = clientPackage; | 
 | 5073 | } | 
 | 5074 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5075 | std::string CameraService::CameraState::getClientPackage() const { | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 5076 |     Mutex::Autolock lock(mStatusLock); | 
 | 5077 |     return mClientPackage; | 
 | 5078 | } | 
 | 5079 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5080 | // ---------------------------------------------------------------------------- | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5081 | //                  ClientEventListener | 
 | 5082 | // ---------------------------------------------------------------------------- | 
 | 5083 |  | 
 | 5084 | void CameraService::ClientEventListener::onClientAdded( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5085 |         const resource_policy::ClientDescriptor<std::string, | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5086 |         sp<CameraService::BasicClient>>& descriptor) { | 
| Chih-Hung Hsieh | 5404ee1 | 2016-08-09 14:25:53 -0700 | [diff] [blame] | 5087 |     const auto& basicClient = descriptor.getValue(); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5088 |     if (basicClient.get() != nullptr) { | 
 | 5089 |         BatteryNotifier& notifier(BatteryNotifier::getInstance()); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5090 |         notifier.noteStartCamera(toString8(descriptor.getKey()), | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5091 |                 static_cast<int>(basicClient->getClientUid())); | 
 | 5092 |     } | 
 | 5093 | } | 
 | 5094 |  | 
 | 5095 | void CameraService::ClientEventListener::onClientRemoved( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5096 |         const resource_policy::ClientDescriptor<std::string, | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5097 |         sp<CameraService::BasicClient>>& descriptor) { | 
| Chih-Hung Hsieh | 5404ee1 | 2016-08-09 14:25:53 -0700 | [diff] [blame] | 5098 |     const auto& basicClient = descriptor.getValue(); | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5099 |     if (basicClient.get() != nullptr) { | 
 | 5100 |         BatteryNotifier& notifier(BatteryNotifier::getInstance()); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5101 |         notifier.noteStopCamera(toString8(descriptor.getKey()), | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5102 |                 static_cast<int>(basicClient->getClientUid())); | 
 | 5103 |     } | 
 | 5104 | } | 
 | 5105 |  | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5106 | // ---------------------------------------------------------------------------- | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5107 | //                  CameraClientManager | 
 | 5108 | // ---------------------------------------------------------------------------- | 
 | 5109 |  | 
| Ruben Brunk | 99e6971 | 2015-05-26 17:25:07 -0700 | [diff] [blame] | 5110 | CameraService::CameraClientManager::CameraClientManager() { | 
 | 5111 |     setListener(std::make_shared<ClientEventListener>()); | 
 | 5112 | } | 
 | 5113 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5114 | CameraService::CameraClientManager::~CameraClientManager() {} | 
 | 5115 |  | 
 | 5116 | sp<CameraService::BasicClient> CameraService::CameraClientManager::getCameraClient( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5117 |         const std::string& id) const { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5118 |     auto descriptor = get(id); | 
 | 5119 |     if (descriptor == nullptr) { | 
 | 5120 |         return sp<BasicClient>{nullptr}; | 
 | 5121 |     } | 
 | 5122 |     return descriptor->getValue(); | 
 | 5123 | } | 
 | 5124 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5125 | std::string CameraService::CameraClientManager::toString() const { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5126 |     auto all = getAll(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5127 |     std::ostringstream ret; | 
 | 5128 |     ret << "["; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5129 |     bool hasAny = false; | 
 | 5130 |     for (auto& i : all) { | 
 | 5131 |         hasAny = true; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5132 |         std::string key = i->getKey(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5133 |         int32_t cost = i->getCost(); | 
 | 5134 |         int32_t pid = i->getOwnerId(); | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 5135 |         int32_t score = i->getPriority().getScore(); | 
 | 5136 |         int32_t state = i->getPriority().getState(); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5137 |         auto conflicting = i->getConflicting(); | 
 | 5138 |         auto clientSp = i->getValue(); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5139 |         std::string packageName; | 
| Eino-Ville Talvala | 022f0cb | 2015-05-19 16:31:16 -0700 | [diff] [blame] | 5140 |         userid_t clientUserId = 0; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5141 |         if (clientSp.get() != nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5142 |             packageName = clientSp->getPackageName(); | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 5143 |             uid_t clientUid = clientSp->getClientUid(); | 
 | 5144 |             clientUserId = multiuser_get_user_id(clientUid); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5145 |         } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5146 |         ret << fmt::sprintf("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %" | 
 | 5147 |                 PRId32 ", State: %" PRId32, key.c_str(), cost, pid, score, state); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5148 |  | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 5149 |         if (clientSp.get() != nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5150 |             ret << fmt::sprintf("User Id: %d, ", clientUserId); | 
| Ruben Brunk | 6267b53 | 2015-04-30 17:44:07 -0700 | [diff] [blame] | 5151 |         } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5152 |         if (packageName.size() != 0) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5153 |             ret << fmt::sprintf("Client Package Name: %s", packageName.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5154 |         } | 
 | 5155 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5156 |         ret << ", Conflicting Client Devices: {"; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5157 |         for (auto& j : conflicting) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5158 |             ret << fmt::sprintf("%s, ", j.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5159 |         } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5160 |         ret << "})"; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5161 |     } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5162 |     if (hasAny) ret << "\n"; | 
 | 5163 |     ret << "]\n"; | 
 | 5164 |     return std::move(ret.str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5165 | } | 
 | 5166 |  | 
 | 5167 | CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5168 |         const std::string& key, const sp<BasicClient>& value, int32_t cost, | 
 | 5169 |         const std::set<std::string>& conflictingKeys, int32_t score, int32_t ownerId, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 5170 |         int32_t state, int32_t oomScoreOffset, bool systemNativeClient) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5171 |  | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 5172 |     int32_t score_adj = systemNativeClient ? kSystemNativeClientScore : score; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5173 |     int32_t state_adj = systemNativeClient ? kSystemNativeClientState : state; | 
| Jayant Chowdhary | c578a50 | 2019-05-08 10:57:54 -0700 | [diff] [blame] | 5174 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5175 |     return std::make_shared<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>>( | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 5176 |             key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, | 
 | 5177 |             systemNativeClient, oomScoreOffset); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5178 | } | 
 | 5179 |  | 
 | 5180 | CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor( | 
| Jayant Chowdhary | 8eb8d91 | 2021-05-18 17:41:56 +0000 | [diff] [blame] | 5181 |         const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial, | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 5182 |         int32_t oomScoreOffset, bool systemNativeClient) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5183 |     return makeClientDescriptor(partial->getKey(), value, partial->getCost(), | 
| Emilian Peev | 8131a26 | 2017-02-01 12:33:43 +0000 | [diff] [blame] | 5184 |             partial->getConflicting(), partial->getPriority().getScore(), | 
| Jayant Chowdhary | eb0169f | 2022-01-31 00:00:02 -0800 | [diff] [blame] | 5185 |             partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset, | 
 | 5186 |             systemNativeClient); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5187 | } | 
 | 5188 |  | 
 | 5189 | // ---------------------------------------------------------------------------- | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 5190 | //                  InjectionStatusListener | 
 | 5191 | // ---------------------------------------------------------------------------- | 
 | 5192 |  | 
 | 5193 | void CameraService::InjectionStatusListener::addListener( | 
 | 5194 |         const sp<ICameraInjectionCallback>& callback) { | 
 | 5195 |     Mutex::Autolock lock(mListenerLock); | 
 | 5196 |     if (mCameraInjectionCallback) return; | 
 | 5197 |     status_t res = IInterface::asBinder(callback)->linkToDeath(this); | 
 | 5198 |     if (res == OK) { | 
 | 5199 |         mCameraInjectionCallback = callback; | 
 | 5200 |     } | 
 | 5201 | } | 
 | 5202 |  | 
 | 5203 | void CameraService::InjectionStatusListener::removeListener() { | 
 | 5204 |     Mutex::Autolock lock(mListenerLock); | 
 | 5205 |     if (mCameraInjectionCallback == nullptr) { | 
 | 5206 |         ALOGW("InjectionStatusListener: mCameraInjectionCallback == nullptr"); | 
 | 5207 |         return; | 
 | 5208 |     } | 
 | 5209 |     IInterface::asBinder(mCameraInjectionCallback)->unlinkToDeath(this); | 
 | 5210 |     mCameraInjectionCallback = nullptr; | 
 | 5211 | } | 
 | 5212 |  | 
 | 5213 | void CameraService::InjectionStatusListener::notifyInjectionError( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5214 |         const std::string &injectedCamId, status_t err) { | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 5215 |     if (mCameraInjectionCallback == nullptr) { | 
 | 5216 |         ALOGW("InjectionStatusListener: mCameraInjectionCallback == nullptr"); | 
 | 5217 |         return; | 
 | 5218 |     } | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5219 |  | 
 | 5220 |     switch (err) { | 
 | 5221 |         case -ENODEV: | 
 | 5222 |             mCameraInjectionCallback->onInjectionError( | 
 | 5223 |                     ICameraInjectionCallback::ERROR_INJECTION_SESSION); | 
 | 5224 |             ALOGE("No camera device with ID \"%s\" currently available!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5225 |                     injectedCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5226 |             break; | 
 | 5227 |         case -EBUSY: | 
 | 5228 |             mCameraInjectionCallback->onInjectionError( | 
 | 5229 |                     ICameraInjectionCallback::ERROR_INJECTION_SESSION); | 
 | 5230 |             ALOGE("Higher-priority client using camera, ID \"%s\" currently unavailable!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5231 |                     injectedCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5232 |             break; | 
 | 5233 |         case DEAD_OBJECT: | 
 | 5234 |             mCameraInjectionCallback->onInjectionError( | 
 | 5235 |                     ICameraInjectionCallback::ERROR_INJECTION_SESSION); | 
 | 5236 |             ALOGE("Camera ID \"%s\" object is dead!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5237 |                     injectedCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5238 |             break; | 
 | 5239 |         case INVALID_OPERATION: | 
 | 5240 |             mCameraInjectionCallback->onInjectionError( | 
 | 5241 |                     ICameraInjectionCallback::ERROR_INJECTION_SESSION); | 
 | 5242 |             ALOGE("Camera ID \"%s\" encountered an operating or internal error!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5243 |                     injectedCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5244 |             break; | 
 | 5245 |         case UNKNOWN_TRANSACTION: | 
 | 5246 |             mCameraInjectionCallback->onInjectionError( | 
 | 5247 |                     ICameraInjectionCallback::ERROR_INJECTION_UNSUPPORTED); | 
 | 5248 |             ALOGE("Camera ID \"%s\" method doesn't support!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5249 |                     injectedCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5250 |             break; | 
 | 5251 |         default: | 
 | 5252 |             mCameraInjectionCallback->onInjectionError( | 
 | 5253 |                     ICameraInjectionCallback::ERROR_INJECTION_INVALID_ERROR); | 
 | 5254 |             ALOGE("Unexpected error %s (%d) opening camera \"%s\"!", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5255 |                     strerror(-err), err, injectedCamId.c_str()); | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5256 |     } | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 5257 | } | 
 | 5258 |  | 
 | 5259 | void CameraService::InjectionStatusListener::binderDied( | 
 | 5260 |         const wp<IBinder>& /*who*/) { | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 5261 |     ALOGV("InjectionStatusListener: ICameraInjectionCallback has died"); | 
 | 5262 |     auto parent = mParent.promote(); | 
 | 5263 |     if (parent != nullptr) { | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5264 |         auto clientDescriptor = parent->mActiveClientManager.get(parent->mInjectionInternalCamId); | 
 | 5265 |         if (clientDescriptor != nullptr) { | 
 | 5266 |             BasicClient* baseClientPtr = clientDescriptor->getValue().get(); | 
 | 5267 |             baseClientPtr->stopInjection(); | 
 | 5268 |         } | 
| Cliff Wu | 3b26818 | 2021-07-06 15:44:43 +0800 | [diff] [blame] | 5269 |         parent->clearInjectionParameters(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 5270 |     } | 
 | 5271 | } | 
 | 5272 |  | 
 | 5273 | // ---------------------------------------------------------------------------- | 
 | 5274 | //                  CameraInjectionSession | 
 | 5275 | // ---------------------------------------------------------------------------- | 
 | 5276 |  | 
 | 5277 | binder::Status CameraService::CameraInjectionSession::stopInjection() { | 
 | 5278 |     Mutex::Autolock lock(mInjectionSessionLock); | 
 | 5279 |     auto parent = mParent.promote(); | 
 | 5280 |     if (parent == nullptr) { | 
 | 5281 |         ALOGE("CameraInjectionSession: Parent is gone"); | 
 | 5282 |         return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_SERVICE, | 
 | 5283 |                 "Camera service encountered error"); | 
 | 5284 |     } | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5285 |  | 
 | 5286 |     status_t res = NO_ERROR; | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 5287 |     auto clientDescriptor = parent->mActiveClientManager.get(parent->mInjectionInternalCamId); | 
 | 5288 |     if (clientDescriptor != nullptr) { | 
 | 5289 |         BasicClient* baseClientPtr = clientDescriptor->getValue().get(); | 
 | 5290 |         res = baseClientPtr->stopInjection(); | 
 | 5291 |         if (res != OK) { | 
 | 5292 |             ALOGE("CameraInjectionSession: Failed to stop the injection camera!" | 
 | 5293 |                 " ret != NO_ERROR: %d", res); | 
 | 5294 |             return STATUS_ERROR(ICameraInjectionCallback::ERROR_INJECTION_SESSION, | 
 | 5295 |                 "Camera session encountered error"); | 
 | 5296 |         } | 
 | 5297 |     } | 
| Cliff Wu | 3b26818 | 2021-07-06 15:44:43 +0800 | [diff] [blame] | 5298 |     parent->clearInjectionParameters(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 5299 |     return binder::Status::ok(); | 
 | 5300 | } | 
 | 5301 |  | 
 | 5302 | // ---------------------------------------------------------------------------- | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 5303 |  | 
 | 5304 | static const int kDumpLockRetries = 50; | 
 | 5305 | static const int kDumpLockSleep = 60000; | 
 | 5306 |  | 
 | 5307 | static bool tryLock(Mutex& mutex) | 
 | 5308 | { | 
 | 5309 |     bool locked = false; | 
 | 5310 |     for (int i = 0; i < kDumpLockRetries; ++i) { | 
 | 5311 |         if (mutex.tryLock() == NO_ERROR) { | 
 | 5312 |             locked = true; | 
 | 5313 |             break; | 
 | 5314 |         } | 
 | 5315 |         usleep(kDumpLockSleep); | 
 | 5316 |     } | 
 | 5317 |     return locked; | 
 | 5318 | } | 
 | 5319 |  | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5320 | void CameraService::cacheDump() { | 
 | 5321 |     if (mMemFd != -1) { | 
 | 5322 |         const Vector<String16> args; | 
 | 5323 |         ATRACE_CALL(); | 
 | 5324 |         // Acquiring service lock here will avoid the deadlock since | 
 | 5325 |         // cacheDump will not be called during the second disconnect. | 
 | 5326 |         Mutex::Autolock lock(mServiceLock); | 
 | 5327 |  | 
 | 5328 |         Mutex::Autolock l(mCameraStatesLock); | 
 | 5329 |         // Start collecting the info for open sessions and store it in temp file. | 
 | 5330 |         for (const auto& state : mCameraStates) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5331 |             std::string cameraId = state.first; | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5332 |             auto clientDescriptor = mActiveClientManager.get(cameraId); | 
 | 5333 |             if (clientDescriptor != nullptr) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5334 |                 dprintf(mMemFd, "== Camera device %s dynamic info: ==\n", cameraId.c_str()); | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5335 |                 // Log the current open session info before device is disconnected. | 
 | 5336 |                 dumpOpenSessionClientLogs(mMemFd, args, cameraId); | 
 | 5337 |             } | 
 | 5338 |         } | 
 | 5339 |     } | 
 | 5340 | } | 
 | 5341 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 5342 | status_t CameraService::dump(int fd, const Vector<String16>& args) { | 
| Eino-Ville Talvala | a84bbe6 | 2015-09-08 17:59:17 -0700 | [diff] [blame] | 5343 |     ATRACE_CALL(); | 
 | 5344 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5345 |     if (checkCallingPermission(toString16(sDumpPermission)) == false) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5346 |         dprintf(fd, "Permission Denial: can't dump CameraService from pid=%d, uid=%d\n", | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 5347 |                 getCallingPid(), | 
 | 5348 |                 getCallingUid()); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5349 |         return NO_ERROR; | 
 | 5350 |     } | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5351 |     bool locked = tryLock(mServiceLock); | 
 | 5352 |     // failed to lock - CameraService is probably deadlocked | 
 | 5353 |     if (!locked) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5354 |         dprintf(fd, "!! CameraService may be deadlocked !!\n"); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5355 |     } | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5356 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5357 |     if (!mInitialized) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5358 |         dprintf(fd, "!! No camera HAL available !!\n"); | 
| Ruben Brunk | f81648e | 2014-04-17 16:14:57 -0700 | [diff] [blame] | 5359 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5360 |         // Dump event log for error information | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5361 |         dumpEventLog(fd); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5362 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5363 |         if (locked) mServiceLock.unlock(); | 
 | 5364 |         return NO_ERROR; | 
 | 5365 |     } | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5366 |     dprintf(fd, "\n== Service global info: ==\n\n"); | 
 | 5367 |     dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 5368 |     dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size()); | 
| Jayant Chowdhary | 847947d | 2019-08-30 18:02:59 -0700 | [diff] [blame] | 5369 |     dprintf(fd, "Number of public camera devices visible to API1: %zu\n", | 
 | 5370 |             mNormalDeviceIdsWithoutSystemCamera.size()); | 
| Yin-Chia Yeh | c3e9d6f | 2018-02-06 10:56:32 -0800 | [diff] [blame] | 5371 |     for (size_t i = 0; i < mNormalDeviceIds.size(); i++) { | 
 | 5372 |         dprintf(fd, "    Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str()); | 
 | 5373 |     } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5374 |     std::string activeClientString = mActiveClientManager.toString(); | 
 | 5375 |     dprintf(fd, "Active Camera Clients:\n%s", activeClientString.c_str()); | 
 | 5376 |     dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).c_str()); | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 5377 |     if (mStreamUseCaseOverrides.size() > 0) { | 
 | 5378 |         dprintf(fd, "Active stream use case overrides:"); | 
 | 5379 |         for (int64_t useCaseOverride : mStreamUseCaseOverrides) { | 
 | 5380 |             dprintf(fd, " %" PRId64, useCaseOverride); | 
 | 5381 |         } | 
 | 5382 |         dprintf(fd, "\n"); | 
 | 5383 |     } | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5384 |  | 
 | 5385 |     dumpEventLog(fd); | 
 | 5386 |  | 
 | 5387 |     bool stateLocked = tryLock(mCameraStatesLock); | 
 | 5388 |     if (!stateLocked) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5389 |         dprintf(fd, "CameraStates in use, may be deadlocked\n"); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5390 |     } | 
 | 5391 |  | 
| Emilian Peev | bd8c503 | 2018-02-14 23:05:40 +0000 | [diff] [blame] | 5392 |     int argSize = args.size(); | 
 | 5393 |     for (int i = 0; i < argSize; i++) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5394 |         if (args[i] == toString16(TagMonitor::kMonitorOption)) { | 
| Emilian Peev | bd8c503 | 2018-02-14 23:05:40 +0000 | [diff] [blame] | 5395 |             if (i + 1 < argSize) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5396 |                 mMonitorTags = toStdString(args[i + 1]); | 
| Emilian Peev | bd8c503 | 2018-02-14 23:05:40 +0000 | [diff] [blame] | 5397 |             } | 
 | 5398 |             break; | 
 | 5399 |         } | 
 | 5400 |     } | 
 | 5401 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5402 |     for (auto& state : mCameraStates) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5403 |         const std::string &cameraId = state.first; | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5404 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5405 |         dprintf(fd, "== Camera device %s dynamic info: ==\n", cameraId.c_str()); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5406 |  | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5407 |         CameraParameters p = state.second->getShimParams(); | 
 | 5408 |         if (!p.isEmpty()) { | 
 | 5409 |             dprintf(fd, "  Camera1 API shim is using parameters:\n        "); | 
 | 5410 |             p.dump(fd, args); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5411 |         } | 
 | 5412 |  | 
 | 5413 |         auto clientDescriptor = mActiveClientManager.get(cameraId); | 
| Zhijun He | 2f140ed | 2017-02-08 09:57:23 -0800 | [diff] [blame] | 5414 |         if (clientDescriptor != nullptr) { | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5415 |             // log the current open session info | 
 | 5416 |             dumpOpenSessionClientLogs(fd, args, cameraId); | 
| Zhijun He | 2f140ed | 2017-02-08 09:57:23 -0800 | [diff] [blame] | 5417 |         } else { | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5418 |             dumpClosedSessionClientLogs(fd, cameraId); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5419 |         } | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5420 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5421 |     } | 
 | 5422 |  | 
 | 5423 |     if (stateLocked) mCameraStatesLock.unlock(); | 
 | 5424 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5425 |     if (locked) mServiceLock.unlock(); | 
 | 5426 |  | 
| Emilian Peev | f53f66e | 2017-04-11 14:29:43 +0100 | [diff] [blame] | 5427 |     mCameraProviderManager->dump(fd, args); | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5428 |  | 
 | 5429 |     dprintf(fd, "\n== Vendor tags: ==\n\n"); | 
 | 5430 |  | 
 | 5431 |     sp<VendorTagDescriptor> desc = VendorTagDescriptor::getGlobalVendorTagDescriptor(); | 
 | 5432 |     if (desc == NULL) { | 
| Emilian Peev | 71c73a2 | 2017-03-21 16:35:51 +0000 | [diff] [blame] | 5433 |         sp<VendorTagDescriptorCache> cache = | 
 | 5434 |                 VendorTagDescriptorCache::getGlobalVendorTagCache(); | 
 | 5435 |         if (cache == NULL) { | 
 | 5436 |             dprintf(fd, "No vendor tags.\n"); | 
 | 5437 |         } else { | 
 | 5438 |             cache->dump(fd, /*verbosity*/2, /*indentation*/2); | 
 | 5439 |         } | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5440 |     } else { | 
 | 5441 |         desc->dump(fd, /*verbosity*/2, /*indentation*/2); | 
 | 5442 |     } | 
 | 5443 |  | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5444 |     // Dump camera traces if there were any | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5445 |     dprintf(fd, "\n"); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 5446 |     camera3::CameraTraces::dump(fd); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5447 |  | 
 | 5448 |     // Process dump arguments, if any | 
 | 5449 |     int n = args.size(); | 
 | 5450 |     String16 verboseOption("-v"); | 
 | 5451 |     String16 unreachableOption("--unreachable"); | 
 | 5452 |     for (int i = 0; i < n; i++) { | 
 | 5453 |         if (args[i] == verboseOption) { | 
 | 5454 |             // change logging level | 
 | 5455 |             if (i + 1 >= n) continue; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5456 |             std::string levelStr = toStdString(args[i+1]); | 
 | 5457 |             int level = atoi(levelStr.c_str()); | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5458 |             dprintf(fd, "\nSetting log level to %d.\n", level); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5459 |             setLogLevel(level); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5460 |         } else if (args[i] == unreachableOption) { | 
 | 5461 |             // Dump memory analysis | 
 | 5462 |             // TODO - should limit be an argument parameter? | 
 | 5463 |             UnreachableMemoryInfo info; | 
 | 5464 |             bool success = GetUnreachableMemory(info, /*limit*/ 10000); | 
 | 5465 |             if (!success) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5466 |                 dprintf(fd, "\n== Unable to dump unreachable memory. " | 
 | 5467 |                         "Try disabling SELinux enforcement. ==\n"); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5468 |             } else { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5469 |                 dprintf(fd, "\n== Dumping unreachable memory: ==\n"); | 
| Eino-Ville Talvala | 8131418 | 2017-01-30 16:13:45 -0800 | [diff] [blame] | 5470 |                 std::string s = info.ToString(/*log_contents*/ true); | 
 | 5471 |                 write(fd, s.c_str(), s.size()); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 5472 |             } | 
 | 5473 |         } | 
 | 5474 |     } | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5475 |  | 
 | 5476 |     bool serviceLocked = tryLock(mServiceLock); | 
 | 5477 |  | 
 | 5478 |     // Dump info from previous open sessions. | 
 | 5479 |     // Reposition the offset to beginning of the file before reading | 
 | 5480 |  | 
 | 5481 |     if ((mMemFd >= 0) && (lseek(mMemFd, 0, SEEK_SET) != -1)) { | 
 | 5482 |         dprintf(fd, "\n**********Dumpsys from previous open session**********\n"); | 
 | 5483 |         ssize_t size_read; | 
 | 5484 |         char buf[4096]; | 
 | 5485 |         while ((size_read = read(mMemFd, buf, (sizeof(buf) - 1))) > 0) { | 
 | 5486 |             // Read data from file to a small buffer and write it to fd. | 
 | 5487 |             write(fd, buf, size_read); | 
 | 5488 |             if (size_read == -1) { | 
 | 5489 |                 ALOGE("%s: Error during reading the file: %s", __FUNCTION__, sFileName); | 
 | 5490 |                 break; | 
 | 5491 |             } | 
 | 5492 |         } | 
 | 5493 |         dprintf(fd, "\n**********End of Dumpsys from previous open session**********\n"); | 
 | 5494 |     } else { | 
 | 5495 |         ALOGE("%s: Error during reading the file: %s", __FUNCTION__, sFileName); | 
 | 5496 |     } | 
 | 5497 |  | 
 | 5498 |     if (serviceLocked) mServiceLock.unlock(); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 5499 |     return NO_ERROR; | 
 | 5500 | } | 
 | 5501 |  | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5502 | void CameraService::dumpOpenSessionClientLogs(int fd, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5503 |         const Vector<String16>& args, const std::string& cameraId) { | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5504 |     auto clientDescriptor = mActiveClientManager.get(cameraId); | 
| Rucha Katakwar | 71a0e05 | 2022-04-07 15:44:18 -0700 | [diff] [blame] | 5505 |     dprintf(fd, "  %s : Device %s is open. Client instance dump:\n", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5506 |             getFormattedCurrentTime().c_str(), | 
 | 5507 |             cameraId.c_str()); | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5508 |     dprintf(fd, "    Client priority score: %d state: %d\n", | 
 | 5509 |         clientDescriptor->getPriority().getScore(), | 
 | 5510 |         clientDescriptor->getPriority().getState()); | 
 | 5511 |     dprintf(fd, "    Client PID: %d\n", clientDescriptor->getOwnerId()); | 
 | 5512 |  | 
 | 5513 |     auto client = clientDescriptor->getValue(); | 
 | 5514 |     dprintf(fd, "    Client package: %s\n", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5515 |         client->getPackageName().c_str()); | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5516 |  | 
 | 5517 |     client->dumpClient(fd, args); | 
 | 5518 | } | 
 | 5519 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5520 | void CameraService::dumpClosedSessionClientLogs(int fd, const std::string& cameraId) { | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5521 |     dprintf(fd, "  Device %s is closed, no client instance\n", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5522 |                     cameraId.c_str()); | 
| Rucha Katakwar | df22307 | 2021-06-15 10:21:00 -0700 | [diff] [blame] | 5523 | } | 
 | 5524 |  | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5525 | void CameraService::dumpEventLog(int fd) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5526 |     dprintf(fd, "\n== Camera service events log (most recent at top): ==\n"); | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5527 |  | 
 | 5528 |     Mutex::Autolock l(mLogLock); | 
 | 5529 |     for (const auto& msg : mEventLog) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5530 |         dprintf(fd, "  %s\n", msg.c_str()); | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5531 |     } | 
 | 5532 |  | 
 | 5533 |     if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5534 |         dprintf(fd, "  ...\n"); | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5535 |     } else if (mEventLog.size() == 0) { | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5536 |         dprintf(fd, "  [no events yet]\n"); | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5537 |     } | 
| Eino-Ville Talvala | d00111e | 2017-01-31 11:59:12 -0800 | [diff] [blame] | 5538 |     dprintf(fd, "\n"); | 
| Eino-Ville Talvala | 1527f07 | 2015-04-07 15:55:31 -0700 | [diff] [blame] | 5539 | } | 
 | 5540 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5541 | void CameraService::cacheClientTagDumpIfNeeded(const std::string &cameraId, BasicClient* client) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 5542 |     Mutex::Autolock lock(mLogLock); | 
 | 5543 |     if (!isClientWatchedLocked(client)) { return; } | 
 | 5544 |  | 
 | 5545 |     std::vector<std::string> dumpVector; | 
 | 5546 |     client->dumpWatchedEventsToVector(dumpVector); | 
 | 5547 |  | 
 | 5548 |     if (dumpVector.empty()) { return; } | 
 | 5549 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5550 |     std::ostringstream dumpString; | 
| Avichal Rakesh | 882c08b | 2021-12-09 17:47:07 -0800 | [diff] [blame] | 5551 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5552 |     std::string currentTime = getFormattedCurrentTime(); | 
 | 5553 |     dumpString << "Cached @ "; | 
 | 5554 |     dumpString << currentTime; | 
 | 5555 |     dumpString << "\n"; // First line is the timestamp of when client is cached. | 
| Avichal Rakesh | 882c08b | 2021-12-09 17:47:07 -0800 | [diff] [blame] | 5556 |  | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 5557 |     size_t i = dumpVector.size(); | 
 | 5558 |  | 
 | 5559 |     // Store the string in reverse order (latest last) | 
 | 5560 |     while (i > 0) { | 
 | 5561 |          i--; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5562 |          dumpString << cameraId; | 
 | 5563 |          dumpString << ":"; | 
 | 5564 |          dumpString << client->getPackageName(); | 
 | 5565 |          dumpString << "  "; | 
 | 5566 |          dumpString << dumpVector[i]; // implicitly ends with '\n' | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 5567 |     } | 
 | 5568 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5569 |     mWatchedClientsDumpCache[client->getPackageName()] = dumpString.str(); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 5570 | } | 
 | 5571 |  | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5572 | void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) { | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 5573 |     Mutex::Autolock al(mTorchClientMapMutex); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5574 |     for (size_t i = 0; i < mTorchClientMap.size(); i++) { | 
 | 5575 |         if (mTorchClientMap[i] == who) { | 
 | 5576 |             // turn off the torch mode that was turned on by dead client | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5577 |             std::string cameraId = mTorchClientMap.keyAt(i); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 5578 |             status_t res = mFlashlight->setTorchMode(cameraId, false); | 
 | 5579 |             if (res) { | 
 | 5580 |                 ALOGE("%s: torch client died but couldn't turn off torch: " | 
 | 5581 |                     "%s (%d)", __FUNCTION__, strerror(-res), res); | 
 | 5582 |                 return; | 
 | 5583 |             } | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5584 |             mTorchClientMap.removeItemsAt(i); | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5585 |             break; | 
 | 5586 |         } | 
 | 5587 |     } | 
 | 5588 | } | 
 | 5589 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5590 | /*virtual*/void CameraService::binderDied(const wp<IBinder> &who) { | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 5591 |  | 
| Igor Murashkin | 294d0ec | 2012-10-05 10:44:57 -0700 | [diff] [blame] | 5592 |     /** | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 5593 |       * While tempting to promote the wp<IBinder> into a sp, it's actually not supported by the | 
 | 5594 |       * binder driver | 
| Igor Murashkin | 294d0ec | 2012-10-05 10:44:57 -0700 | [diff] [blame] | 5595 |       */ | 
| Yin-Chia Yeh | dbfcb38 | 2018-02-16 11:17:36 -0800 | [diff] [blame] | 5596 |     // PID here is approximate and can be wrong. | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 5597 |     logClientDied(getCallingPid(), "Binder died unexpectedly"); | 
| Ruben Brunk | a8ca915 | 2015-04-07 14:23:40 -0700 | [diff] [blame] | 5598 |  | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5599 |     // check torch client | 
 | 5600 |     handleTorchClientBinderDied(who); | 
 | 5601 |  | 
 | 5602 |     // check camera device client | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5603 |     if(!evictClientIdByRemote(who)) { | 
 | 5604 |         ALOGV("%s: Java client's binder death already cleaned up (normal case)", __FUNCTION__); | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 5605 |         return; | 
 | 5606 |     } | 
 | 5607 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5608 |     ALOGE("%s: Java client's binder died, removing it from the list of active clients", | 
 | 5609 |             __FUNCTION__); | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 5610 | } | 
 | 5611 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5612 | void CameraService::updateStatus(StatusInternal status, const std::string& cameraId) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5613 |     updateStatus(status, cameraId, {}); | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 5614 | } | 
 | 5615 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5616 | void CameraService::updateStatus(StatusInternal status, const std::string& cameraId, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5617 |         std::initializer_list<StatusInternal> rejectSourceStates) { | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5618 |     // Do not lock mServiceLock here or can get into a deadlock from | 
 | 5619 |     // connect() -> disconnect -> updateStatus | 
 | 5620 |  | 
 | 5621 |     auto state = getCameraState(cameraId); | 
 | 5622 |  | 
 | 5623 |     if (state == nullptr) { | 
 | 5624 |         ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5625 |                 cameraId.c_str()); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5626 |         return; | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 5627 |     } | 
 | 5628 |  | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 5629 |     // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275) | 
 | 5630 |     SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; | 
 | 5631 |     if (getSystemCameraKind(cameraId, &deviceKind) != OK) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5632 |         ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.c_str()); | 
| Jayant Chowdhary | 33e8ef8 | 2019-09-27 09:20:42 -0700 | [diff] [blame] | 5633 |         return; | 
 | 5634 |     } | 
| Jayant Chowdhary | 5e2cd30 | 2020-08-14 02:48:34 +0000 | [diff] [blame] | 5635 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5636 |     if (vd_flags::camera_device_awareness() && status == StatusInternal::PRESENT) { | 
 | 5637 |         CameraMetadata cameraInfo; | 
 | 5638 |         status_t res = mCameraProviderManager->getCameraCharacteristics( | 
| Jayant Chowdhary | 81d81b0 | 2024-02-15 19:13:39 +0000 | [diff] [blame] | 5639 |                 cameraId, false, &cameraInfo, hardware::ICameraService::ROTATION_OVERRIDE_NONE); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5640 |         if (res != OK) { | 
 | 5641 |             ALOGW("%s: Not able to get camera characteristics for camera id %s", | 
 | 5642 |                   __FUNCTION__, cameraId.c_str()); | 
 | 5643 |         } else { | 
 | 5644 |             int32_t deviceId = getDeviceId(cameraInfo); | 
 | 5645 |             if (deviceId != kDefaultDeviceId) { | 
 | 5646 |                 const auto &lensFacingEntry = cameraInfo.find(ANDROID_LENS_FACING); | 
 | 5647 |                 camera_metadata_enum_android_lens_facing_t androidLensFacing = | 
 | 5648 |                         static_cast<camera_metadata_enum_android_lens_facing_t>( | 
 | 5649 |                                 lensFacingEntry.data.u8[0]); | 
 | 5650 |                 std::string mappedCameraId; | 
 | 5651 |                 if (androidLensFacing == ANDROID_LENS_FACING_BACK) { | 
 | 5652 |                     mappedCameraId = kVirtualDeviceBackCameraId; | 
 | 5653 |                 } else if (androidLensFacing == ANDROID_LENS_FACING_FRONT) { | 
 | 5654 |                     mappedCameraId = kVirtualDeviceFrontCameraId; | 
 | 5655 |                 } else { | 
 | 5656 |                     ALOGD("%s: Not adding entry for an external camera of a virtual device", | 
 | 5657 |                           __func__); | 
 | 5658 |                 } | 
 | 5659 |                 if (!mappedCameraId.empty()) { | 
 | 5660 |                     mVirtualDeviceCameraIdMapper.addCamera(cameraId, deviceId, mappedCameraId); | 
 | 5661 |                 } | 
 | 5662 |             } | 
 | 5663 |         } | 
 | 5664 |     } | 
 | 5665 |  | 
| Jayant Chowdhary | 5e2cd30 | 2020-08-14 02:48:34 +0000 | [diff] [blame] | 5666 |     // Collect the logical cameras without holding mStatusLock in updateStatus | 
 | 5667 |     // as that can lead to a deadlock(b/162192331). | 
 | 5668 |     auto logicalCameraIds = getLogicalCameras(cameraId); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5669 |     // Update the status for this camera state, then send the onStatusChangedCallbacks to each | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5670 |     // of the listeners with both the mStatusLock and mStatusListenerLock held | 
| Shuzhen Wang | b825979 | 2021-05-27 09:27:06 -0700 | [diff] [blame] | 5671 |     state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, | 
| Jayant Chowdhary | 5e2cd30 | 2020-08-14 02:48:34 +0000 | [diff] [blame] | 5672 |                         &logicalCameraIds] | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5673 |             (const std::string& cameraId, StatusInternal status) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5674 |                 // Get the device id and app-visible camera id for the given HAL-visible camera id. | 
 | 5675 |                 auto [deviceId, mappedCameraId] = | 
 | 5676 |                         mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5677 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5678 |                 if (status != StatusInternal::ENUMERATING) { | 
 | 5679 |                     // Update torch status if it has a flash unit. | 
 | 5680 |                     Mutex::Autolock al(mTorchStatusMutex); | 
 | 5681 |                     TorchModeStatus torchStatus; | 
 | 5682 |                     if (getTorchStatusLocked(cameraId, &torchStatus) != | 
 | 5683 |                             NAME_NOT_FOUND) { | 
 | 5684 |                         TorchModeStatus newTorchStatus = | 
 | 5685 |                                 status == StatusInternal::PRESENT ? | 
 | 5686 |                                 TorchModeStatus::AVAILABLE_OFF : | 
 | 5687 |                                 TorchModeStatus::NOT_AVAILABLE; | 
 | 5688 |                         if (torchStatus != newTorchStatus) { | 
 | 5689 |                             onTorchStatusChangedLocked(cameraId, newTorchStatus, deviceKind); | 
 | 5690 |                         } | 
| Chien-Yu Chen | f6463fc | 2015-04-07 15:11:31 -0700 | [diff] [blame] | 5691 |                     } | 
 | 5692 |                 } | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 5693 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5694 |                 Mutex::Autolock lock(mStatusListenerLock); | 
 | 5695 |                 notifyPhysicalCameraStatusLocked(mapToInterface(status), mappedCameraId, | 
 | 5696 |                         logicalCameraIds, deviceKind, deviceId); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5697 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5698 |                 for (auto& listener : mListenerList) { | 
 | 5699 |                     bool isVendorListener = listener->isVendorListener(); | 
 | 5700 |                     if (shouldSkipStatusUpdates(deviceKind, isVendorListener, | 
 | 5701 |                             listener->getListenerPid(), listener->getListenerUid())) { | 
 | 5702 |                         ALOGV("Skipping discovery callback for system-only camera device %s", | 
 | 5703 |                               cameraId.c_str()); | 
 | 5704 |                         continue; | 
 | 5705 |                     } | 
 | 5706 |  | 
 | 5707 |                     auto ret = listener->getListener()->onStatusChanged(mapToInterface(status), | 
 | 5708 |                             mappedCameraId, deviceId); | 
| malikakash | 82ed435 | 2023-07-21 22:44:34 +0000 | [diff] [blame] | 5709 |                     listener->handleBinderStatus(ret, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5710 |                             "%s: Failed to trigger onStatusChanged callback for %d:%d: %d", | 
| malikakash | 82ed435 | 2023-07-21 22:44:34 +0000 | [diff] [blame] | 5711 |                             __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(), | 
 | 5712 |                             ret.exceptionCode()); | 
 | 5713 |                 } | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5714 |             }); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 5715 | } | 
 | 5716 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5717 | void CameraService::updateOpenCloseStatus(const std::string& cameraId, bool open, | 
 | 5718 |         const std::string& clientPackageName) { | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 5719 |     auto state = getCameraState(cameraId); | 
 | 5720 |     if (state == nullptr) { | 
 | 5721 |         ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5722 |                 cameraId.c_str()); | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 5723 |         return; | 
 | 5724 |     } | 
 | 5725 |     if (open) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5726 |         state->setClientPackage(clientPackageName); | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 5727 |     } else { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5728 |         state->setClientPackage(std::string()); | 
| Shuzhen Wang | e7aa034 | 2021-08-03 11:29:47 -0700 | [diff] [blame] | 5729 |     } | 
 | 5730 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5731 |     // Get the device id and app-visible camera id for the given HAL-visible camera id. | 
 | 5732 |     auto [deviceId, mappedCameraId] = | 
 | 5733 |             mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId); | 
 | 5734 |  | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 5735 |     Mutex::Autolock lock(mStatusListenerLock); | 
 | 5736 |  | 
 | 5737 |     for (const auto& it : mListenerList) { | 
 | 5738 |         if (!it->isOpenCloseCallbackAllowed()) { | 
 | 5739 |             continue; | 
 | 5740 |         } | 
 | 5741 |  | 
 | 5742 |         binder::Status ret; | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 5743 |         if (open) { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5744 |             ret = it->getListener()->onCameraOpened(mappedCameraId, clientPackageName, | 
 | 5745 |                     deviceId); | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 5746 |         } else { | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5747 |             ret = it->getListener()->onCameraClosed(mappedCameraId, deviceId); | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 5748 |         } | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 5749 |  | 
 | 5750 |         it->handleBinderStatus(ret, | 
 | 5751 |                 "%s: Failed to trigger onCameraOpened/onCameraClosed callback for %d:%d: %d", | 
 | 5752 |                 __FUNCTION__, it->getListenerUid(), it->getListenerPid(), ret.exceptionCode()); | 
| Shuzhen Wang | 695044d | 2020-03-06 09:02:23 -0800 | [diff] [blame] | 5753 |     } | 
 | 5754 | } | 
 | 5755 |  | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5756 | template<class Func> | 
 | 5757 | void CameraService::CameraState::updateStatus(StatusInternal status, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5758 |         const std::string& cameraId, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5759 |         std::initializer_list<StatusInternal> rejectSourceStates, | 
 | 5760 |         Func onStatusUpdatedLocked) { | 
 | 5761 |     Mutex::Autolock lock(mStatusLock); | 
 | 5762 |     StatusInternal oldStatus = mStatus; | 
 | 5763 |     mStatus = status; | 
 | 5764 |  | 
 | 5765 |     if (oldStatus == status) { | 
 | 5766 |         return; | 
 | 5767 |     } | 
 | 5768 |  | 
 | 5769 |     ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5770 |             cameraId.c_str(), oldStatus, status); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5771 |  | 
 | 5772 |     if (oldStatus == StatusInternal::NOT_PRESENT && | 
 | 5773 |             (status != StatusInternal::PRESENT && | 
 | 5774 |              status != StatusInternal::ENUMERATING)) { | 
 | 5775 |  | 
 | 5776 |         ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING", | 
 | 5777 |                 __FUNCTION__); | 
 | 5778 |         mStatus = oldStatus; | 
 | 5779 |         return; | 
 | 5780 |     } | 
 | 5781 |  | 
 | 5782 |     /** | 
 | 5783 |      * Sometimes we want to conditionally do a transition. | 
 | 5784 |      * For example if a client disconnects, we want to go to PRESENT | 
 | 5785 |      * only if we weren't already in NOT_PRESENT or ENUMERATING. | 
 | 5786 |      */ | 
 | 5787 |     for (auto& rejectStatus : rejectSourceStates) { | 
 | 5788 |         if (oldStatus == rejectStatus) { | 
 | 5789 |             ALOGV("%s: Rejecting status transition for Camera ID %s,  since the source " | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5790 |                     "state was was in one of the bad states.", __FUNCTION__, cameraId.c_str()); | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5791 |             mStatus = oldStatus; | 
 | 5792 |             return; | 
 | 5793 |         } | 
 | 5794 |     } | 
 | 5795 |  | 
 | 5796 |     onStatusUpdatedLocked(cameraId, status); | 
 | 5797 | } | 
 | 5798 |  | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 5799 | status_t CameraService::getTorchStatusLocked( | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5800 |         const std::string& cameraId, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5801 |         TorchModeStatus *status) const { | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 5802 |     if (!status) { | 
 | 5803 |         return BAD_VALUE; | 
 | 5804 |     } | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5805 |     ssize_t index = mTorchStatusMap.indexOfKey(cameraId); | 
 | 5806 |     if (index == NAME_NOT_FOUND) { | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 5807 |         // invalid camera ID or the camera doesn't have a flash unit | 
 | 5808 |         return NAME_NOT_FOUND; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5809 |     } | 
 | 5810 |  | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 5811 |     *status = mTorchStatusMap.valueAt(index); | 
 | 5812 |     return OK; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5813 | } | 
 | 5814 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5815 | status_t CameraService::setTorchStatusLocked(const std::string& cameraId, | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5816 |         TorchModeStatus status) { | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5817 |     ssize_t index = mTorchStatusMap.indexOfKey(cameraId); | 
 | 5818 |     if (index == NAME_NOT_FOUND) { | 
 | 5819 |         return BAD_VALUE; | 
 | 5820 |     } | 
| Eino-Ville Talvala | f51fca2 | 2016-12-13 11:25:55 -0800 | [diff] [blame] | 5821 |     mTorchStatusMap.editValueAt(index) = status; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 5822 |  | 
 | 5823 |     return OK; | 
 | 5824 | } | 
 | 5825 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5826 | std::list<std::string> CameraService::getLogicalCameras( | 
 | 5827 |         const std::string& physicalCameraId) { | 
 | 5828 |     std::list<std::string> retList; | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5829 |     Mutex::Autolock lock(mCameraStatesLock); | 
 | 5830 |     for (const auto& state : mCameraStates) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5831 |         if (state.second->containsPhysicalCamera(physicalCameraId)) { | 
 | 5832 |             retList.emplace_back(state.first); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5833 |         } | 
| Jayant Chowdhary | 5e2cd30 | 2020-08-14 02:48:34 +0000 | [diff] [blame] | 5834 |     } | 
 | 5835 |     return retList; | 
 | 5836 | } | 
 | 5837 |  | 
 | 5838 | void CameraService::notifyPhysicalCameraStatusLocked(int32_t status, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5839 |         const std::string& physicalCameraId, const std::list<std::string>& logicalCameraIds, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5840 |         SystemCameraKind deviceKind, int32_t deviceId) { | 
| Jayant Chowdhary | 5e2cd30 | 2020-08-14 02:48:34 +0000 | [diff] [blame] | 5841 |     // mStatusListenerLock is expected to be locked | 
 | 5842 |     for (const auto& logicalCameraId : logicalCameraIds) { | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5843 |         for (auto& listener : mListenerList) { | 
| Jayant Chowdhary | 5e2cd30 | 2020-08-14 02:48:34 +0000 | [diff] [blame] | 5844 |             // Note: we check only the deviceKind of the physical camera id | 
 | 5845 |             // since, logical camera ids and their physical camera ids are | 
 | 5846 |             // guaranteed to have the same system camera kind. | 
| Jayant Chowdhary | d1478ce | 2020-05-07 17:35:23 -0700 | [diff] [blame] | 5847 |             if (shouldSkipStatusUpdates(deviceKind, listener->isVendorListener(), | 
 | 5848 |                     listener->getListenerPid(), listener->getListenerUid())) { | 
 | 5849 |                 ALOGV("Skipping discovery callback for system-only camera device %s", | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5850 |                         physicalCameraId.c_str()); | 
| Jayant Chowdhary | d1478ce | 2020-05-07 17:35:23 -0700 | [diff] [blame] | 5851 |                 continue; | 
 | 5852 |             } | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 5853 |             auto ret = listener->getListener()->onPhysicalCameraStatusChanged(status, | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 5854 |                     logicalCameraId, physicalCameraId, deviceId); | 
| Austin Borger | e8e2c42 | 2022-05-12 13:45:24 -0700 | [diff] [blame] | 5855 |             listener->handleBinderStatus(ret, | 
 | 5856 |                     "%s: Failed to trigger onPhysicalCameraStatusChanged for %d:%d: %d", | 
 | 5857 |                     __FUNCTION__, listener->getListenerUid(), listener->getListenerPid(), | 
 | 5858 |                     ret.exceptionCode()); | 
| Shuzhen Wang | 4385816 | 2020-01-10 13:42:15 -0800 | [diff] [blame] | 5859 |         } | 
 | 5860 |     } | 
 | 5861 | } | 
 | 5862 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5863 | void CameraService::blockClientsForUid(uid_t uid) { | 
 | 5864 |     const auto clients = mActiveClientManager.getAll(); | 
 | 5865 |     for (auto& current : clients) { | 
 | 5866 |         if (current != nullptr) { | 
 | 5867 |             const auto basicClient = current->getValue(); | 
 | 5868 |             if (basicClient.get() != nullptr && basicClient->getClientUid() == uid) { | 
 | 5869 |                 basicClient->block(); | 
 | 5870 |             } | 
 | 5871 |         } | 
 | 5872 |     } | 
 | 5873 | } | 
 | 5874 |  | 
| Michael Groover | d1d435a | 2018-12-18 17:39:42 -0800 | [diff] [blame] | 5875 | void CameraService::blockAllClients() { | 
 | 5876 |     const auto clients = mActiveClientManager.getAll(); | 
 | 5877 |     for (auto& current : clients) { | 
 | 5878 |         if (current != nullptr) { | 
 | 5879 |             const auto basicClient = current->getValue(); | 
 | 5880 |             if (basicClient.get() != nullptr) { | 
 | 5881 |                 basicClient->block(); | 
 | 5882 |             } | 
 | 5883 |         } | 
 | 5884 |     } | 
 | 5885 | } | 
 | 5886 |  | 
| Jyoti Bhayana | c05a119 | 2024-02-11 13:19:29 +0000 | [diff] [blame] | 5887 | void CameraService::blockPrivacyEnabledClients() { | 
 | 5888 |     const auto clients = mActiveClientManager.getAll(); | 
 | 5889 |     for (auto& current : clients) { | 
 | 5890 |         if (current != nullptr) { | 
 | 5891 |             const auto basicClient = current->getValue(); | 
 | 5892 |             if (basicClient.get() != nullptr) { | 
 | 5893 |                 std::string pkgName = basicClient->getPackageName(); | 
 | 5894 |                 bool cameraPrivacyEnabled = | 
 | 5895 |                         mSensorPrivacyPolicy->isCameraPrivacyEnabled(toString16(pkgName)); | 
 | 5896 |                 if (cameraPrivacyEnabled) { | 
 | 5897 |                     basicClient->block(); | 
 | 5898 |                 } | 
 | 5899 |            } | 
 | 5900 |         } | 
 | 5901 |     } | 
 | 5902 | } | 
 | 5903 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5904 | // NOTE: This is a remote API - make sure all args are validated | 
 | 5905 | status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5906 |     if (!checkCallingPermission(toString16(sManageCameraPermission), nullptr, nullptr)) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5907 |         return PERMISSION_DENIED; | 
 | 5908 |     } | 
 | 5909 |     if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) { | 
 | 5910 |         return BAD_VALUE; | 
 | 5911 |     } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5912 |     if (args.size() >= 3 && args[0] == toString16("set-uid-state")) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5913 |         return handleSetUidState(args, err); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5914 |     } else if (args.size() >= 2 && args[0] == toString16("reset-uid-state")) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5915 |         return handleResetUidState(args, err); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5916 |     } else if (args.size() >= 2 && args[0] == toString16("get-uid-state")) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5917 |         return handleGetUidState(args, out, err); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5918 |     } else if (args.size() >= 2 && args[0] == toString16("set-rotate-and-crop")) { | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 5919 |         return handleSetRotateAndCrop(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5920 |     } else if (args.size() >= 1 && args[0] == toString16("get-rotate-and-crop")) { | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 5921 |         return handleGetRotateAndCrop(out); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5922 |     } else if (args.size() >= 2 && args[0] == toString16("set-autoframing")) { | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 5923 |         return handleSetAutoframing(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5924 |     } else if (args.size() >= 1 && args[0] == toString16("get-autoframing")) { | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 5925 |         return handleGetAutoframing(out); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5926 |     } else if (args.size() >= 2 && args[0] == toString16("set-image-dump-mask")) { | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 5927 |         return handleSetImageDumpMask(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5928 |     } else if (args.size() >= 1 && args[0] == toString16("get-image-dump-mask")) { | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 5929 |         return handleGetImageDumpMask(out); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5930 |     } else if (args.size() >= 2 && args[0] == toString16("set-camera-mute")) { | 
| Eino-Ville Talvala | 305cec6 | 2020-11-12 14:18:17 -0800 | [diff] [blame] | 5931 |         return handleSetCameraMute(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5932 |     } else if (args.size() >= 2 && args[0] == toString16("set-stream-use-case-override")) { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 5933 |         return handleSetStreamUseCaseOverrides(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5934 |     } else if (args.size() >= 1 && args[0] == toString16("clear-stream-use-case-override")) { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 5935 |         handleClearStreamUseCaseOverrides(); | 
 | 5936 |         return OK; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5937 |     } else if (args.size() >= 1 && args[0] == toString16("set-zoom-override")) { | 
| Shuzhen Wang | af22e91 | 2023-04-11 16:03:17 -0700 | [diff] [blame] | 5938 |         return handleSetZoomOverride(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5939 |     } else if (args.size() >= 2 && args[0] == toString16("watch")) { | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 5940 |         return handleWatchCommand(args, in, out); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5941 |     } else if (args.size() >= 2 && args[0] == toString16("set-watchdog")) { | 
| Ravneet | aeb20dc | 2022-03-30 05:33:03 +0000 | [diff] [blame] | 5942 |         return handleSetCameraServiceWatchdog(args); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5943 |     } else if (args.size() == 1 && args[0] == toString16("help")) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5944 |         printHelp(out); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 5945 |         return OK; | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5946 |     } | 
 | 5947 |     printHelp(err); | 
 | 5948 |     return BAD_VALUE; | 
 | 5949 | } | 
 | 5950 |  | 
 | 5951 | status_t CameraService::handleSetUidState(const Vector<String16>& args, int err) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5952 |     std::string packageName = toStdString(args[1]); | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5953 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5954 |     bool active = false; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5955 |     if (args[2] == toString16("active")) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5956 |         active = true; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5957 |     } else if ((args[2] != toString16("idle"))) { | 
 | 5958 |         ALOGE("Expected active or idle but got: '%s'", toStdString(args[2]).c_str()); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5959 |         return BAD_VALUE; | 
 | 5960 |     } | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5961 |  | 
 | 5962 |     int userId = 0; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5963 |     if (args.size() >= 5 && args[3] == toString16("--user")) { | 
 | 5964 |         userId = atoi(toStdString(args[4]).c_str()); | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5965 |     } | 
 | 5966 |  | 
 | 5967 |     uid_t uid; | 
 | 5968 |     if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) { | 
 | 5969 |         return BAD_VALUE; | 
 | 5970 |     } | 
 | 5971 |  | 
 | 5972 |     mUidPolicy->addOverrideUid(uid, packageName, active); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5973 |     return NO_ERROR; | 
 | 5974 | } | 
 | 5975 |  | 
 | 5976 | status_t CameraService::handleResetUidState(const Vector<String16>& args, int err) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5977 |     std::string packageName = toStdString(args[1]); | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5978 |  | 
 | 5979 |     int userId = 0; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5980 |     if (args.size() >= 4 && args[2] == toString16("--user")) { | 
 | 5981 |         userId = atoi(toStdString(args[3]).c_str()); | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5982 |     } | 
 | 5983 |  | 
 | 5984 |     uid_t uid; | 
 | 5985 |     if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5986 |         return BAD_VALUE; | 
 | 5987 |     } | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5988 |  | 
 | 5989 |     mUidPolicy->removeOverrideUid(uid, packageName); | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 5990 |     return NO_ERROR; | 
 | 5991 | } | 
 | 5992 |  | 
 | 5993 | status_t CameraService::handleGetUidState(const Vector<String16>& args, int out, int err) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5994 |     std::string packageName = toStdString(args[1]); | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5995 |  | 
 | 5996 |     int userId = 0; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 5997 |     if (args.size() >= 4 && args[2] == toString16("--user")) { | 
 | 5998 |         userId = atoi(toStdString(args[3]).c_str()); | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 5999 |     } | 
 | 6000 |  | 
 | 6001 |     uid_t uid; | 
 | 6002 |     if (getUidForPackage(packageName, userId, uid, err) == BAD_VALUE) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 6003 |         return BAD_VALUE; | 
 | 6004 |     } | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 6005 |  | 
 | 6006 |     if (mUidPolicy->isUidActive(uid, packageName)) { | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 6007 |         return dprintf(out, "active\n"); | 
 | 6008 |     } else { | 
 | 6009 |         return dprintf(out, "idle\n"); | 
 | 6010 |     } | 
 | 6011 | } | 
 | 6012 |  | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 6013 | status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6014 |     int rotateValue = atoi(toStdString(args[1]).c_str()); | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 6015 |     if (rotateValue < ANDROID_SCALER_ROTATE_AND_CROP_NONE || | 
 | 6016 |             rotateValue > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE; | 
 | 6017 |     Mutex::Autolock lock(mServiceLock); | 
 | 6018 |  | 
 | 6019 |     mOverrideRotateAndCropMode = rotateValue; | 
 | 6020 |  | 
 | 6021 |     if (rotateValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return OK; | 
 | 6022 |  | 
 | 6023 |     const auto clients = mActiveClientManager.getAll(); | 
 | 6024 |     for (auto& current : clients) { | 
 | 6025 |         if (current != nullptr) { | 
 | 6026 |             const auto basicClient = current->getValue(); | 
 | 6027 |             if (basicClient.get() != nullptr) { | 
 | 6028 |                 basicClient->setRotateAndCropOverride(rotateValue); | 
 | 6029 |             } | 
 | 6030 |         } | 
 | 6031 |     } | 
 | 6032 |  | 
 | 6033 |     return OK; | 
 | 6034 | } | 
 | 6035 |  | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 6036 | status_t CameraService::handleSetAutoframing(const Vector<String16>& args) { | 
 | 6037 |     char* end; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6038 |     int autoframingValue = (int) strtol(toStdString(args[1]).c_str(), &end, /*base=*/10); | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 6039 |     if ((*end != '\0') || | 
 | 6040 |             (autoframingValue != ANDROID_CONTROL_AUTOFRAMING_OFF && | 
 | 6041 |              autoframingValue != ANDROID_CONTROL_AUTOFRAMING_ON && | 
 | 6042 |              autoframingValue != ANDROID_CONTROL_AUTOFRAMING_AUTO)) { | 
 | 6043 |         return BAD_VALUE; | 
 | 6044 |     } | 
 | 6045 |  | 
 | 6046 |     Mutex::Autolock lock(mServiceLock); | 
 | 6047 |     mOverrideAutoframingMode = autoframingValue; | 
 | 6048 |  | 
 | 6049 |     if (autoframingValue == ANDROID_CONTROL_AUTOFRAMING_AUTO) return OK; | 
 | 6050 |  | 
 | 6051 |     const auto clients = mActiveClientManager.getAll(); | 
 | 6052 |     for (auto& current : clients) { | 
 | 6053 |         if (current != nullptr) { | 
 | 6054 |             const auto basicClient = current->getValue(); | 
 | 6055 |             if (basicClient.get() != nullptr) { | 
 | 6056 |                 basicClient->setAutoframingOverride(autoframingValue); | 
 | 6057 |             } | 
 | 6058 |         } | 
 | 6059 |     } | 
 | 6060 |  | 
 | 6061 |     return OK; | 
 | 6062 | } | 
 | 6063 |  | 
| Ravneet | aeb20dc | 2022-03-30 05:33:03 +0000 | [diff] [blame] | 6064 | status_t CameraService::handleSetCameraServiceWatchdog(const Vector<String16>& args) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6065 |     int enableWatchdog = atoi(toStdString(args[1]).c_str()); | 
| Ravneet | aeb20dc | 2022-03-30 05:33:03 +0000 | [diff] [blame] | 6066 |  | 
 | 6067 |     if (enableWatchdog < 0 || enableWatchdog > 1) return BAD_VALUE; | 
 | 6068 |  | 
 | 6069 |     Mutex::Autolock lock(mServiceLock); | 
 | 6070 |  | 
 | 6071 |     mCameraServiceWatchdogEnabled = enableWatchdog; | 
 | 6072 |  | 
 | 6073 |     const auto clients = mActiveClientManager.getAll(); | 
 | 6074 |     for (auto& current : clients) { | 
 | 6075 |         if (current != nullptr) { | 
 | 6076 |             const auto basicClient = current->getValue(); | 
 | 6077 |             if (basicClient.get() != nullptr) { | 
 | 6078 |                 basicClient->setCameraServiceWatchdog(enableWatchdog); | 
 | 6079 |             } | 
 | 6080 |         } | 
 | 6081 |     } | 
 | 6082 |  | 
 | 6083 |     return OK; | 
 | 6084 | } | 
 | 6085 |  | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 6086 | status_t CameraService::handleGetRotateAndCrop(int out) { | 
 | 6087 |     Mutex::Autolock lock(mServiceLock); | 
 | 6088 |  | 
 | 6089 |     return dprintf(out, "rotateAndCrop override: %d\n", mOverrideRotateAndCropMode); | 
 | 6090 | } | 
 | 6091 |  | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 6092 | status_t CameraService::handleGetAutoframing(int out) { | 
 | 6093 |     Mutex::Autolock lock(mServiceLock); | 
 | 6094 |  | 
 | 6095 |     return dprintf(out, "autoframing override: %d\n", mOverrideAutoframingMode); | 
 | 6096 | } | 
 | 6097 |  | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 6098 | status_t CameraService::handleSetImageDumpMask(const Vector<String16>& args) { | 
 | 6099 |     char *endPtr; | 
 | 6100 |     errno = 0; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6101 |     std::string maskString = toStdString(args[1]); | 
 | 6102 |     long maskValue = strtol(maskString.c_str(), &endPtr, 10); | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 6103 |  | 
 | 6104 |     if (errno != 0) return BAD_VALUE; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6105 |     if (endPtr != maskString.c_str() + maskString.size()) return BAD_VALUE; | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 6106 |     if (maskValue < 0 || maskValue > 1) return BAD_VALUE; | 
 | 6107 |  | 
 | 6108 |     Mutex::Autolock lock(mServiceLock); | 
 | 6109 |  | 
 | 6110 |     mImageDumpMask = maskValue; | 
 | 6111 |  | 
 | 6112 |     return OK; | 
 | 6113 | } | 
 | 6114 |  | 
 | 6115 | status_t CameraService::handleGetImageDumpMask(int out) { | 
 | 6116 |     Mutex::Autolock lock(mServiceLock); | 
 | 6117 |  | 
 | 6118 |     return dprintf(out, "Image dump mask: %d\n", mImageDumpMask); | 
 | 6119 | } | 
 | 6120 |  | 
| Eino-Ville Talvala | 305cec6 | 2020-11-12 14:18:17 -0800 | [diff] [blame] | 6121 | status_t CameraService::handleSetCameraMute(const Vector<String16>& args) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6122 |     int muteValue = strtol(toStdString(args[1]).c_str(), nullptr, 10); | 
| Eino-Ville Talvala | 305cec6 | 2020-11-12 14:18:17 -0800 | [diff] [blame] | 6123 |     if (errno != 0) return BAD_VALUE; | 
 | 6124 |  | 
 | 6125 |     if (muteValue < 0 || muteValue > 1) return BAD_VALUE; | 
 | 6126 |     Mutex::Autolock lock(mServiceLock); | 
 | 6127 |  | 
 | 6128 |     mOverrideCameraMuteMode = (muteValue == 1); | 
 | 6129 |  | 
 | 6130 |     const auto clients = mActiveClientManager.getAll(); | 
 | 6131 |     for (auto& current : clients) { | 
 | 6132 |         if (current != nullptr) { | 
 | 6133 |             const auto basicClient = current->getValue(); | 
 | 6134 |             if (basicClient.get() != nullptr) { | 
 | 6135 |                 if (basicClient->supportsCameraMute()) { | 
 | 6136 |                     basicClient->setCameraMute(mOverrideCameraMuteMode); | 
 | 6137 |                 } | 
 | 6138 |             } | 
 | 6139 |         } | 
 | 6140 |     } | 
 | 6141 |  | 
 | 6142 |     return OK; | 
 | 6143 | } | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 6144 |  | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6145 | status_t CameraService::handleSetStreamUseCaseOverrides(const Vector<String16>& args) { | 
 | 6146 |     std::vector<int64_t> useCasesOverride; | 
 | 6147 |     for (size_t i = 1; i < args.size(); i++) { | 
 | 6148 |         int64_t useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6149 |         std::string arg = toStdString(args[i]); | 
 | 6150 |         if (arg == "DEFAULT") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6151 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6152 |         } else if (arg == "PREVIEW") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6153 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6154 |         } else if (arg == "STILL_CAPTURE") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6155 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6156 |         } else if (arg == "VIDEO_RECORD") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6157 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6158 |         } else if (arg == "PREVIEW_VIDEO_STILL") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6159 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6160 |         } else if (arg == "VIDEO_CALL") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6161 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6162 |         } else if (arg == "CROPPED_RAW") { | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6163 |             useCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW; | 
 | 6164 |         } else { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6165 |             ALOGE("%s: Invalid stream use case %s", __FUNCTION__, arg.c_str()); | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6166 |             return BAD_VALUE; | 
 | 6167 |         } | 
 | 6168 |         useCasesOverride.push_back(useCase); | 
 | 6169 |     } | 
 | 6170 |  | 
 | 6171 |     Mutex::Autolock lock(mServiceLock); | 
 | 6172 |     mStreamUseCaseOverrides = std::move(useCasesOverride); | 
 | 6173 |  | 
 | 6174 |     return OK; | 
 | 6175 | } | 
 | 6176 |  | 
 | 6177 | void CameraService::handleClearStreamUseCaseOverrides() { | 
 | 6178 |     Mutex::Autolock lock(mServiceLock); | 
 | 6179 |     mStreamUseCaseOverrides.clear(); | 
 | 6180 | } | 
 | 6181 |  | 
| Shuzhen Wang | af22e91 | 2023-04-11 16:03:17 -0700 | [diff] [blame] | 6182 | status_t CameraService::handleSetZoomOverride(const Vector<String16>& args) { | 
 | 6183 |     char* end; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6184 |     int zoomOverrideValue = strtol(toStdString(args[1]).c_str(), &end, /*base=*/10); | 
| Shuzhen Wang | af22e91 | 2023-04-11 16:03:17 -0700 | [diff] [blame] | 6185 |     if ((*end != '\0') || | 
 | 6186 |             (zoomOverrideValue != -1 && | 
 | 6187 |              zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF && | 
 | 6188 |              zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM)) { | 
 | 6189 |         return BAD_VALUE; | 
 | 6190 |     } | 
 | 6191 |  | 
 | 6192 |     Mutex::Autolock lock(mServiceLock); | 
 | 6193 |     mZoomOverrideValue = zoomOverrideValue; | 
 | 6194 |  | 
 | 6195 |     const auto clients = mActiveClientManager.getAll(); | 
 | 6196 |     for (auto& current : clients) { | 
 | 6197 |         if (current != nullptr) { | 
 | 6198 |             const auto basicClient = current->getValue(); | 
 | 6199 |             if (basicClient.get() != nullptr) { | 
 | 6200 |                 if (basicClient->supportsZoomOverride()) { | 
 | 6201 |                     basicClient->setZoomOverride(mZoomOverrideValue); | 
 | 6202 |                 } | 
 | 6203 |             } | 
 | 6204 |         } | 
 | 6205 |     } | 
 | 6206 |  | 
 | 6207 |     return OK; | 
 | 6208 | } | 
 | 6209 |  | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6210 | status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6211 |     if (args.size() >= 3 && args[1] == toString16("start")) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6212 |         return startWatchingTags(args, outFd); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6213 |     } else if (args.size() == 2 && args[1] == toString16("stop")) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6214 |         return stopWatchingTags(outFd); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6215 |     } else if (args.size() == 2 && args[1] == toString16("dump")) { | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6216 |         return printWatchedTags(outFd); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6217 |     } else if (args.size() >= 2 && args[1] == toString16("live")) { | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6218 |         return printWatchedTagsUntilInterrupt(args, inFd, outFd); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6219 |     } else if (args.size() == 2 && args[1] == toString16("clear")) { | 
| Avichal Rakesh | 3a85d2d | 2021-11-10 16:21:33 -0800 | [diff] [blame] | 6220 |         return clearCachedMonitoredTagDumps(outFd); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6221 |     } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6222 |     dprintf(outFd, "Camera service watch commands:\n" | 
 | 6223 |                  "  start -m <comma_separated_tag_list> [-c <comma_separated_client_list>]\n" | 
 | 6224 |                  "        starts watching the provided tags for clients with provided package\n" | 
 | 6225 |                  "        recognizes tag shorthands like '3a'\n" | 
 | 6226 |                  "        watches all clients if no client is passed, or if 'all' is listed\n" | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6227 |                  "  dump dumps the monitoring information and exits\n" | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6228 |                  "  stop stops watching all tags\n" | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6229 |                  "  live [-n <refresh_interval_ms>]\n" | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6230 |                  "        prints the monitored information in real time\n" | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6231 |                  "        Hit return to exit\n" | 
| Avichal Rakesh | 3a85d2d | 2021-11-10 16:21:33 -0800 | [diff] [blame] | 6232 |                  "  clear clears all buffers storing information for watch command"); | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 6233 |     return BAD_VALUE; | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6234 | } | 
 | 6235 |  | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6236 | status_t CameraService::startWatchingTags(const Vector<String16> &args, int outFd) { | 
 | 6237 |     Mutex::Autolock lock(mLogLock); | 
 | 6238 |     size_t tagsIdx; // index of '-m' | 
 | 6239 |     String16 tags(""); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6240 |     for (tagsIdx = 2; tagsIdx < args.size() && args[tagsIdx] != toString16("-m"); tagsIdx++); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6241 |     if (tagsIdx < args.size() - 1) { | 
 | 6242 |         tags = args[tagsIdx + 1]; | 
 | 6243 |     } else { | 
 | 6244 |         dprintf(outFd, "No tags provided.\n"); | 
 | 6245 |         return BAD_VALUE; | 
 | 6246 |     } | 
 | 6247 |  | 
 | 6248 |     size_t clientsIdx; // index of '-c' | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6249 |     // watch all clients if no clients are provided | 
 | 6250 |     String16 clients = toString16(kWatchAllClientsFlag); | 
 | 6251 |     for (clientsIdx = 2; clientsIdx < args.size() && args[clientsIdx] != toString16("-c"); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6252 |          clientsIdx++); | 
 | 6253 |     if (clientsIdx < args.size() - 1) { | 
 | 6254 |         clients = args[clientsIdx + 1]; | 
 | 6255 |     } | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6256 |     parseClientsToWatchLocked(toStdString(clients)); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6257 |  | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6258 |     // track tags to initialize future clients with the monitoring information | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6259 |     mMonitorTags = toStdString(tags); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6260 |  | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6261 |     bool serviceLock = tryLock(mServiceLock); | 
 | 6262 |     int numWatchedClients = 0; | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6263 |     auto cameraClients = mActiveClientManager.getAll(); | 
 | 6264 |     for (const auto &clientDescriptor: cameraClients) { | 
 | 6265 |         if (clientDescriptor == nullptr) { continue; } | 
 | 6266 |         sp<BasicClient> client = clientDescriptor->getValue(); | 
 | 6267 |         if (client.get() == nullptr) { continue; } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6268 |  | 
 | 6269 |         if (isClientWatchedLocked(client.get())) { | 
 | 6270 |             client->startWatchingTags(mMonitorTags, outFd); | 
 | 6271 |             numWatchedClients++; | 
 | 6272 |         } | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6273 |     } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6274 |     dprintf(outFd, "Started watching %d active clients\n", numWatchedClients); | 
 | 6275 |  | 
 | 6276 |     if (serviceLock) { mServiceLock.unlock(); } | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6277 |     return OK; | 
 | 6278 | } | 
 | 6279 |  | 
 | 6280 | status_t CameraService::stopWatchingTags(int outFd) { | 
 | 6281 |     // clear mMonitorTags to prevent new clients from monitoring tags at initialization | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6282 |     Mutex::Autolock lock(mLogLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6283 |     mMonitorTags = ""; | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6284 |  | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6285 |     mWatchedClientPackages.clear(); | 
 | 6286 |     mWatchedClientsDumpCache.clear(); | 
 | 6287 |  | 
 | 6288 |     bool serviceLock = tryLock(mServiceLock); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6289 |     auto cameraClients = mActiveClientManager.getAll(); | 
 | 6290 |     for (const auto &clientDescriptor : cameraClients) { | 
 | 6291 |         if (clientDescriptor == nullptr) { continue; } | 
 | 6292 |         sp<BasicClient> client = clientDescriptor->getValue(); | 
 | 6293 |         if (client.get() == nullptr) { continue; } | 
 | 6294 |         client->stopWatchingTags(outFd); | 
 | 6295 |     } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6296 |     dprintf(outFd, "Stopped watching all clients.\n"); | 
 | 6297 |     if (serviceLock) { mServiceLock.unlock(); } | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6298 |     return OK; | 
 | 6299 | } | 
 | 6300 |  | 
| Avichal Rakesh | 3a85d2d | 2021-11-10 16:21:33 -0800 | [diff] [blame] | 6301 | status_t CameraService::clearCachedMonitoredTagDumps(int outFd) { | 
 | 6302 |     Mutex::Autolock lock(mLogLock); | 
 | 6303 |     size_t clearedSize = mWatchedClientsDumpCache.size(); | 
 | 6304 |     mWatchedClientsDumpCache.clear(); | 
 | 6305 |     dprintf(outFd, "Cleared tag information of %zu cached clients.\n", clearedSize); | 
 | 6306 |     return OK; | 
 | 6307 | } | 
 | 6308 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6309 | status_t CameraService::printWatchedTags(int outFd) { | 
 | 6310 |     Mutex::Autolock logLock(mLogLock); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6311 |     std::set<std::string> connectedMonitoredClients; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6312 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6313 |     bool printedSomething = false; // tracks if any monitoring information was printed | 
 | 6314 |                                    // (from either cached or active clients) | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6315 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6316 |     bool serviceLock = tryLock(mServiceLock); | 
 | 6317 |     // get all watched clients that are currently connected | 
 | 6318 |     for (const auto &clientDescriptor: mActiveClientManager.getAll()) { | 
 | 6319 |         if (clientDescriptor == nullptr) { continue; } | 
 | 6320 |  | 
 | 6321 |         sp<BasicClient> client = clientDescriptor->getValue(); | 
 | 6322 |         if (client.get() == nullptr) { continue; } | 
 | 6323 |         if (!isClientWatchedLocked(client.get())) { continue; } | 
 | 6324 |  | 
 | 6325 |         std::vector<std::string> dumpVector; | 
 | 6326 |         client->dumpWatchedEventsToVector(dumpVector); | 
 | 6327 |  | 
 | 6328 |         size_t printIdx = dumpVector.size(); | 
 | 6329 |         if (printIdx == 0) { | 
 | 6330 |             continue; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6331 |         } | 
 | 6332 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6333 |         // Print tag dumps for active client | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6334 |         const std::string &cameraId = clientDescriptor->getKey(); | 
 | 6335 |         dprintf(outFd, "Client: %s (active)\n", client->getPackageName().c_str()); | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6336 |         while(printIdx > 0) { | 
 | 6337 |             printIdx--; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6338 |             dprintf(outFd, "%s:%s  %s", cameraId.c_str(), client->getPackageName().c_str(), | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6339 |                     dumpVector[printIdx].c_str()); | 
| Avichal Rakesh | 3a85d2d | 2021-11-10 16:21:33 -0800 | [diff] [blame] | 6340 |         } | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6341 |         dprintf(outFd, "\n"); | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6342 |         printedSomething = true; | 
 | 6343 |  | 
 | 6344 |         connectedMonitoredClients.emplace(client->getPackageName()); | 
 | 6345 |     } | 
 | 6346 |     if (serviceLock) { mServiceLock.unlock(); } | 
 | 6347 |  | 
 | 6348 |     // Print entries in mWatchedClientsDumpCache for clients that are not connected | 
 | 6349 |     for (const auto &kv: mWatchedClientsDumpCache) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6350 |         const std::string &package = kv.first; | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6351 |         if (connectedMonitoredClients.find(package) != connectedMonitoredClients.end()) { | 
 | 6352 |             continue; | 
 | 6353 |         } | 
 | 6354 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6355 |         dprintf(outFd, "Client: %s (cached)\n", package.c_str()); | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6356 |         dprintf(outFd, "%s\n", kv.second.c_str()); | 
 | 6357 |         printedSomething = true; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6358 |     } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6359 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6360 |     if (!printedSomething) { | 
 | 6361 |         dprintf(outFd, "No monitoring information to print.\n"); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6362 |     } | 
 | 6363 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6364 |     return OK; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6365 | } | 
 | 6366 |  | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6367 | // Print all events in vector `events' that came after lastPrintedEvent | 
 | 6368 | void printNewWatchedEvents(int outFd, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6369 |                            const std::string &cameraId, | 
 | 6370 |                            const std::string &packageName, | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6371 |                            const std::vector<std::string> &events, | 
 | 6372 |                            const std::string &lastPrintedEvent) { | 
 | 6373 |     if (events.empty()) { return; } | 
 | 6374 |  | 
 | 6375 |     // index of lastPrintedEvent in events. | 
 | 6376 |     // lastPrintedIdx = events.size() if lastPrintedEvent is not in events | 
 | 6377 |     size_t lastPrintedIdx; | 
 | 6378 |     for (lastPrintedIdx = 0; | 
 | 6379 |          lastPrintedIdx < events.size() && lastPrintedEvent != events[lastPrintedIdx]; | 
 | 6380 |          lastPrintedIdx++); | 
 | 6381 |  | 
 | 6382 |     if (lastPrintedIdx == 0) { return; } // early exit if no new event in `events` | 
 | 6383 |  | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6384 |     // print events in chronological order (latest event last) | 
 | 6385 |     size_t idxToPrint = lastPrintedIdx; | 
 | 6386 |     do { | 
 | 6387 |         idxToPrint--; | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6388 |         dprintf(outFd, "%s:%s  %s", cameraId.c_str(), packageName.c_str(), | 
 | 6389 |                 events[idxToPrint].c_str()); | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6390 |     } while (idxToPrint != 0); | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6391 | } | 
 | 6392 |  | 
 | 6393 | // Returns true if adb shell cmd watch should be interrupted based on data in inFd. The watch | 
 | 6394 | // command should be interrupted if the user presses the return key, or if user loses any way to | 
 | 6395 | // signal interrupt. | 
 | 6396 | // If timeoutMs == 0, this function will always return false | 
 | 6397 | bool shouldInterruptWatchCommand(int inFd, int outFd, long timeoutMs) { | 
 | 6398 |     struct timeval startTime; | 
 | 6399 |     int startTimeError = gettimeofday(&startTime, nullptr); | 
 | 6400 |     if (startTimeError) { | 
 | 6401 |         dprintf(outFd, "Failed waiting for interrupt, aborting.\n"); | 
 | 6402 |         return true; | 
 | 6403 |     } | 
 | 6404 |  | 
 | 6405 |     const nfds_t numFds = 1; | 
 | 6406 |     struct pollfd pollFd = { .fd = inFd, .events = POLLIN, .revents = 0 }; | 
 | 6407 |  | 
 | 6408 |     struct timeval currTime; | 
 | 6409 |     char buffer[2]; | 
 | 6410 |     while(true) { | 
 | 6411 |         int currTimeError = gettimeofday(&currTime, nullptr); | 
 | 6412 |         if (currTimeError) { | 
 | 6413 |             dprintf(outFd, "Failed waiting for interrupt, aborting.\n"); | 
 | 6414 |             return true; | 
 | 6415 |         } | 
 | 6416 |  | 
 | 6417 |         long elapsedTimeMs = ((currTime.tv_sec - startTime.tv_sec) * 1000L) | 
 | 6418 |                 + ((currTime.tv_usec - startTime.tv_usec) / 1000L); | 
 | 6419 |         int remainingTimeMs = (int) (timeoutMs - elapsedTimeMs); | 
 | 6420 |  | 
 | 6421 |         if (remainingTimeMs <= 0) { | 
 | 6422 |             // No user interrupt within timeoutMs, don't interrupt watch command | 
 | 6423 |             return false; | 
 | 6424 |         } | 
 | 6425 |  | 
 | 6426 |         int numFdsUpdated = poll(&pollFd, numFds, remainingTimeMs); | 
 | 6427 |         if (numFdsUpdated < 0) { | 
 | 6428 |             dprintf(outFd, "Failed while waiting for user input. Exiting.\n"); | 
 | 6429 |             return true; | 
 | 6430 |         } | 
 | 6431 |  | 
 | 6432 |         if (numFdsUpdated == 0) { | 
 | 6433 |             // No user input within timeoutMs, don't interrupt watch command | 
 | 6434 |             return false; | 
 | 6435 |         } | 
 | 6436 |  | 
 | 6437 |         if (!(pollFd.revents & POLLIN)) { | 
 | 6438 |             dprintf(outFd, "Failed while waiting for user input. Exiting.\n"); | 
 | 6439 |             return true; | 
 | 6440 |         } | 
 | 6441 |  | 
 | 6442 |         ssize_t sizeRead = read(inFd, buffer, sizeof(buffer) - 1); | 
 | 6443 |         if (sizeRead < 0) { | 
 | 6444 |             dprintf(outFd, "Error reading user input. Exiting.\n"); | 
 | 6445 |             return true; | 
 | 6446 |         } | 
 | 6447 |  | 
 | 6448 |         if (sizeRead == 0) { | 
 | 6449 |             // Reached end of input fd (can happen if input is piped) | 
 | 6450 |             // User has no way to signal an interrupt, so interrupt here | 
 | 6451 |             return true; | 
 | 6452 |         } | 
 | 6453 |  | 
 | 6454 |         if (buffer[0] == '\n') { | 
 | 6455 |             // User pressed return, interrupt watch command. | 
 | 6456 |             return true; | 
 | 6457 |         } | 
 | 6458 |     } | 
 | 6459 | } | 
 | 6460 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6461 | status_t CameraService::printWatchedTagsUntilInterrupt(const Vector<String16> &args, | 
 | 6462 |                                                        int inFd, int outFd) { | 
 | 6463 |     // Figure out refresh interval, if present in args | 
 | 6464 |     long refreshTimeoutMs = 1000L; // refresh every 1s by default | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6465 |     if (args.size() > 2) { | 
 | 6466 |         size_t intervalIdx; // index of '-n' | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6467 |         for (intervalIdx = 2; intervalIdx < args.size() && toString16("-n") != args[intervalIdx]; | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6468 |              intervalIdx++); | 
 | 6469 |  | 
 | 6470 |         size_t intervalValIdx = intervalIdx + 1; | 
 | 6471 |         if (intervalValIdx < args.size()) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6472 |             refreshTimeoutMs = strtol(toStdString(args[intervalValIdx]).c_str(), nullptr, 10); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6473 |             if (errno) { return BAD_VALUE; } | 
 | 6474 |         } | 
 | 6475 |     } | 
 | 6476 |  | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6477 |     // Set min timeout of 10ms. This prevents edge cases in polling when timeout of 0 is passed. | 
 | 6478 |     refreshTimeoutMs = refreshTimeoutMs < 10 ? 10 : refreshTimeoutMs; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6479 |  | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6480 |     dprintf(outFd, "Press return to exit...\n\n"); | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6481 |     std::map<std::string, std::string> packageNameToLastEvent; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6482 |  | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6483 |     while (true) { | 
| Avichal Rakesh | a14d983 | 2021-11-11 01:41:55 -0800 | [diff] [blame] | 6484 |         bool serviceLock = tryLock(mServiceLock); | 
 | 6485 |         auto cameraClients = mActiveClientManager.getAll(); | 
 | 6486 |         if (serviceLock) { mServiceLock.unlock(); } | 
 | 6487 |  | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6488 |         for (const auto& clientDescriptor : cameraClients) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6489 |             Mutex::Autolock lock(mLogLock); | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6490 |             if (clientDescriptor == nullptr) { continue; } | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6491 |  | 
 | 6492 |             sp<BasicClient> client = clientDescriptor->getValue(); | 
 | 6493 |             if (client.get() == nullptr) { continue; } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6494 |             if (!isClientWatchedLocked(client.get())) { continue; } | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6495 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6496 |             const std::string &packageName = client->getPackageName(); | 
| Avichal Rakesh | a14d983 | 2021-11-11 01:41:55 -0800 | [diff] [blame] | 6497 |             // This also initializes the map entries with an empty string | 
 | 6498 |             const std::string& lastPrintedEvent = packageNameToLastEvent[packageName]; | 
 | 6499 |  | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6500 |             std::vector<std::string> latestEvents; | 
 | 6501 |             client->dumpWatchedEventsToVector(latestEvents); | 
 | 6502 |  | 
 | 6503 |             if (!latestEvents.empty()) { | 
 | 6504 |                 printNewWatchedEvents(outFd, | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6505 |                                       clientDescriptor->getKey(), | 
| Avichal Rakesh | a14d983 | 2021-11-11 01:41:55 -0800 | [diff] [blame] | 6506 |                                       packageName, | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6507 |                                       latestEvents, | 
 | 6508 |                                       lastPrintedEvent); | 
| Avichal Rakesh | a14d983 | 2021-11-11 01:41:55 -0800 | [diff] [blame] | 6509 |                 packageNameToLastEvent[packageName] = latestEvents[0]; | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6510 |             } | 
 | 6511 |         } | 
| Avichal Rakesh | 9e5a1e4 | 2021-11-15 12:11:21 -0800 | [diff] [blame] | 6512 |         if (shouldInterruptWatchCommand(inFd, outFd, refreshTimeoutMs)) { | 
| Avichal Rakesh | 8414713 | 2021-11-11 17:47:11 -0800 | [diff] [blame] | 6513 |             break; | 
 | 6514 |         } | 
| Avichal Rakesh | 7e53cad | 2021-10-05 13:46:30 -0700 | [diff] [blame] | 6515 |     } | 
 | 6516 |     return OK; | 
 | 6517 | } | 
 | 6518 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6519 | void CameraService::parseClientsToWatchLocked(const std::string &clients) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6520 |     mWatchedClientPackages.clear(); | 
 | 6521 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6522 |     std::istringstream iss(clients); | 
 | 6523 |     std::string nextClient; | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6524 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6525 |     while (std::getline(iss, nextClient, ',')) { | 
 | 6526 |         if (nextClient == kWatchAllClientsFlag) { | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6527 |             // Don't need to track any other package if 'all' is present | 
 | 6528 |             mWatchedClientPackages.clear(); | 
 | 6529 |             mWatchedClientPackages.emplace(kWatchAllClientsFlag); | 
 | 6530 |             break; | 
 | 6531 |         } | 
 | 6532 |  | 
 | 6533 |         // track package names | 
 | 6534 |         mWatchedClientPackages.emplace(nextClient); | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6535 |     } | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6536 | } | 
 | 6537 |  | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 6538 | status_t CameraService::printHelp(int out) { | 
 | 6539 |     return dprintf(out, "Camera service commands:\n" | 
| Nicholas Sauer | a362033 | 2019-04-03 14:05:17 -0700 | [diff] [blame] | 6540 |         "  get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n" | 
 | 6541 |         "  set-uid-state <PACKAGE> <active|idle> [--user USER_ID] overrides the uid state\n" | 
 | 6542 |         "  reset-uid-state <PACKAGE> [--user USER_ID] clears the uid state override\n" | 
| Eino-Ville Talvala | f2e3709 | 2020-01-07 15:32:32 -0800 | [diff] [blame] | 6543 |         "  set-rotate-and-crop <ROTATION> overrides the rotate-and-crop value for AUTO backcompat\n" | 
 | 6544 |         "      Valid values 0=0 deg, 1=90 deg, 2=180 deg, 3=270 deg, 4=No override\n" | 
 | 6545 |         "  get-rotate-and-crop returns the current override rotate-and-crop value\n" | 
| Bharatt Kukreja | 7146ced | 2022-10-25 15:45:29 +0000 | [diff] [blame] | 6546 |         "  set-autoframing <VALUE> overrides the autoframing value for AUTO\n" | 
 | 6547 |         "      Valid values 0=false, 1=true, 2=auto\n" | 
 | 6548 |         "  get-autoframing returns the current override autoframing value\n" | 
| Shuzhen Wang | abbcb6b | 2020-12-09 22:32:44 -0800 | [diff] [blame] | 6549 |         "  set-image-dump-mask <MASK> specifies the formats to be saved to disk\n" | 
 | 6550 |         "      Valid values 0=OFF, 1=ON for JPEG\n" | 
 | 6551 |         "  get-image-dump-mask returns the current image-dump-mask value\n" | 
| Eino-Ville Talvala | 305cec6 | 2020-11-12 14:18:17 -0800 | [diff] [blame] | 6552 |         "  set-camera-mute <0/1> enable or disable camera muting\n" | 
| Shuzhen Wang | 16610a6 | 2022-12-15 22:38:07 -0800 | [diff] [blame] | 6553 |         "  set-stream-use-case-override <usecase1> <usecase2> ... override stream use cases\n" | 
 | 6554 |         "      Use cases applied in descending resolutions. So usecase1 is assigned to the\n" | 
 | 6555 |         "      largest resolution, usecase2 is assigned to the 2nd largest resolution, and so\n" | 
 | 6556 |         "      on. In case the number of usecases is smaller than the number of streams, the\n" | 
 | 6557 |         "      last use case is assigned to all the remaining streams. In case of multiple\n" | 
 | 6558 |         "      streams with the same resolution, the tie-breaker is (JPEG, RAW, YUV, and PRIV)\n" | 
 | 6559 |         "      Valid values are (case sensitive): DEFAULT, PREVIEW, STILL_CAPTURE, VIDEO_RECORD,\n" | 
 | 6560 |         "      PREVIEW_VIDEO_STILL, VIDEO_CALL, CROPPED_RAW\n" | 
 | 6561 |         "  clear-stream-use-case-override clear the stream use case override\n" | 
| Shuzhen Wang | af22e91 | 2023-04-11 16:03:17 -0700 | [diff] [blame] | 6562 |         "  set-zoom-override <-1/0/1> enable or disable zoom override\n" | 
 | 6563 |         "      Valid values -1: do not override, 0: override to OFF, 1: override to ZOOM\n" | 
| Ravneet Dhanjal | ad99ff5 | 2023-07-24 05:21:07 +0000 | [diff] [blame] | 6564 |         "  set-watchdog <VALUE> enables or disables the camera service watchdog\n" | 
 | 6565 |         "      Valid values 0=disable, 1=enable\n" | 
| Avichal Rakesh | 3a85d2d | 2021-11-10 16:21:33 -0800 | [diff] [blame] | 6566 |         "  watch <start|stop|dump|print|clear> manages tag monitoring in connected clients\n" | 
| Svet Ganov | a453d0d | 2018-01-11 15:37:58 -0800 | [diff] [blame] | 6567 |         "  help print this message\n"); | 
 | 6568 | } | 
 | 6569 |  | 
| Avichal Rakesh | 7fbc398 | 2021-10-20 04:35:03 -0700 | [diff] [blame] | 6570 | bool CameraService::isClientWatched(const BasicClient *client) { | 
 | 6571 |     Mutex::Autolock lock(mLogLock); | 
 | 6572 |     return isClientWatchedLocked(client); | 
 | 6573 | } | 
 | 6574 |  | 
 | 6575 | bool CameraService::isClientWatchedLocked(const BasicClient *client) { | 
 | 6576 |     return mWatchedClientPackages.find(kWatchAllClientsFlag) != mWatchedClientPackages.end() || | 
 | 6577 |            mWatchedClientPackages.find(client->getPackageName()) != mWatchedClientPackages.end(); | 
 | 6578 | } | 
 | 6579 |  | 
| Yin-Chia Yeh | dba0323 | 2019-08-19 15:54:28 -0700 | [diff] [blame] | 6580 | int32_t CameraService::updateAudioRestriction() { | 
 | 6581 |     Mutex::Autolock lock(mServiceLock); | 
 | 6582 |     return updateAudioRestrictionLocked(); | 
 | 6583 | } | 
 | 6584 |  | 
 | 6585 | int32_t CameraService::updateAudioRestrictionLocked() { | 
 | 6586 |     int32_t mode = 0; | 
 | 6587 |     // iterate through all active client | 
 | 6588 |     for (const auto& i : mActiveClientManager.getAll()) { | 
 | 6589 |         const auto clientSp = i->getValue(); | 
 | 6590 |         mode |= clientSp->getAudioRestriction(); | 
 | 6591 |     } | 
 | 6592 |  | 
 | 6593 |     bool modeChanged = (mAudioRestriction != mode); | 
 | 6594 |     mAudioRestriction = mode; | 
 | 6595 |     if (modeChanged) { | 
 | 6596 |         mAppOps.setCameraAudioRestriction(mode); | 
 | 6597 |     } | 
 | 6598 |     return mode; | 
 | 6599 | } | 
 | 6600 |  | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6601 | status_t CameraService::checkIfInjectionCameraIsPresent(const std::string& externalCamId, | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 6602 |         sp<BasicClient> clientSp) { | 
 | 6603 |     std::unique_ptr<AutoConditionLock> lock = | 
 | 6604 |             AutoConditionLock::waitAndAcquire(mServiceLockWrapper); | 
 | 6605 |     status_t res = NO_ERROR; | 
 | 6606 |     if ((res = checkIfDeviceIsUsable(externalCamId)) != NO_ERROR) { | 
| Austin Borger | ed99f64 | 2023-06-01 16:51:35 -0700 | [diff] [blame] | 6607 |         ALOGW("Device %s is not usable!", externalCamId.c_str()); | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 6608 |         mInjectionStatusListener->notifyInjectionError( | 
 | 6609 |                 externalCamId, UNKNOWN_TRANSACTION); | 
 | 6610 |         clientSp->notifyError( | 
 | 6611 |                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, | 
 | 6612 |                 CaptureResultExtras()); | 
 | 6613 |  | 
 | 6614 |         // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking | 
 | 6615 |         // other clients from connecting in mServiceLockWrapper if held | 
 | 6616 |         mServiceLock.unlock(); | 
 | 6617 |  | 
 | 6618 |         // Clear caller identity temporarily so client disconnect PID checks work correctly | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 6619 |         int64_t token = clearCallingIdentity(); | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 6620 |         clientSp->disconnect(); | 
| Austin Borger | 22c5c85 | 2024-03-08 13:31:36 -0800 | [diff] [blame] | 6621 |         restoreCallingIdentity(token); | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 6622 |  | 
 | 6623 |         // Reacquire mServiceLock | 
 | 6624 |         mServiceLock.lock(); | 
 | 6625 |     } | 
 | 6626 |  | 
 | 6627 |     return res; | 
 | 6628 | } | 
 | 6629 |  | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 6630 | void CameraService::clearInjectionParameters() { | 
 | 6631 |     { | 
 | 6632 |         Mutex::Autolock lock(mInjectionParametersLock); | 
| Cliff Wu | 646bd61 | 2021-11-23 23:21:29 +0800 | [diff] [blame] | 6633 |         mInjectionInitPending = false; | 
| Cliff Wu | d3a0531 | 2021-04-26 23:07:31 +0800 | [diff] [blame] | 6634 |         mInjectionInternalCamId = ""; | 
 | 6635 |     } | 
 | 6636 |     mInjectionExternalCamId = ""; | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 6637 |     mInjectionStatusListener->removeListener(); | 
| Cliff Wu | d8cae10 | 2021-03-11 01:37:42 +0800 | [diff] [blame] | 6638 | } | 
 | 6639 |  | 
| Biswarup Pal | 37a7518 | 2024-01-16 15:53:35 +0000 | [diff] [blame] | 6640 | } // namespace android |