| 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 | #ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H | 
 | 18 | #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H | 
 | 19 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 20 | #include <cutils/multiuser.h> | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 21 | #include <utils/Vector.h> | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 22 | #include <utils/KeyedVector.h> | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 23 | #include <binder/AppOpsManager.h> | 
| Mathias Agopian | 5462fc9 | 2010-07-14 18:41:18 -0700 | [diff] [blame] | 24 | #include <binder/BinderService.h> | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 25 | #include <binder/IAppOpsCallback.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 26 | #include <camera/ICameraService.h> | 
| Iliyan Malchev | 8951a97 | 2011-04-14 16:55:59 -0700 | [diff] [blame] | 27 | #include <hardware/camera.h> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 28 |  | 
| Igor Murashkin | c073ba5 | 2013-02-26 14:32:34 -0800 | [diff] [blame] | 29 | #include <camera/ICamera.h> | 
 | 30 | #include <camera/ICameraClient.h> | 
| Eino-Ville Talvala | 7b82efe | 2013-07-25 17:12:35 -0700 | [diff] [blame] | 31 | #include <camera/camera2/ICameraDeviceUser.h> | 
 | 32 | #include <camera/camera2/ICameraDeviceCallbacks.h> | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 33 | #include <camera/VendorTagDescriptor.h> | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 34 | #include <camera/CaptureResult.h> | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 35 | #include <camera/CameraParameters.h> | 
| Igor Murashkin | c073ba5 | 2013-02-26 14:32:34 -0800 | [diff] [blame] | 36 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 37 | #include <camera/ICameraServiceListener.h> | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 38 | #include "CameraFlashlight.h" | 
 | 39 |  | 
| Yin-Chia Yeh | e074a93 | 2015-01-30 10:29:02 -0800 | [diff] [blame] | 40 | #include "common/CameraModule.h" | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 41 | #include "utils/AutoConditionLock.h" | 
 | 42 | #include "utils/ClientManager.h" | 
 | 43 | #include "utils/RingBuffer.h" | 
| Yin-Chia Yeh | e074a93 | 2015-01-30 10:29:02 -0800 | [diff] [blame] | 44 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 45 | #include <set> | 
 | 46 | #include <string> | 
 | 47 | #include <map> | 
 | 48 | #include <memory> | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 49 |  | 
 | 50 | namespace android { | 
 | 51 |  | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 52 | extern volatile int32_t gLogLevel; | 
 | 53 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 54 | class MemoryHeapBase; | 
 | 55 | class MediaPlayer; | 
 | 56 |  | 
| Mathias Agopian | 5462fc9 | 2010-07-14 18:41:18 -0700 | [diff] [blame] | 57 | class CameraService : | 
 | 58 |     public BinderService<CameraService>, | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 59 |     public BnCameraService, | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 60 |     public IBinder::DeathRecipient, | 
 | 61 |     public camera_module_callbacks_t | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 62 | { | 
| Mathias Agopian | 5462fc9 | 2010-07-14 18:41:18 -0700 | [diff] [blame] | 63 |     friend class BinderService<CameraService>; | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 64 | public: | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 65 |     class Client; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 66 |     class BasicClient; | 
 | 67 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 68 |     enum apiLevel { | 
 | 69 |         API_1 = 1, | 
 | 70 |         API_2 = 2 | 
 | 71 |     }; | 
 | 72 |  | 
 | 73 |     // Process States (mirrors frameworks/base/core/java/android/app/ActivityManager.java) | 
 | 74 |     static const int PROCESS_STATE_NONEXISTENT = -1; | 
 | 75 |     static const int PROCESS_STATE_PERSISTENT = 0; | 
 | 76 |     static const int PROCESS_STATE_PERSISTENT_UI = 1; | 
 | 77 |     static const int PROCESS_STATE_TOP = 2; | 
 | 78 |     static const int PROCESS_STATE_IMPORTANT_FOREGROUND = 3; | 
 | 79 |     static const int PROCESS_STATE_IMPORTANT_BACKGROUND = 4; | 
 | 80 |     static const int PROCESS_STATE_BACKUP = 5; | 
 | 81 |     static const int PROCESS_STATE_HEAVY_WEIGHT = 6; | 
 | 82 |     static const int PROCESS_STATE_SERVICE = 7; | 
 | 83 |     static const int PROCESS_STATE_RECEIVER = 8; | 
 | 84 |     static const int PROCESS_STATE_HOME = 9; | 
 | 85 |     static const int PROCESS_STATE_LAST_ACTIVITY = 10; | 
 | 86 |     static const int PROCESS_STATE_CACHED_ACTIVITY = 11; | 
 | 87 |     static const int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 12; | 
 | 88 |     static const int PROCESS_STATE_CACHED_EMPTY = 13; | 
 | 89 |  | 
 | 90 |     // 3 second busy timeout when other clients are connecting | 
 | 91 |     static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000; | 
 | 92 |  | 
 | 93 |     // Default number of messages to store in eviction log | 
 | 94 |     static const size_t DEFAULT_EVICTION_LOG_LENGTH = 50; | 
 | 95 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 96 |     enum { | 
 | 97 |         // Default last user id | 
 | 98 |         DEFAULT_LAST_USER_ID = 0, | 
 | 99 |     }; | 
 | 100 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 101 |     // Implementation of BinderService<T> | 
| Mathias Agopian | 5462fc9 | 2010-07-14 18:41:18 -0700 | [diff] [blame] | 102 |     static char const* getServiceName() { return "media.camera"; } | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 103 |  | 
 | 104 |                         CameraService(); | 
 | 105 |     virtual             ~CameraService(); | 
 | 106 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 107 |     ///////////////////////////////////////////////////////////////////// | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 108 |     // HAL Callbacks | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 109 |     virtual void        onDeviceStatusChanged(camera_device_status_t cameraId, | 
 | 110 |                                               camera_device_status_t newStatus); | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 111 |     virtual void        onTorchStatusChanged(const String8& cameraId, | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 112 |                                              ICameraServiceListener::TorchStatus | 
 | 113 |                                                    newStatus); | 
| Igor Murashkin | cba2c16 | 2013-03-20 15:56:31 -0700 | [diff] [blame] | 114 |  | 
 | 115 |     ///////////////////////////////////////////////////////////////////// | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 116 |     // ICameraService | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 117 |     virtual int32_t     getNumberOfCameras(); | 
 | 118 |     virtual status_t    getCameraInfo(int cameraId, | 
 | 119 |                                       struct CameraInfo* cameraInfo); | 
| Zhijun He | 2b59be8 | 2013-09-25 10:14:30 -0700 | [diff] [blame] | 120 |     virtual status_t    getCameraCharacteristics(int cameraId, | 
 | 121 |                                                  CameraMetadata* cameraInfo); | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 122 |     virtual status_t    getCameraVendorTagDescriptor(/*out*/ sp<VendorTagDescriptor>& desc); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 123 |  | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 124 |     virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId, | 
 | 125 |             const String16& clientPackageName, int clientUid, | 
 | 126 |             /*out*/ | 
 | 127 |             sp<ICamera>& device); | 
 | 128 |  | 
| Zhijun He | b10cdad | 2014-06-16 16:38:35 -0700 | [diff] [blame] | 129 |     virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId, | 
 | 130 |             int halVersion, const String16& clientPackageName, int clientUid, | 
 | 131 |             /*out*/ | 
 | 132 |             sp<ICamera>& device); | 
 | 133 |  | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 134 |     virtual status_t connectDevice( | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 135 |             const sp<ICameraDeviceCallbacks>& cameraCb, | 
 | 136 |             int cameraId, | 
 | 137 |             const String16& clientPackageName, | 
| Ruben Brunk | 0f61d8f | 2013-08-08 13:07:18 -0700 | [diff] [blame] | 138 |             int clientUid, | 
 | 139 |             /*out*/ | 
 | 140 |             sp<ICameraDeviceUser>& device); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 141 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 142 |     virtual status_t    addListener(const sp<ICameraServiceListener>& listener); | 
 | 143 |     virtual status_t    removeListener( | 
 | 144 |                                     const sp<ICameraServiceListener>& listener); | 
 | 145 |  | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 146 |     virtual status_t    getLegacyParameters( | 
 | 147 |             int cameraId, | 
 | 148 |             /*out*/ | 
 | 149 |             String16* parameters); | 
 | 150 |  | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 151 |     virtual status_t    setTorchMode(const String16& cameraId, bool enabled, | 
 | 152 |             const sp<IBinder>& clientBinder); | 
 | 153 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 154 |     virtual void notifySystemEvent(int eventId, int arg0); | 
 | 155 |  | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 156 |     // OK = supports api of that version, -EOPNOTSUPP = does not support | 
 | 157 |     virtual status_t    supportsCameraApi( | 
 | 158 |             int cameraId, int apiVersion); | 
 | 159 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 160 |     // Extra permissions checks | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 161 |     virtual status_t    onTransact(uint32_t code, const Parcel& data, | 
 | 162 |                                    Parcel* reply, uint32_t flags); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 163 |  | 
 | 164 |     virtual status_t    dump(int fd, const Vector<String16>& args); | 
 | 165 |  | 
 | 166 |     ///////////////////////////////////////////////////////////////////// | 
 | 167 |     // Client functionality | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 168 |  | 
 | 169 |     enum sound_kind { | 
 | 170 |         SOUND_SHUTTER = 0, | 
 | 171 |         SOUND_RECORDING = 1, | 
 | 172 |         NUM_SOUNDS | 
 | 173 |     }; | 
 | 174 |  | 
 | 175 |     void                loadSound(); | 
 | 176 |     void                playSound(sound_kind kind); | 
 | 177 |     void                releaseSound(); | 
 | 178 |  | 
| Igor Murashkin | 98e2472 | 2013-06-19 19:51:04 -0700 | [diff] [blame] | 179 |     ///////////////////////////////////////////////////////////////////// | 
 | 180 |     // CameraDeviceFactory functionality | 
 | 181 |     int                 getDeviceVersion(int cameraId, int* facing = NULL); | 
 | 182 |  | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 183 |     ///////////////////////////////////////////////////////////////////// | 
 | 184 |     // Shared utilities | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 185 |     static status_t     filterGetInfoErrorCode(status_t err); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 186 |  | 
 | 187 |     ///////////////////////////////////////////////////////////////////// | 
 | 188 |     // CameraClient functionality | 
 | 189 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 190 |     class BasicClient : public virtual RefBase { | 
 | 191 |     public: | 
| Yin-Chia Yeh | e074a93 | 2015-01-30 10:29:02 -0800 | [diff] [blame] | 192 |         virtual status_t    initialize(CameraModule *module) = 0; | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 193 |         virtual void        disconnect(); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 194 |  | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 195 |         // because we can't virtually inherit IInterface, which breaks | 
 | 196 |         // virtual inheritance | 
 | 197 |         virtual sp<IBinder> asBinderWrapper() = 0; | 
 | 198 |  | 
| Ruben Brunk | 9efdf95 | 2015-03-18 23:11:57 -0700 | [diff] [blame] | 199 |         // Return the remote callback binder object (e.g. ICameraDeviceCallbacks) | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 200 |         sp<IBinder>         getRemote() { | 
| Igor Murashkin | 44cfcf0 | 2013-03-01 16:22:28 -0800 | [diff] [blame] | 201 |             return mRemoteBinder; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 202 |         } | 
 | 203 |  | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 204 |         virtual status_t    dump(int fd, const Vector<String16>& args) = 0; | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 205 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 206 |         // Return the package name for this client | 
 | 207 |         virtual String16 getPackageName() const; | 
 | 208 |  | 
 | 209 |         // Notify client about a fatal error | 
 | 210 |         virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, | 
 | 211 |                 const CaptureResultExtras& resultExtras) = 0; | 
 | 212 |  | 
 | 213 |         // Get the PID of the application client using this | 
 | 214 |         virtual int getClientPid() const; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 215 |     protected: | 
 | 216 |         BasicClient(const sp<CameraService>& cameraService, | 
 | 217 |                 const sp<IBinder>& remoteCallback, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 218 |                 const String16& clientPackageName, | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 219 |                 int cameraId, | 
 | 220 |                 int cameraFacing, | 
 | 221 |                 int clientPid, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 222 |                 uid_t clientUid, | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 223 |                 int servicePid); | 
 | 224 |  | 
 | 225 |         virtual ~BasicClient(); | 
 | 226 |  | 
 | 227 |         // the instance is in the middle of destruction. When this is set, | 
 | 228 |         // the instance should not be accessed from callback. | 
 | 229 |         // CameraService's mClientLock should be acquired to access this. | 
 | 230 |         // - subclasses should set this to true in their destructors. | 
 | 231 |         bool                            mDestructionStarted; | 
 | 232 |  | 
 | 233 |         // these are initialized in the constructor. | 
 | 234 |         sp<CameraService>               mCameraService;  // immutable after constructor | 
 | 235 |         int                             mCameraId;       // immutable after constructor | 
 | 236 |         int                             mCameraFacing;   // immutable after constructor | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 237 |         const String16                  mClientPackageName; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 238 |         pid_t                           mClientPid; | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 239 |         uid_t                           mClientUid;      // immutable after constructor | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 240 |         pid_t                           mServicePid;     // immutable after constructor | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 241 |         bool                            mDisconnected; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 242 |  | 
 | 243 |         // - The app-side Binder interface to receive callbacks from us | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 244 |         sp<IBinder>                     mRemoteBinder;   // immutable after constructor | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 245 |  | 
 | 246 |         // permissions management | 
 | 247 |         status_t                        startCameraOps(); | 
 | 248 |         status_t                        finishCameraOps(); | 
 | 249 |  | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 250 |     private: | 
 | 251 |         AppOpsManager                   mAppOpsManager; | 
 | 252 |  | 
 | 253 |         class OpsCallback : public BnAppOpsCallback { | 
 | 254 |         public: | 
 | 255 |             OpsCallback(wp<BasicClient> client); | 
 | 256 |             virtual void opChanged(int32_t op, const String16& packageName); | 
 | 257 |  | 
 | 258 |         private: | 
 | 259 |             wp<BasicClient> mClient; | 
 | 260 |  | 
 | 261 |         }; // class OpsCallback | 
 | 262 |  | 
 | 263 |         sp<OpsCallback> mOpsCallback; | 
 | 264 |         // Track whether startCameraOps was called successfully, to avoid | 
 | 265 |         // finishing what we didn't start. | 
 | 266 |         bool            mOpsActive; | 
 | 267 |  | 
 | 268 |         // IAppOpsCallback interface, indirected through opListener | 
 | 269 |         virtual void opChanged(int32_t op, const String16& packageName); | 
 | 270 |     }; // class BasicClient | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 271 |  | 
 | 272 |     class Client : public BnCamera, public BasicClient | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 273 |     { | 
 | 274 |     public: | 
| Igor Murashkin | 44cfcf0 | 2013-03-01 16:22:28 -0800 | [diff] [blame] | 275 |         typedef ICameraClient TCamCallbacks; | 
 | 276 |  | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 277 |         // ICamera interface (see ICamera for details) | 
 | 278 |         virtual void          disconnect(); | 
 | 279 |         virtual status_t      connect(const sp<ICameraClient>& client) = 0; | 
 | 280 |         virtual status_t      lock() = 0; | 
 | 281 |         virtual status_t      unlock() = 0; | 
| Eino-Ville Talvala | 1ce7c34 | 2013-08-21 13:57:21 -0700 | [diff] [blame] | 282 |         virtual status_t      setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)=0; | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 283 |         virtual void          setPreviewCallbackFlag(int flag) = 0; | 
| Eino-Ville Talvala | 3ee3550 | 2013-04-02 15:45:11 -0700 | [diff] [blame] | 284 |         virtual status_t      setPreviewCallbackTarget( | 
 | 285 |                 const sp<IGraphicBufferProducer>& callbackProducer) = 0; | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 286 |         virtual status_t      startPreview() = 0; | 
 | 287 |         virtual void          stopPreview() = 0; | 
 | 288 |         virtual bool          previewEnabled() = 0; | 
 | 289 |         virtual status_t      storeMetaDataInBuffers(bool enabled) = 0; | 
 | 290 |         virtual status_t      startRecording() = 0; | 
 | 291 |         virtual void          stopRecording() = 0; | 
 | 292 |         virtual bool          recordingEnabled() = 0; | 
 | 293 |         virtual void          releaseRecordingFrame(const sp<IMemory>& mem) = 0; | 
 | 294 |         virtual status_t      autoFocus() = 0; | 
 | 295 |         virtual status_t      cancelAutoFocus() = 0; | 
 | 296 |         virtual status_t      takePicture(int msgType) = 0; | 
 | 297 |         virtual status_t      setParameters(const String8& params) = 0; | 
 | 298 |         virtual String8       getParameters() const = 0; | 
 | 299 |         virtual status_t      sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; | 
 | 300 |  | 
 | 301 |         // Interface used by CameraService | 
 | 302 |         Client(const sp<CameraService>& cameraService, | 
 | 303 |                 const sp<ICameraClient>& cameraClient, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 304 |                 const String16& clientPackageName, | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 305 |                 int cameraId, | 
 | 306 |                 int cameraFacing, | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 307 |                 int clientPid, | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 308 |                 uid_t clientUid, | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 309 |                 int servicePid); | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 310 |         ~Client(); | 
 | 311 |  | 
 | 312 |         // return our camera client | 
| Igor Murashkin | 44cfcf0 | 2013-03-01 16:22:28 -0800 | [diff] [blame] | 313 |         const sp<ICameraClient>&    getRemoteCallback() { | 
 | 314 |             return mRemoteCallback; | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 315 |         } | 
 | 316 |  | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 317 |         virtual sp<IBinder> asBinderWrapper() { | 
| Marco Nelissen | 06b4606 | 2014-11-14 07:58:25 -0800 | [diff] [blame] | 318 |             return asBinder(this); | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 319 |         } | 
 | 320 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 321 |         virtual void         notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, | 
 | 322 |                                          const CaptureResultExtras& resultExtras); | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 323 |     protected: | 
 | 324 |         // Convert client from cookie. | 
 | 325 |         static sp<CameraService::Client> getClientFromCookie(void* user); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 326 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 327 |         // Initialized in constructor | 
| Eino-Ville Talvala | 5e08d60 | 2012-05-16 14:59:25 -0700 | [diff] [blame] | 328 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 329 |         // - The app-side Binder interface to receive callbacks from us | 
| Igor Murashkin | 44cfcf0 | 2013-03-01 16:22:28 -0800 | [diff] [blame] | 330 |         sp<ICameraClient>               mRemoteCallback; | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 331 |  | 
 | 332 |     }; // class Client | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 333 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 334 |     typedef std::shared_ptr<resource_policy::ClientDescriptor<String8, | 
 | 335 |             sp<CameraService::BasicClient>>> DescriptorPtr; | 
 | 336 |  | 
 | 337 |     /** | 
 | 338 |      * A container class for managing active camera clients that are using HAL devices.  Active | 
 | 339 |      * clients are represented by ClientDescriptor objects that contain strong pointers to the | 
 | 340 |      * actual BasicClient subclass binder interface implementation. | 
 | 341 |      * | 
 | 342 |      * This class manages the eviction behavior for the camera clients.  See the parent class | 
 | 343 |      * implementation in utils/ClientManager for the specifics of this behavior. | 
 | 344 |      */ | 
 | 345 |     class CameraClientManager : | 
 | 346 |             public resource_policy::ClientManager<String8, sp<CameraService::BasicClient>> { | 
 | 347 |     public: | 
 | 348 |         virtual ~CameraClientManager(); | 
 | 349 |  | 
 | 350 |         /** | 
 | 351 |          * Return a strong pointer to the active BasicClient for this camera ID, or an empty | 
 | 352 |          * if none exists. | 
 | 353 |          */ | 
 | 354 |         sp<CameraService::BasicClient> getCameraClient(const String8& id) const; | 
 | 355 |  | 
 | 356 |         /** | 
 | 357 |          * Return a string describing the current state. | 
 | 358 |          */ | 
 | 359 |         String8 toString() const; | 
 | 360 |  | 
 | 361 |         /** | 
 | 362 |          * Make a ClientDescriptor object wrapping the given BasicClient strong pointer. | 
 | 363 |          */ | 
 | 364 |         static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value, | 
 | 365 |                 int32_t cost, const std::set<String8>& conflictingKeys, int32_t priority, | 
 | 366 |                 int32_t ownerId); | 
 | 367 |  | 
 | 368 |         /** | 
 | 369 |          * Make a ClientDescriptor object wrapping the given BasicClient strong pointer with | 
 | 370 |          * values intialized from a prior ClientDescriptor. | 
 | 371 |          */ | 
 | 372 |         static DescriptorPtr makeClientDescriptor(const sp<BasicClient>& value, | 
 | 373 |                 const CameraService::DescriptorPtr& partial); | 
 | 374 |  | 
 | 375 |     }; // class CameraClientManager | 
 | 376 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 377 | private: | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 378 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 379 |     /** | 
 | 380 |      * Container class for the state of each logical camera device, including: ID, status, and | 
 | 381 |      * dependencies on other devices.  The mapping of camera ID -> state saved in mCameraStates | 
 | 382 |      * represents the camera devices advertised by the HAL (and any USB devices, when we add | 
 | 383 |      * those). | 
 | 384 |      * | 
 | 385 |      * This container does NOT represent an active camera client.  These are represented using | 
 | 386 |      * the ClientDescriptors stored in mActiveClientManager. | 
 | 387 |      */ | 
 | 388 |     class CameraState { | 
 | 389 |     public: | 
 | 390 |         /** | 
 | 391 |          * Make a new CameraState and set the ID, cost, and conflicting devices using the values | 
 | 392 |          * returned in the HAL's camera_info struct for each device. | 
 | 393 |          */ | 
 | 394 |         CameraState(const String8& id, int cost, const std::set<String8>& conflicting); | 
 | 395 |         virtual ~CameraState(); | 
 | 396 |  | 
 | 397 |         /** | 
 | 398 |          * Return the status for this device. | 
 | 399 |          * | 
 | 400 |          * This method acquires mStatusLock. | 
 | 401 |          */ | 
 | 402 |         ICameraServiceListener::Status getStatus() const; | 
 | 403 |  | 
 | 404 |         /** | 
 | 405 |          * This function updates the status for this camera device, unless the given status | 
 | 406 |          * is in the given list of rejected status states, and execute the function passed in | 
 | 407 |          * with a signature onStatusUpdateLocked(const String8&, ICameraServiceListener::Status) | 
 | 408 |          * if the status has changed. | 
 | 409 |          * | 
 | 410 |          * This method is idempotent, and will not result in the function passed to | 
 | 411 |          * onStatusUpdateLocked being called more than once for the same arguments. | 
 | 412 |          * This method aquires mStatusLock. | 
 | 413 |          */ | 
 | 414 |         template<class Func> | 
 | 415 |         void updateStatus(ICameraServiceListener::Status status, const String8& cameraId, | 
 | 416 |                 std::initializer_list<ICameraServiceListener::Status> rejectSourceStates, | 
 | 417 |                 Func onStatusUpdatedLocked); | 
 | 418 |  | 
 | 419 |         /** | 
 | 420 |          * Return the last set CameraParameters object generated from the information returned by | 
 | 421 |          * the HAL for this device (or an empty CameraParameters object if none has been set). | 
 | 422 |          */ | 
 | 423 |         CameraParameters getShimParams() const; | 
 | 424 |  | 
 | 425 |         /** | 
 | 426 |          * Set the CameraParameters for this device. | 
 | 427 |          */ | 
 | 428 |         void setShimParams(const CameraParameters& params); | 
 | 429 |  | 
 | 430 |         /** | 
 | 431 |          * Return the resource_cost advertised by the HAL for this device. | 
 | 432 |          */ | 
 | 433 |         int getCost() const; | 
 | 434 |  | 
 | 435 |         /** | 
 | 436 |          * Return a set of the IDs of conflicting devices advertised by the HAL for this device. | 
 | 437 |          */ | 
 | 438 |         std::set<String8> getConflicting() const; | 
 | 439 |  | 
 | 440 |         /** | 
 | 441 |          * Return the ID of this camera device. | 
 | 442 |          */ | 
 | 443 |         String8 getId() const; | 
 | 444 |  | 
 | 445 |     private: | 
 | 446 |         const String8 mId; | 
 | 447 |         ICameraServiceListener::Status mStatus; // protected by mStatusLock | 
 | 448 |         const int mCost; | 
 | 449 |         std::set<String8> mConflicting; | 
 | 450 |         mutable Mutex mStatusLock; | 
 | 451 |         CameraParameters mShimParams; | 
 | 452 |     }; // class CameraState | 
 | 453 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 454 |     // Delay-load the Camera HAL module | 
 | 455 |     virtual void onFirstRef(); | 
 | 456 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 457 |     // Check if we can connect, before we acquire the service lock. | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 458 |     status_t validateConnectLocked(const String8& cameraId, /*inout*/int& clientUid) const; | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 459 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 460 |     // Handle active client evictions, and update service state. | 
 | 461 |     // Only call with with mServiceLock held. | 
 | 462 |     status_t handleEvictionsLocked(const String8& cameraId, int clientPid, | 
 | 463 |         apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName, | 
 | 464 |         /*out*/ | 
 | 465 |         sp<BasicClient>* client, | 
 | 466 |         std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial); | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 467 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 468 |     // Single implementation shared between the various connect calls | 
 | 469 |     template<class CALLBACK, class CLIENT> | 
 | 470 |     status_t connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, int halVersion, | 
 | 471 |             const String16& clientPackageName, int clientUid, apiLevel effectiveApiLevel, | 
 | 472 |             bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device); | 
| Igor Murashkin | e6800ce | 2013-03-04 17:25:57 -0800 | [diff] [blame] | 473 |  | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 474 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 475 |     // Lock guarding camera service state | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 476 |     Mutex               mServiceLock; | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 477 |  | 
 | 478 |     // Condition to use with mServiceLock, used to handle simultaneous connect calls from clients | 
 | 479 |     std::shared_ptr<WaitableMutexWrapper> mServiceLockWrapper; | 
 | 480 |  | 
 | 481 |     // Return NO_ERROR if the device with a give ID can be connected to | 
 | 482 |     status_t checkIfDeviceIsUsable(const String8& cameraId) const; | 
 | 483 |  | 
 | 484 |     // Container for managing currently active application-layer clients | 
 | 485 |     CameraClientManager mActiveClientManager; | 
 | 486 |  | 
 | 487 |     // Mapping from camera ID -> state for each device, map is protected by mCameraStatesLock | 
 | 488 |     std::map<String8, std::shared_ptr<CameraState>> mCameraStates; | 
 | 489 |  | 
 | 490 |     // Mutex guarding mCameraStates map | 
 | 491 |     mutable Mutex mCameraStatesLock; | 
 | 492 |  | 
 | 493 |     // Circular buffer for storing event logging for dumps | 
 | 494 |     RingBuffer<String8> mEventLog; | 
 | 495 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 496 |     // UID of last user. | 
 | 497 |     int mLastUserId; | 
 | 498 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 499 |     /** | 
 | 500 |      * Get the camera state for a given camera id. | 
 | 501 |      * | 
 | 502 |      * This acquires mCameraStatesLock. | 
 | 503 |      */ | 
 | 504 |     std::shared_ptr<CameraService::CameraState> getCameraState(const String8& cameraId) const; | 
 | 505 |  | 
 | 506 |     /** | 
 | 507 |      * Evict client who's remote binder has died.  Returns true if this client was in the active | 
 | 508 |      * list and was disconnected. | 
 | 509 |      * | 
 | 510 |      * This method acquires mServiceLock. | 
 | 511 |      */ | 
 | 512 |     bool evictClientIdByRemote(const wp<IBinder>& cameraClient); | 
 | 513 |  | 
 | 514 |     /** | 
 | 515 |      * Remove the given client from the active clients list; does not disconnect the client. | 
 | 516 |      * | 
 | 517 |      * This method acquires mServiceLock. | 
 | 518 |      */ | 
 | 519 |     void removeByClient(const BasicClient* client); | 
 | 520 |  | 
 | 521 |     /** | 
 | 522 |      * Add new client to active clients list after conflicting clients have disconnected using the | 
 | 523 |      * values set in the partial descriptor passed in to construct the actual client descriptor. | 
 | 524 |      * This is typically called at the end of a connect call. | 
 | 525 |      * | 
 | 526 |      * This method must be called with mServiceLock held. | 
 | 527 |      */ | 
 | 528 |     void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc); | 
 | 529 |  | 
 | 530 |     /** | 
 | 531 |      * Returns the integer corresponding to the given camera ID string, or -1 on failure. | 
 | 532 |      */ | 
 | 533 |     static int cameraIdToInt(const String8& cameraId); | 
 | 534 |  | 
 | 535 |     /** | 
 | 536 |      * Remove a single client corresponding to the given camera id from the list of active clients. | 
 | 537 |      * If none exists, return an empty strongpointer. | 
 | 538 |      * | 
 | 539 |      * This method must be called with mServiceLock held. | 
 | 540 |      */ | 
 | 541 |     sp<CameraService::BasicClient> removeClientLocked(const String8& cameraId); | 
 | 542 |  | 
 | 543 |     /** | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 544 |      * Handle a notification that the current device user has changed. | 
 | 545 |      */ | 
 | 546 |     void doUserSwitch(int newUserId); | 
 | 547 |  | 
 | 548 |     /** | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 549 |      * Add a event log message that a client has been disconnected. | 
 | 550 |      */ | 
 | 551 |     void logDisconnected(const String8& cameraId, int clientPid, const String8& clientPackage); | 
 | 552 |  | 
 | 553 |     /** | 
 | 554 |      * Add a event log message that a client has been connected. | 
 | 555 |      */ | 
 | 556 |     void logConnected(const String8& cameraId, int clientPid, const String8& clientPackage); | 
 | 557 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 558 |     int                 mNumberOfCameras; | 
 | 559 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 560 |     // sounds | 
| Chih-Chung Chang | ff4f55c | 2011-10-17 19:03:12 +0800 | [diff] [blame] | 561 |     MediaPlayer*        newMediaPlayer(const char *file); | 
 | 562 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 563 |     Mutex               mSoundLock; | 
 | 564 |     sp<MediaPlayer>     mSoundPlayer[NUM_SOUNDS]; | 
 | 565 |     int                 mSoundRef;  // reference count (release all MediaPlayer when 0) | 
 | 566 |  | 
| Yin-Chia Yeh | e074a93 | 2015-01-30 10:29:02 -0800 | [diff] [blame] | 567 |     CameraModule*     mModule; | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 568 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 569 |     // Guarded by mStatusListenerMutex | 
 | 570 |     std::vector<sp<ICameraServiceListener>> mListenerList; | 
 | 571 |     Mutex       mStatusListenerLock; | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 572 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 573 |     /** | 
 | 574 |      * Update the status for the given camera id (if that device exists), and broadcast the | 
 | 575 |      * status update to all current ICameraServiceListeners if the status has changed.  Any | 
 | 576 |      * statuses in rejectedSourceStates will be ignored. | 
 | 577 |      * | 
 | 578 |      * This method must be idempotent. | 
 | 579 |      * This method acquires mStatusLock and mStatusListenerLock. | 
 | 580 |      */ | 
 | 581 |     void updateStatus(ICameraServiceListener::Status status, const String8& cameraId, | 
 | 582 |             std::initializer_list<ICameraServiceListener::Status> rejectedSourceStates); | 
 | 583 |     void updateStatus(ICameraServiceListener::Status status, const String8& cameraId); | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 584 |  | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 585 |     // flashlight control | 
 | 586 |     sp<CameraFlashlight> mFlashlight; | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 587 |     // guard mTorchStatusMap | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 588 |     Mutex                mTorchStatusMutex; | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 589 |     // guard mTorchClientMap | 
 | 590 |     Mutex                mTorchClientMapMutex; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 591 |     // camera id -> torch status | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 592 |     KeyedVector<String8, ICameraServiceListener::TorchStatus> mTorchStatusMap; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 593 |     // camera id -> torch client binder | 
 | 594 |     // only store the last client that turns on each camera's torch mode | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 595 |     KeyedVector<String8, sp<IBinder> > mTorchClientMap; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 596 |  | 
 | 597 |     // check and handle if torch client's process has died | 
 | 598 |     void handleTorchClientBinderDied(const wp<IBinder> &who); | 
 | 599 |  | 
 | 600 |     // handle torch mode status change and invoke callbacks. mTorchStatusMutex | 
 | 601 |     // should be locked. | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 602 |     void onTorchStatusChangedLocked(const String8& cameraId, | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 603 |             ICameraServiceListener::TorchStatus newStatus); | 
 | 604 |  | 
 | 605 |     // get a camera's torch status. mTorchStatusMutex should be locked. | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 606 |     status_t getTorchStatusLocked(const String8 &cameraId, | 
 | 607 |             ICameraServiceListener::TorchStatus *status) const; | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 608 |  | 
 | 609 |     // set a camera's torch status. mTorchStatusMutex should be locked. | 
| Chien-Yu Chen | 88da526 | 2015-02-17 13:56:46 -0800 | [diff] [blame] | 610 |     status_t setTorchStatusLocked(const String8 &cameraId, | 
| Chien-Yu Chen | 3068d73 | 2015-02-09 13:29:57 -0800 | [diff] [blame] | 611 |             ICameraServiceListener::TorchStatus status); | 
 | 612 |  | 
| Igor Murashkin | ecf17e8 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 613 |     // IBinder::DeathRecipient implementation | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 614 |     virtual void        binderDied(const wp<IBinder> &who); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 615 |  | 
 | 616 |     // Helpers | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 617 |  | 
| Ruben Brunk | d1176ef | 2014-02-21 10:51:38 -0800 | [diff] [blame] | 618 |     bool                setUpVendorTags(); | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 619 |  | 
 | 620 |     /** | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 621 |      * Initialize and cache the metadata used by the HAL1 shim for a given cameraId. | 
 | 622 |      * | 
 | 623 |      * Returns OK on success, or a negative error code. | 
 | 624 |      */ | 
 | 625 |     status_t            initializeShimMetadata(int cameraId); | 
 | 626 |  | 
 | 627 |     /** | 
| Igor Murashkin | 65d14b9 | 2014-06-17 12:03:20 -0700 | [diff] [blame] | 628 |      * Get the cached CameraParameters for the camera. If they haven't been | 
 | 629 |      * cached yet, then initialize them for the first time. | 
 | 630 |      * | 
 | 631 |      * Returns OK on success, or a negative error code. | 
 | 632 |      */ | 
 | 633 |     status_t            getLegacyParametersLazy(int cameraId, /*out*/CameraParameters* parameters); | 
 | 634 |  | 
 | 635 |     /** | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 636 |      * Generate the CameraCharacteristics metadata required by the Camera2 API | 
 | 637 |      * from the available HAL1 CameraParameters and CameraInfo. | 
 | 638 |      * | 
 | 639 |      * Returns OK on success, or a negative error code. | 
 | 640 |      */ | 
 | 641 |     status_t            generateShimMetadata(int cameraId, /*out*/CameraMetadata* cameraInfo); | 
 | 642 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 643 |     static int getCallingPid(); | 
 | 644 |  | 
 | 645 |     static int getCallingUid(); | 
 | 646 |  | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 647 |     /** | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 648 |      * Get the current system time as a formatted string. | 
| Ruben Brunk | b2119af | 2014-05-09 19:57:56 -0700 | [diff] [blame] | 649 |      */ | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 650 |     static String8 getFormattedCurrentTime(); | 
 | 651 |  | 
 | 652 |     /** | 
 | 653 |      * Get the camera eviction priority from the current process state given by ActivityManager. | 
 | 654 |      */ | 
 | 655 |     static int getCameraPriorityFromProcState(int procState); | 
 | 656 |  | 
 | 657 |     static status_t makeClient(const sp<CameraService>& cameraService, | 
 | 658 |             const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId, | 
 | 659 |             int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode, | 
 | 660 |             int halVersion, int deviceVersion, apiLevel effectiveApiLevel, | 
 | 661 |             /*out*/sp<BasicClient>* client); | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 662 | }; | 
 | 663 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 664 | template<class Func> | 
 | 665 | void CameraService::CameraState::updateStatus(ICameraServiceListener::Status status, | 
 | 666 |         const String8& cameraId, | 
 | 667 |         std::initializer_list<ICameraServiceListener::Status> rejectSourceStates, | 
 | 668 |         Func onStatusUpdatedLocked) { | 
 | 669 |     Mutex::Autolock lock(mStatusLock); | 
 | 670 |     ICameraServiceListener::Status oldStatus = mStatus; | 
 | 671 |     mStatus = status; | 
 | 672 |  | 
 | 673 |     if (oldStatus == status) { | 
 | 674 |         return; | 
 | 675 |     } | 
 | 676 |  | 
 | 677 |     ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__, | 
 | 678 |             cameraId.string(), oldStatus, status); | 
 | 679 |  | 
 | 680 |     if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT && | 
 | 681 |         (status != ICameraServiceListener::STATUS_PRESENT && | 
 | 682 |          status != ICameraServiceListener::STATUS_ENUMERATING)) { | 
 | 683 |  | 
 | 684 |         ALOGW("%s: From NOT_PRESENT can only transition into PRESENT or ENUMERATING", | 
 | 685 |                 __FUNCTION__); | 
 | 686 |         mStatus = oldStatus; | 
 | 687 |         return; | 
 | 688 |     } | 
 | 689 |  | 
 | 690 |     /** | 
 | 691 |      * Sometimes we want to conditionally do a transition. | 
 | 692 |      * For example if a client disconnects, we want to go to PRESENT | 
 | 693 |      * only if we weren't already in NOT_PRESENT or ENUMERATING. | 
 | 694 |      */ | 
 | 695 |     for (auto& rejectStatus : rejectSourceStates) { | 
 | 696 |         if (oldStatus == rejectStatus) { | 
 | 697 |             ALOGV("%s: Rejecting status transition for Camera ID %s,  since the source " | 
 | 698 |                     "state was was in one of the bad states.", __FUNCTION__, cameraId.string()); | 
 | 699 |             mStatus = oldStatus; | 
 | 700 |             return; | 
 | 701 |         } | 
 | 702 |     } | 
 | 703 |  | 
 | 704 |     onStatusUpdatedLocked(cameraId, status); | 
 | 705 | } | 
 | 706 |  | 
 | 707 |  | 
 | 708 | template<class CALLBACK, class CLIENT> | 
 | 709 | status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, | 
 | 710 |         int halVersion, const String16& clientPackageName, int clientUid, | 
 | 711 |         apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, | 
 | 712 |         /*out*/sp<CLIENT>& device) { | 
 | 713 |     status_t ret = NO_ERROR; | 
 | 714 |     String8 clientName8(clientPackageName); | 
 | 715 |     int clientPid = getCallingPid(); | 
 | 716 |  | 
 | 717 |     ALOGI("CameraService::connect call E (PID %d \"%s\", camera ID %s) for HAL version %d and " | 
 | 718 |             "Camera API version %d", clientPid, clientName8.string(), cameraId.string(), | 
 | 719 |             halVersion, static_cast<int>(effectiveApiLevel)); | 
 | 720 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 721 |     sp<CLIENT> client = nullptr; | 
 | 722 |     { | 
 | 723 |         // Acquire mServiceLock and prevent other clients from connecting | 
 | 724 |         std::unique_ptr<AutoConditionLock> lock = | 
 | 725 |                 AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS); | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 726 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 727 |         if (lock == nullptr) { | 
 | 728 |             ALOGE("CameraService::connect X (PID %d) rejected (too many other clients connecting)." | 
 | 729 |                     , clientPid); | 
 | 730 |             return -EBUSY; | 
 | 731 |         } | 
 | 732 |  | 
| Ruben Brunk | 36597b2 | 2015-03-20 22:15:57 -0700 | [diff] [blame] | 733 |         // Enforce client permissions and do basic sanity checks | 
 | 734 |         if((ret = validateConnectLocked(cameraId, /*inout*/clientUid)) != NO_ERROR) { | 
 | 735 |             return ret; | 
 | 736 |         } | 
 | 737 |         mLastUserId = multiuser_get_user_id(clientUid); | 
 | 738 |  | 
| Ruben Brunk | cc77671 | 2015-02-17 20:18:47 -0800 | [diff] [blame] | 739 |         // Check the shim parameters after acquiring lock, if they have already been updated and | 
 | 740 |         // we were doing a shim update, return immediately | 
 | 741 |         if (shimUpdateOnly) { | 
 | 742 |             auto cameraState = getCameraState(cameraId); | 
 | 743 |             if (cameraState != nullptr) { | 
 | 744 |                 if (!cameraState->getShimParams().isEmpty()) return NO_ERROR; | 
 | 745 |             } | 
 | 746 |         } | 
 | 747 |  | 
 | 748 |         sp<BasicClient> clientTmp = nullptr; | 
 | 749 |         std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial; | 
 | 750 |         if ((ret = handleEvictionsLocked(cameraId, clientPid, effectiveApiLevel, | 
 | 751 |                 IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp, | 
 | 752 |                 /*out*/&partial)) != NO_ERROR) { | 
 | 753 |             return ret; | 
 | 754 |         } | 
 | 755 |  | 
 | 756 |         if (clientTmp.get() != nullptr) { | 
 | 757 |             // Handle special case for API1 MediaRecorder where the existing client is returned | 
 | 758 |             device = static_cast<CLIENT*>(clientTmp.get()); | 
 | 759 |             return NO_ERROR; | 
 | 760 |         } | 
 | 761 |  | 
 | 762 |         // give flashlight a chance to close devices if necessary. | 
 | 763 |         mFlashlight->prepareDeviceOpen(cameraId); | 
 | 764 |  | 
 | 765 |         // TODO: Update getDeviceVersion + HAL interface to use strings for Camera IDs | 
 | 766 |         int id = cameraIdToInt(cameraId); | 
 | 767 |         if (id == -1) { | 
 | 768 |             ALOGE("%s: Invalid camera ID %s, cannot get device version from HAL.", __FUNCTION__, | 
 | 769 |                     cameraId.string()); | 
 | 770 |             return BAD_VALUE; | 
 | 771 |         } | 
 | 772 |  | 
 | 773 |         int facing = -1; | 
 | 774 |         int deviceVersion = getDeviceVersion(id, /*out*/&facing); | 
 | 775 |         sp<BasicClient> tmp = nullptr; | 
 | 776 |         if((ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid, | 
 | 777 |                 clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, | 
 | 778 |                 /*out*/&tmp)) != NO_ERROR) { | 
 | 779 |             return ret; | 
 | 780 |         } | 
 | 781 |         client = static_cast<CLIENT*>(tmp.get()); | 
 | 782 |  | 
 | 783 |         LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state", | 
 | 784 |                 __FUNCTION__); | 
 | 785 |  | 
 | 786 |         if ((ret = client->initialize(mModule)) != OK) { | 
 | 787 |             ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__); | 
 | 788 |             return ret; | 
 | 789 |         } | 
 | 790 |  | 
 | 791 |         sp<IBinder> remoteCallback = client->getRemote(); | 
 | 792 |         if (remoteCallback != nullptr) { | 
 | 793 |             remoteCallback->linkToDeath(this); | 
 | 794 |         } | 
 | 795 |  | 
 | 796 |         // Update shim paremeters for legacy clients | 
 | 797 |         if (effectiveApiLevel == API_1) { | 
 | 798 |             // Assume we have always received a Client subclass for API1 | 
 | 799 |             sp<Client> shimClient = reinterpret_cast<Client*>(client.get()); | 
 | 800 |             String8 rawParams = shimClient->getParameters(); | 
 | 801 |             CameraParameters params(rawParams); | 
 | 802 |  | 
 | 803 |             auto cameraState = getCameraState(cameraId); | 
 | 804 |             if (cameraState != nullptr) { | 
 | 805 |                 cameraState->setShimParams(params); | 
 | 806 |             } else { | 
 | 807 |                 ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.", | 
 | 808 |                         __FUNCTION__, cameraId.string()); | 
 | 809 |             } | 
 | 810 |         } | 
 | 811 |  | 
 | 812 |         if (shimUpdateOnly) { | 
 | 813 |             // If only updating legacy shim parameters, immediately disconnect client | 
 | 814 |             mServiceLock.unlock(); | 
 | 815 |             client->disconnect(); | 
 | 816 |             mServiceLock.lock(); | 
 | 817 |         } else { | 
 | 818 |             // Otherwise, add client to active clients list | 
 | 819 |             finishConnectLocked(client, partial); | 
 | 820 |         } | 
 | 821 |     } // lock is destroyed, allow further connect calls | 
 | 822 |  | 
 | 823 |     // Important: release the mutex here so the client can call back into the service from its | 
 | 824 |     // destructor (can be at the end of the call) | 
 | 825 |     device = client; | 
 | 826 |     return NO_ERROR; | 
 | 827 | } | 
 | 828 |  | 
| Mathias Agopian | 65ab471 | 2010-07-14 17:59:35 -0700 | [diff] [blame] | 829 | } // namespace android | 
 | 830 |  | 
 | 831 | #endif |