blob: 5c6f653afcc039fe5ef2f575c1be8e395c983e3c [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -07001/*
Ruben Brunkd1176ef2014-02-21 10:51:38 -08002 * 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 Agopian65ab4712010-07-14 17:59:35 -070016
17#define LOG_TAG "CameraService"
Iliyan Malchev8951a972011-04-14 16:55:59 -070018//#define LOG_NDEBUG 0
Mathias Agopian65ab4712010-07-14 17:59:35 -070019
20#include <stdio.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080021#include <string.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070022#include <sys/types.h>
23#include <pthread.h>
24
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080025#include <binder/AppOpsManager.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070026#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28#include <binder/MemoryBase.h>
29#include <binder/MemoryHeapBase.h>
30#include <cutils/atomic.h>
Nipun Kwatrab5ca4612010-09-11 19:31:10 -070031#include <cutils/properties.h>
Mathias Agopiandf712ea2012-02-25 18:48:35 -080032#include <gui/Surface.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070033#include <hardware/hardware.h>
34#include <media/AudioSystem.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080035#include <media/IMediaHTTPService.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070036#include <media/mediaplayer.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070037#include <utils/Errors.h>
38#include <utils/Log.h>
39#include <utils/String16.h>
Ruben Brunkd1176ef2014-02-21 10:51:38 -080040#include <utils/Trace.h>
41#include <system/camera_vendor_tags.h>
Mathias Agopian65ab4712010-07-14 17:59:35 -070042
43#include "CameraService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070044#include "api1/CameraClient.h"
45#include "api1/Camera2Client.h"
46#include "api_pro/ProCamera2Client.h"
47#include "api2/CameraDeviceClient.h"
Igor Murashkinff3e31d2013-10-23 16:40:06 -070048#include "utils/CameraTraces.h"
Igor Murashkin98e24722013-06-19 19:51:04 -070049#include "CameraDeviceFactory.h"
Mathias Agopian65ab4712010-07-14 17:59:35 -070050
51namespace android {
52
53// ----------------------------------------------------------------------------
54// Logging support -- this is for debugging only
55// Use "adb shell dumpsys media.camera -v 1" to change it.
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070056volatile int32_t gLogLevel = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -070057
Steve Blockb8a80522011-12-20 16:23:08 +000058#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
59#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
Mathias Agopian65ab4712010-07-14 17:59:35 -070060
61static void setLogLevel(int level) {
62 android_atomic_write(level, &gLogLevel);
63}
64
65// ----------------------------------------------------------------------------
66
67static int getCallingPid() {
68 return IPCThreadState::self()->getCallingPid();
69}
70
71static int getCallingUid() {
72 return IPCThreadState::self()->getCallingUid();
73}
74
Igor Murashkincba2c162013-03-20 15:56:31 -070075extern "C" {
76static void camera_device_status_change(
77 const struct camera_module_callbacks* callbacks,
78 int camera_id,
79 int new_status) {
80 sp<CameraService> cs = const_cast<CameraService*>(
81 static_cast<const CameraService*>(callbacks));
82
83 cs->onDeviceStatusChanged(
84 camera_id,
85 new_status);
86}
87} // extern "C"
88
Mathias Agopian65ab4712010-07-14 17:59:35 -070089// ----------------------------------------------------------------------------
90
91// This is ugly and only safe if we never re-create the CameraService, but
92// should be ok for now.
93static CameraService *gCameraService;
94
95CameraService::CameraService()
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080096 :mSoundRef(0), mModule(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -070097{
Steve Blockdf64d152012-01-04 20:05:49 +000098 ALOGI("CameraService started (pid=%d)", getpid());
Mathias Agopian65ab4712010-07-14 17:59:35 -070099 gCameraService = this;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800100
101 for (size_t i = 0; i < MAX_CAMERAS; ++i) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700102 mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800103 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700104
105 this->camera_device_status_change = android::camera_device_status_change;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700106}
107
Iliyan Malchev8951a972011-04-14 16:55:59 -0700108void CameraService::onFirstRef()
109{
Igor Murashkin634a5152013-02-20 17:15:11 -0800110 LOG1("CameraService::onFirstRef");
111
Iliyan Malchev8951a972011-04-14 16:55:59 -0700112 BnCameraService::onFirstRef();
113
114 if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
115 (const hw_module_t **)&mModule) < 0) {
Steve Block29357bc2012-01-06 19:20:56 +0000116 ALOGE("Could not load camera HAL module");
Iliyan Malchev8951a972011-04-14 16:55:59 -0700117 mNumberOfCameras = 0;
118 }
119 else {
Alex Rayc0dd54f2013-02-20 13:39:37 -0800120 ALOGI("Loaded \"%s\" camera module", mModule->common.name);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700121 mNumberOfCameras = mModule->get_number_of_cameras();
122 if (mNumberOfCameras > MAX_CAMERAS) {
Steve Block29357bc2012-01-06 19:20:56 +0000123 ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
Iliyan Malchev8951a972011-04-14 16:55:59 -0700124 mNumberOfCameras, MAX_CAMERAS);
125 mNumberOfCameras = MAX_CAMERAS;
126 }
127 for (int i = 0; i < mNumberOfCameras; i++) {
128 setCameraFree(i);
129 }
Igor Murashkincba2c162013-03-20 15:56:31 -0700130
131 if (mModule->common.module_api_version >=
132 CAMERA_MODULE_API_VERSION_2_1) {
133 mModule->set_callbacks(this);
134 }
Igor Murashkin98e24722013-06-19 19:51:04 -0700135
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800136 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
137
138 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_2) {
139 setUpVendorTags();
140 }
141
Igor Murashkin98e24722013-06-19 19:51:04 -0700142 CameraDeviceFactory::registerService(this);
Iliyan Malchev8951a972011-04-14 16:55:59 -0700143 }
144}
145
Mathias Agopian65ab4712010-07-14 17:59:35 -0700146CameraService::~CameraService() {
147 for (int i = 0; i < mNumberOfCameras; i++) {
148 if (mBusy[i]) {
Steve Block29357bc2012-01-06 19:20:56 +0000149 ALOGE("camera %d is still in use in destructor!", i);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700150 }
151 }
152
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800153 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700154 gCameraService = NULL;
155}
156
Igor Murashkincba2c162013-03-20 15:56:31 -0700157void CameraService::onDeviceStatusChanged(int cameraId,
158 int newStatus)
159{
160 ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
161 cameraId, newStatus);
162
163 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
164 ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
165 return;
166 }
167
168 if ((int)getStatus(cameraId) == newStatus) {
169 ALOGE("%s: State transition to the same status 0x%x not allowed",
170 __FUNCTION__, (uint32_t)newStatus);
171 return;
172 }
173
174 /* don't do this in updateStatus
175 since it is also called from connect and we could get into a deadlock */
176 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
177 Vector<sp<BasicClient> > clientsToDisconnect;
178 {
179 Mutex::Autolock al(mServiceLock);
180
181 /* Find all clients that we need to disconnect */
Igor Murashkine7ee7632013-06-11 18:10:18 -0700182 sp<BasicClient> client = mClient[cameraId].promote();
Igor Murashkincba2c162013-03-20 15:56:31 -0700183 if (client.get() != NULL) {
184 clientsToDisconnect.push_back(client);
185 }
186
187 int i = cameraId;
188 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
189 sp<ProClient> cl = mProClientList[i][j].promote();
190 if (cl != NULL) {
191 clientsToDisconnect.push_back(cl);
192 }
193 }
194 }
195
196 /* now disconnect them. don't hold the lock
197 or we can get into a deadlock */
198
199 for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
200 sp<BasicClient> client = clientsToDisconnect[i];
201
202 client->disconnect();
203 /**
204 * The remote app will no longer be able to call methods on the
205 * client since the client PID will be reset to 0
206 */
207 }
208
Colin Crosse5729fa2014-03-21 15:04:25 -0700209 ALOGV("%s: After unplug, disconnected %zu clients",
Igor Murashkincba2c162013-03-20 15:56:31 -0700210 __FUNCTION__, clientsToDisconnect.size());
211 }
212
213 updateStatus(
214 static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
215
216}
217
Mathias Agopian65ab4712010-07-14 17:59:35 -0700218int32_t CameraService::getNumberOfCameras() {
219 return mNumberOfCameras;
220}
221
222status_t CameraService::getCameraInfo(int cameraId,
223 struct CameraInfo* cameraInfo) {
Iliyan Malchev8951a972011-04-14 16:55:59 -0700224 if (!mModule) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700225 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700226 }
227
Mathias Agopian65ab4712010-07-14 17:59:35 -0700228 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
229 return BAD_VALUE;
230 }
231
Iliyan Malchev8951a972011-04-14 16:55:59 -0700232 struct camera_info info;
233 status_t rc = mModule->get_camera_info(cameraId, &info);
234 cameraInfo->facing = info.facing;
235 cameraInfo->orientation = info.orientation;
236 return rc;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700237}
238
Zhijun He2b59be82013-09-25 10:14:30 -0700239status_t CameraService::getCameraCharacteristics(int cameraId,
240 CameraMetadata* cameraInfo) {
241 if (!cameraInfo) {
242 ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
243 return BAD_VALUE;
244 }
245
246 if (!mModule) {
247 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
248 return -ENODEV;
249 }
250
251 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0) {
252 // TODO: Remove this check once HAL1 shim is in place.
253 ALOGE("%s: Only HAL module version V2 or higher supports static metadata", __FUNCTION__);
254 return BAD_VALUE;
255 }
256
257 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
258 ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
259 return BAD_VALUE;
260 }
261
262 int facing;
263 if (getDeviceVersion(cameraId, &facing) == CAMERA_DEVICE_API_VERSION_1_0) {
264 // TODO: Remove this check once HAL1 shim is in place.
265 ALOGE("%s: HAL1 doesn't support static metadata yet", __FUNCTION__);
266 return BAD_VALUE;
267 }
268
Zhijun Hef05e50e2013-10-01 11:05:33 -0700269 if (getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1) {
270 // Disable HAL2.x support for camera2 API for now.
271 ALOGW("%s: HAL2.x doesn't support getCameraCharacteristics for now", __FUNCTION__);
272 return BAD_VALUE;
273 }
274
Zhijun He2b59be82013-09-25 10:14:30 -0700275 struct camera_info info;
276 status_t ret = mModule->get_camera_info(cameraId, &info);
277 *cameraInfo = info.static_camera_characteristics;
278
279 return ret;
280}
281
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800282status_t CameraService::getCameraVendorTagDescriptor(/*out*/sp<VendorTagDescriptor>& desc) {
283 if (!mModule) {
284 ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
285 return -ENODEV;
286 }
287
288 if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_2) {
289 // TODO: Remove this check once HAL1 shim is in place.
Igor Murashkine1445da2014-03-17 14:00:29 -0700290 ALOGW("%s: Only HAL module version V2.2 or higher supports vendor tags", __FUNCTION__);
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800291 return -EOPNOTSUPP;
292 }
293
294 desc = VendorTagDescriptor::getGlobalVendorTagDescriptor();
295 return OK;
296}
297
Igor Murashkin634a5152013-02-20 17:15:11 -0800298int CameraService::getDeviceVersion(int cameraId, int* facing) {
299 struct camera_info info;
300 if (mModule->get_camera_info(cameraId, &info) != OK) {
301 return -1;
302 }
303
304 int deviceVersion;
305 if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
306 deviceVersion = info.device_version;
307 } else {
308 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
309 }
310
311 if (facing) {
312 *facing = info.facing;
313 }
314
315 return deviceVersion;
316}
317
Igor Murashkinbfc99152013-02-27 12:55:20 -0800318bool CameraService::isValidCameraId(int cameraId) {
319 int facing;
320 int deviceVersion = getDeviceVersion(cameraId, &facing);
321
322 switch(deviceVersion) {
323 case CAMERA_DEVICE_API_VERSION_1_0:
324 case CAMERA_DEVICE_API_VERSION_2_0:
325 case CAMERA_DEVICE_API_VERSION_2_1:
326 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -0700327 case CAMERA_DEVICE_API_VERSION_3_1:
328 case CAMERA_DEVICE_API_VERSION_3_2:
Igor Murashkinbfc99152013-02-27 12:55:20 -0800329 return true;
330 default:
331 return false;
332 }
333
334 return false;
335}
336
Ruben Brunkd1176ef2014-02-21 10:51:38 -0800337bool CameraService::setUpVendorTags() {
338 vendor_tag_ops_t vOps = vendor_tag_ops_t();
339
340 // Check if vendor operations have been implemented
341 if (mModule->get_vendor_tag_ops == NULL) {
342 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
343 return false;
344 }
345
346 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
347 mModule->get_vendor_tag_ops(&vOps);
348 ATRACE_END();
349
350 // Ensure all vendor operations are present
351 if (vOps.get_tag_count == NULL || vOps.get_all_tags == NULL ||
352 vOps.get_section_name == NULL || vOps.get_tag_name == NULL ||
353 vOps.get_tag_type == NULL) {
354 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
355 , __FUNCTION__);
356 return false;
357 }
358
359 // Read all vendor tag definitions into a descriptor
360 sp<VendorTagDescriptor> desc;
361 status_t res;
362 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
363 != OK) {
364 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
365 "received error %s (%d). Camera clients will not be able to use"
366 "vendor tags", __FUNCTION__, strerror(res), res);
367 return false;
368 }
369
370 // Set the global descriptor to use with camera metadata
371 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
372 return true;
373}
374
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700375status_t CameraService::validateConnect(int cameraId,
Igor Murashkine6800ce2013-03-04 17:25:57 -0800376 /*inout*/
377 int& clientUid) const {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800378
Mathias Agopian65ab4712010-07-14 17:59:35 -0700379 int callingPid = getCallingPid();
Tyler Luu5861a9a2011-10-06 00:00:03 -0500380
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800381 if (clientUid == USE_CALLING_UID) {
382 clientUid = getCallingUid();
383 } else {
384 // We only trust our own process to forward client UIDs
385 if (callingPid != getpid()) {
386 ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
387 callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700388 return PERMISSION_DENIED;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800389 }
390 }
Mathias Agopian65ab4712010-07-14 17:59:35 -0700391
Iliyan Malchev8951a972011-04-14 16:55:59 -0700392 if (!mModule) {
Steve Block29357bc2012-01-06 19:20:56 +0000393 ALOGE("Camera HAL module not loaded");
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700394 return -ENODEV;
Iliyan Malchev8951a972011-04-14 16:55:59 -0700395 }
396
Mathias Agopian65ab4712010-07-14 17:59:35 -0700397 if (cameraId < 0 || cameraId >= mNumberOfCameras) {
Steve Block29357bc2012-01-06 19:20:56 +0000398 ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
Mathias Agopian65ab4712010-07-14 17:59:35 -0700399 callingPid, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700400 return -ENODEV;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700401 }
402
Wu-cheng Lia3355432011-05-20 14:54:25 +0800403 char value[PROPERTY_VALUE_MAX];
404 property_get("sys.secpolicy.camera.disabled", value, "0");
405 if (strcmp(value, "1") == 0) {
406 // Camera is disabled by DevicePolicyManager.
Steve Blockdf64d152012-01-04 20:05:49 +0000407 ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700408 return -EACCES;
Wu-cheng Lia3355432011-05-20 14:54:25 +0800409 }
410
Igor Murashkincba2c162013-03-20 15:56:31 -0700411 ICameraServiceListener::Status currentStatus = getStatus(cameraId);
412 if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
413 ALOGI("Camera is not plugged in,"
414 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700415 return -ENODEV;
Igor Murashkincba2c162013-03-20 15:56:31 -0700416 } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
417 ALOGI("Camera is enumerating,"
418 " connect X (pid %d) rejected", callingPid);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700419 return -EBUSY;
Igor Murashkincba2c162013-03-20 15:56:31 -0700420 }
421 // Else don't check for STATUS_NOT_AVAILABLE.
422 // -- It's done implicitly in canConnectUnsafe /w the mBusy array
423
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700424 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800425}
426
427bool CameraService::canConnectUnsafe(int cameraId,
428 const String16& clientPackageName,
429 const sp<IBinder>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -0700430 sp<BasicClient> &client) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800431 String8 clientName8(clientPackageName);
432 int callingPid = getCallingPid();
433
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800434 if (mClient[cameraId] != 0) {
435 client = mClient[cameraId].promote();
436 if (client != 0) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700437 if (remoteCallback == client->getRemote()) {
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800438 LOG1("CameraService::connect X (pid %d) (the same client)",
439 callingPid);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800440 return true;
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800441 } else {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800442 // TODOSC: need to support 1 regular client,
443 // multiple shared clients here
444 ALOGW("CameraService::connect X (pid %d) rejected"
445 " (existing client).", callingPid);
446 return false;
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800447 }
Wu-cheng Li2fd24402012-02-23 19:01:00 -0800448 }
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800449 mClient[cameraId].clear();
450 }
451
Igor Murashkin634a5152013-02-20 17:15:11 -0800452 /*
453 mBusy is set to false as the last step of the Client destructor,
454 after which it is guaranteed that the Client destructor has finished (
455 including any inherited destructors)
456
457 We only need this for a Client subclasses since we don't allow
458 multiple Clents to be opened concurrently, but multiple BasicClient
459 would be fine
460 */
Wu-cheng Li08ad5ef2012-04-19 12:35:00 +0800461 if (mBusy[cameraId]) {
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800462 ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
463 " (camera %d is still busy).", callingPid,
464 clientName8.string(), cameraId);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800465 return false;
466 }
467
468 return true;
469}
470
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700471status_t CameraService::connect(
Igor Murashkine6800ce2013-03-04 17:25:57 -0800472 const sp<ICameraClient>& cameraClient,
473 int cameraId,
474 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700475 int clientUid,
476 /*out*/
477 sp<ICamera>& device) {
Igor Murashkine6800ce2013-03-04 17:25:57 -0800478
479 String8 clientName8(clientPackageName);
480 int callingPid = getCallingPid();
481
482 LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
483 clientName8.string(), cameraId);
484
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700485 status_t status = validateConnect(cameraId, /*inout*/clientUid);
486 if (status != OK) {
487 return status;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700488 }
489
Igor Murashkine6800ce2013-03-04 17:25:57 -0800490
Igor Murashkine7ee7632013-06-11 18:10:18 -0700491 sp<Client> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700492 {
493 Mutex::Autolock lock(mServiceLock);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700494 sp<BasicClient> clientTmp;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700495 if (!canConnectUnsafe(cameraId, clientPackageName,
496 cameraClient->asBinder(),
Igor Murashkine7ee7632013-06-11 18:10:18 -0700497 /*out*/clientTmp)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700498 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700499 } else if (client.get() != NULL) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700500 device = static_cast<Client*>(clientTmp.get());
501 return OK;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700502 }
503
504 int facing = -1;
505 int deviceVersion = getDeviceVersion(cameraId, &facing);
506
507 // If there are other non-exclusive users of the camera,
508 // this will tear them down before we can reuse the camera
509 if (isValidCameraId(cameraId)) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700510 // transition from PRESENT -> NOT_AVAILABLE
Igor Murashkinacd695c2013-03-13 17:23:00 -0700511 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
512 cameraId);
513 }
514
515 switch(deviceVersion) {
516 case CAMERA_DEVICE_API_VERSION_1_0:
517 client = new CameraClient(this, cameraClient,
518 clientPackageName, cameraId,
519 facing, callingPid, clientUid, getpid());
520 break;
521 case CAMERA_DEVICE_API_VERSION_2_0:
522 case CAMERA_DEVICE_API_VERSION_2_1:
523 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -0700524 case CAMERA_DEVICE_API_VERSION_3_1:
525 case CAMERA_DEVICE_API_VERSION_3_2:
Igor Murashkinacd695c2013-03-13 17:23:00 -0700526 client = new Camera2Client(this, cameraClient,
527 clientPackageName, cameraId,
528 facing, callingPid, clientUid, getpid(),
529 deviceVersion);
530 break;
531 case -1:
532 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700533 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700534 default:
535 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700536 return INVALID_OPERATION;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700537 }
538
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700539 status_t status = connectFinishUnsafe(client, client->getRemote());
540 if (status != OK) {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700541 // this is probably not recoverable.. maybe the client can try again
Igor Murashkincba2c162013-03-20 15:56:31 -0700542 // OK: we can only get here if we were originally in PRESENT state
543 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700544 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700545 }
546
547 mClient[cameraId] = client;
548 LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
549 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800550 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700551 // important: release the mutex here so the client can call back
552 // into the service from its destructor (can be at the end of the call)
Igor Murashkinbfc99152013-02-27 12:55:20 -0800553
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700554 device = client;
555 return OK;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700556}
557
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700558status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
559 const sp<IBinder>& remoteCallback) {
560 status_t status = client->initialize(mModule);
561 if (status != OK) {
562 return status;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800563 }
564
Igor Murashkine7ee7632013-06-11 18:10:18 -0700565 remoteCallback->linkToDeath(this);
Igor Murashkine6800ce2013-03-04 17:25:57 -0800566
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700567 return OK;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800568}
569
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700570status_t CameraService::connectPro(
Igor Murashkin634a5152013-02-20 17:15:11 -0800571 const sp<IProCameraCallbacks>& cameraCb,
Igor Murashkinc073ba52013-02-26 14:32:34 -0800572 int cameraId,
573 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700574 int clientUid,
575 /*out*/
576 sp<IProCameraUser>& device)
Igor Murashkin634a5152013-02-20 17:15:11 -0800577{
Igor Murashkinbfc99152013-02-27 12:55:20 -0800578 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700579 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -0800580
Igor Murashkine6800ce2013-03-04 17:25:57 -0800581 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
582 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700583 status_t status = validateConnect(cameraId, /*inout*/clientUid);
584 if (status != OK) {
585 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -0800586 }
587
Igor Murashkinacd695c2013-03-13 17:23:00 -0700588 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800589 {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700590 Mutex::Autolock lock(mServiceLock);
591 {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700592 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700593 if (!canConnectUnsafe(cameraId, clientPackageName,
594 cameraCb->asBinder(),
595 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700596 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700597 }
598 }
599
600 int facing = -1;
601 int deviceVersion = getDeviceVersion(cameraId, &facing);
602
603 switch(deviceVersion) {
604 case CAMERA_DEVICE_API_VERSION_1_0:
605 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
606 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -0700607 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700608 break;
609 case CAMERA_DEVICE_API_VERSION_2_0:
610 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -0700611 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -0700612 case CAMERA_DEVICE_API_VERSION_3_1:
613 case CAMERA_DEVICE_API_VERSION_3_2:
Igor Murashkinacd695c2013-03-13 17:23:00 -0700614 client = new ProCamera2Client(this, cameraCb, String16(),
615 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
616 break;
617 case -1:
618 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700619 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700620 default:
621 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700622 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800623 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700624
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700625 status_t status = connectFinishUnsafe(client, client->getRemote());
626 if (status != OK) {
627 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700628 }
629
630 mProClientList[cameraId].push(client);
631
632 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
633 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800634 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700635 // important: release the mutex here so the client can call back
636 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700637 device = client;
638 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800639}
Igor Murashkin634a5152013-02-20 17:15:11 -0800640
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700641status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700642 const sp<ICameraDeviceCallbacks>& cameraCb,
643 int cameraId,
644 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700645 int clientUid,
646 /*out*/
647 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700648{
Igor Murashkine7ee7632013-06-11 18:10:18 -0700649
650 String8 clientName8(clientPackageName);
651 int callingPid = getCallingPid();
652
653 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
654 clientName8.string(), cameraId);
655
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700656 status_t status = validateConnect(cameraId, /*inout*/clientUid);
657 if (status != OK) {
658 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700659 }
660
661 sp<CameraDeviceClient> client;
662 {
663 Mutex::Autolock lock(mServiceLock);
664 {
665 sp<BasicClient> client;
666 if (!canConnectUnsafe(cameraId, clientPackageName,
667 cameraCb->asBinder(),
668 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700669 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700670 }
671 }
672
673 int facing = -1;
674 int deviceVersion = getDeviceVersion(cameraId, &facing);
675
676 // If there are other non-exclusive users of the camera,
677 // this will tear them down before we can reuse the camera
678 if (isValidCameraId(cameraId)) {
679 // transition from PRESENT -> NOT_AVAILABLE
680 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
681 cameraId);
682 }
683
684 switch(deviceVersion) {
685 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700686 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -0700687 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700688 // TODO: don't allow 2.0 Only allow 2.1 and higher
689 case CAMERA_DEVICE_API_VERSION_2_0:
690 case CAMERA_DEVICE_API_VERSION_2_1:
691 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -0700692 case CAMERA_DEVICE_API_VERSION_3_1:
693 case CAMERA_DEVICE_API_VERSION_3_2:
Igor Murashkine7ee7632013-06-11 18:10:18 -0700694 client = new CameraDeviceClient(this, cameraCb, String16(),
695 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
696 break;
697 case -1:
698 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700699 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700700 default:
701 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700702 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700703 }
704
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700705 status_t status = connectFinishUnsafe(client, client->getRemote());
706 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700707 // this is probably not recoverable.. maybe the client can try again
708 // OK: we can only get here if we were originally in PRESENT state
709 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700710 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700711 }
712
713 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
714 getpid());
715
716 mClient[cameraId] = client;
717 }
718 // important: release the mutex here so the client can call back
719 // into the service from its destructor (can be at the end of the call)
720
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700721 device = client;
722 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700723}
724
725
Igor Murashkinbfc99152013-02-27 12:55:20 -0800726status_t CameraService::addListener(
727 const sp<ICameraServiceListener>& listener) {
728 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -0800729
Igor Murashkinbd3e2e02014-03-17 13:01:41 -0700730 if (listener == 0) {
731 ALOGE("%s: Listener must not be null", __FUNCTION__);
732 return BAD_VALUE;
733 }
734
Igor Murashkinbfc99152013-02-27 12:55:20 -0800735 Mutex::Autolock lock(mServiceLock);
736
737 Vector<sp<ICameraServiceListener> >::iterator it, end;
738 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
739 if ((*it)->asBinder() == listener->asBinder()) {
740 ALOGW("%s: Tried to add listener %p which was already subscribed",
741 __FUNCTION__, listener.get());
742 return ALREADY_EXISTS;
743 }
744 }
745
746 mListenerList.push_back(listener);
747
Igor Murashkincba2c162013-03-20 15:56:31 -0700748 /* Immediately signal current status to this listener only */
749 {
750 Mutex::Autolock m(mStatusMutex) ;
751 int numCams = getNumberOfCameras();
752 for (int i = 0; i < numCams; ++i) {
753 listener->onStatusChanged(mStatusList[i], i);
754 }
755 }
756
Igor Murashkinbfc99152013-02-27 12:55:20 -0800757 return OK;
758}
759status_t CameraService::removeListener(
760 const sp<ICameraServiceListener>& listener) {
761 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
762
Igor Murashkinbd3e2e02014-03-17 13:01:41 -0700763 if (listener == 0) {
764 ALOGE("%s: Listener must not be null", __FUNCTION__);
765 return BAD_VALUE;
766 }
767
Igor Murashkinbfc99152013-02-27 12:55:20 -0800768 Mutex::Autolock lock(mServiceLock);
769
770 Vector<sp<ICameraServiceListener> >::iterator it;
771 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
772 if ((*it)->asBinder() == listener->asBinder()) {
773 mListenerList.erase(it);
774 return OK;
775 }
776 }
777
778 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
779 __FUNCTION__, listener.get());
780
781 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -0800782}
783
784void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
785 int callingPid = getCallingPid();
786 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700787
Igor Murashkinecf17e82012-10-02 16:05:11 -0700788 // Declare this before the lock to make absolutely sure the
789 // destructor won't be called with the lock held.
790 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700791
Igor Murashkinecf17e82012-10-02 16:05:11 -0700792 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700793 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700794
795 if (client != 0) {
796 // Found our camera, clear and leave.
797 LOG1("removeClient: clear camera %d", outIndex);
798 mClient[outIndex].clear();
799
Igor Murashkine7ee7632013-06-11 18:10:18 -0700800 client->getRemote()->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -0800801 } else {
802
803 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
804
805 if (clientPro != NULL) {
806 // Found our camera, clear and leave.
807 LOG1("removeClient: clear pro %p", clientPro.get());
808
809 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
810 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700811 }
812
Igor Murashkin634a5152013-02-20 17:15:11 -0800813 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
814}
815
816sp<CameraService::ProClient> CameraService::findProClientUnsafe(
817 const wp<IBinder>& cameraCallbacksRemote)
818{
819 sp<ProClient> clientPro;
820
821 for (int i = 0; i < mNumberOfCameras; ++i) {
822 Vector<size_t> removeIdx;
823
824 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
825 wp<ProClient> cl = mProClientList[i][j];
826
827 sp<ProClient> clStrong = cl.promote();
828 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
829 clientPro = clStrong;
830 break;
831 } else if (clStrong == NULL) {
832 // mark to clean up dead ptr
833 removeIdx.push(j);
834 }
835 }
836
837 // remove stale ptrs (in reverse so the indices dont change)
838 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
839 mProClientList[i].removeAt(removeIdx[j]);
840 }
841
842 }
843
844 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700845}
846
Igor Murashkine7ee7632013-06-11 18:10:18 -0700847sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700848 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700849 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700850
851 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700852
853 // This happens when we have already disconnected (or this is
854 // just another unused camera).
855 if (mClient[i] == 0) continue;
856
857 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -0800858 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700859 client = mClient[i].promote();
860
Igor Murashkinecf17e82012-10-02 16:05:11 -0700861 // Clean up stale client entry
862 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700863 mClient[i].clear();
864 continue;
865 }
866
Igor Murashkine7ee7632013-06-11 18:10:18 -0700867 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700868 // Found our camera
869 outIndex = i;
870 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700871 }
872 }
873
Igor Murashkinecf17e82012-10-02 16:05:11 -0700874 outIndex = -1;
875 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700876}
877
Igor Murashkine7ee7632013-06-11 18:10:18 -0700878CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700879 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700880 return mClient[cameraId].unsafe_get();
881}
882
883Mutex* CameraService::getClientLockById(int cameraId) {
884 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
885 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700886}
887
Igor Murashkin634a5152013-02-20 17:15:11 -0800888sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700889 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700890
891 // Declare this before the lock to make absolutely sure the
892 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -0800893 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700894
895 Mutex::Autolock lock(mServiceLock);
896
897 int outIndex;
898 client = findClientUnsafe(cameraClient, outIndex);
899
900 return client;
901}
902
Mathias Agopian65ab4712010-07-14 17:59:35 -0700903status_t CameraService::onTransact(
904 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
905 // Permission checks
906 switch (code) {
907 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -0800908 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700909 const int pid = getCallingPid();
910 const int self_pid = getpid();
911 if (pid != self_pid) {
912 // we're called from a different process, do the real check
913 if (!checkCallingPermission(
914 String16("android.permission.CAMERA"))) {
915 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000916 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700917 "can't use the camera pid=%d, uid=%d", pid, uid);
918 return PERMISSION_DENIED;
919 }
920 }
921 break;
922 }
923
924 return BnCameraService::onTransact(code, data, reply, flags);
925}
926
927// The reason we need this busy bit is a new CameraService::connect() request
928// may come in while the previous Client's destructor has not been run or is
929// still running. If the last strong reference of the previous Client is gone
930// but the destructor has not been finished, we should not allow the new Client
931// to be created because we need to wait for the previous Client to tear down
932// the hardware first.
933void CameraService::setCameraBusy(int cameraId) {
934 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700935
936 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700937}
938
939void CameraService::setCameraFree(int cameraId) {
940 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700941
942 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700943}
944
945// We share the media players for shutter and recording sound for all clients.
946// A reference count is kept to determine when we will actually release the
947// media players.
948
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800949MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700950 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -0800951 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800952 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700953 mp->prepare();
954 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000955 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700956 return NULL;
957 }
958 return mp;
959}
960
961void CameraService::loadSound() {
962 Mutex::Autolock lock(mSoundLock);
963 LOG1("CameraService::loadSound ref=%d", mSoundRef);
964 if (mSoundRef++) return;
965
966 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
967 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
968}
969
970void CameraService::releaseSound() {
971 Mutex::Autolock lock(mSoundLock);
972 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
973 if (--mSoundRef) return;
974
975 for (int i = 0; i < NUM_SOUNDS; i++) {
976 if (mSoundPlayer[i] != 0) {
977 mSoundPlayer[i]->disconnect();
978 mSoundPlayer[i].clear();
979 }
980 }
981}
982
983void CameraService::playSound(sound_kind kind) {
984 LOG1("playSound(%d)", kind);
985 Mutex::Autolock lock(mSoundLock);
986 sp<MediaPlayer> player = mSoundPlayer[kind];
987 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800988 player->seekTo(0);
989 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700990 }
991}
992
993// ----------------------------------------------------------------------------
994
995CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -0700996 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -0800997 const String16& clientPackageName,
998 int cameraId, int cameraFacing,
999 int clientPid, uid_t clientUid,
1000 int servicePid) :
Igor Murashkin634a5152013-02-20 17:15:11 -08001001 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001002 clientPackageName,
1003 cameraId, cameraFacing,
1004 clientPid, clientUid,
1005 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001006{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001007 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001008 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001009
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001010 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001011
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012 cameraService->setCameraBusy(cameraId);
1013 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001014
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001015 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016}
1017
Mathias Agopian65ab4712010-07-14 17:59:35 -07001018// tear down the client
1019CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001020 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001021 mDestructionStarted = true;
1022
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001023 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001024 // unconditionally disconnect. function is idempotent
1025 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001026}
1027
Igor Murashkin634a5152013-02-20 17:15:11 -08001028CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001029 const sp<IBinder>& remoteCallback,
1030 const String16& clientPackageName,
1031 int cameraId, int cameraFacing,
1032 int clientPid, uid_t clientUid,
1033 int servicePid):
1034 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -08001035{
1036 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001037 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001038 mCameraId = cameraId;
1039 mCameraFacing = cameraFacing;
1040 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001041 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001042 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001043 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001044 mDestructionStarted = false;
1045}
1046
1047CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001048 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001049 mDestructionStarted = true;
1050}
1051
1052void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001053 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001054 mCameraService->removeClientByRemote(mRemoteBinder);
Igor Murashkincba2c162013-03-20 15:56:31 -07001055 // client shouldn't be able to call into us anymore
1056 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001057}
1058
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001059status_t CameraService::BasicClient::startCameraOps() {
1060 int32_t res;
1061
1062 mOpsCallback = new OpsCallback(this);
1063
Igor Murashkine6800ce2013-03-04 17:25:57 -08001064 {
1065 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1066 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1067 }
1068
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001069 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1070 mClientPackageName, mOpsCallback);
1071 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1072 mClientUid, mClientPackageName);
1073
1074 if (res != AppOpsManager::MODE_ALLOWED) {
1075 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1076 mCameraId, String8(mClientPackageName).string());
1077 return PERMISSION_DENIED;
1078 }
1079 mOpsActive = true;
1080 return OK;
1081}
1082
1083status_t CameraService::BasicClient::finishCameraOps() {
1084 if (mOpsActive) {
1085 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1086 mClientPackageName);
1087 mOpsActive = false;
1088 }
1089 mAppOpsManager.stopWatchingMode(mOpsCallback);
1090 mOpsCallback.clear();
1091
1092 return OK;
1093}
1094
1095void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1096 String8 name(packageName);
1097 String8 myName(mClientPackageName);
1098
1099 if (op != AppOpsManager::OP_CAMERA) {
1100 ALOGW("Unexpected app ops notification received: %d", op);
1101 return;
1102 }
1103
1104 int32_t res;
1105 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1106 mClientUid, mClientPackageName);
1107 ALOGV("checkOp returns: %d, %s ", res,
1108 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1109 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1110 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1111 "UNKNOWN");
1112
1113 if (res != AppOpsManager::MODE_ALLOWED) {
1114 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1115 myName.string());
1116 // Reset the client PID to allow server-initiated disconnect,
1117 // and to prevent further calls by client.
1118 mClientPid = getCallingPid();
1119 notifyError();
1120 disconnect();
1121 }
1122}
1123
Mathias Agopian65ab4712010-07-14 17:59:35 -07001124// ----------------------------------------------------------------------------
1125
Keun young Parkd8973a72012-03-28 14:13:09 -07001126Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001127 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001128}
1129
1130// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1131// be acquired for this to be safe
1132CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001133 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001134 // OK: only CameraClient calls this, and they already cast anyway.
1135 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001136
1137 // This could happen if the Client is in the process of shutting down (the
1138 // last strong reference is gone, but the destructor hasn't finished
1139 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001140 if (client == NULL) return NULL;
1141
1142 // destruction already started, so should not be accessed
1143 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001144
Mathias Agopian65ab4712010-07-14 17:59:35 -07001145 return client;
1146}
1147
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001148void CameraService::Client::notifyError() {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001149 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001150}
1151
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001152// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001153void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001154 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001155 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001156 mCameraService->setCameraFree(mCameraId);
Igor Murashkin93747b92013-05-01 15:42:20 -07001157
1158 StatusVector rejectSourceStates;
1159 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1160 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1161
1162 // Transition to PRESENT if the camera is not in either of above 2 states
Igor Murashkincba2c162013-03-20 15:56:31 -07001163 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Igor Murashkin93747b92013-05-01 15:42:20 -07001164 mCameraId,
1165 &rejectSourceStates);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001166}
1167
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001168CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1169 mClient(client) {
1170}
1171
1172void CameraService::Client::OpsCallback::opChanged(int32_t op,
1173 const String16& packageName) {
1174 sp<BasicClient> client = mClient.promote();
1175 if (client != NULL) {
1176 client->opChanged(op, packageName);
1177 }
1178}
1179
Mathias Agopian65ab4712010-07-14 17:59:35 -07001180// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001181// IProCamera
1182// ----------------------------------------------------------------------------
1183
1184CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001185 const sp<IProCameraCallbacks>& remoteCallback,
1186 const String16& clientPackageName,
1187 int cameraId,
1188 int cameraFacing,
1189 int clientPid,
1190 uid_t clientUid,
1191 int servicePid)
1192 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1193 clientPackageName, cameraId, cameraFacing,
1194 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001195{
1196 mRemoteCallback = remoteCallback;
1197}
1198
1199CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001200}
1201
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001202void CameraService::ProClient::notifyError() {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001203 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001204}
1205
Igor Murashkin634a5152013-02-20 17:15:11 -08001206// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001207
1208static const int kDumpLockRetries = 50;
1209static const int kDumpLockSleep = 60000;
1210
1211static bool tryLock(Mutex& mutex)
1212{
1213 bool locked = false;
1214 for (int i = 0; i < kDumpLockRetries; ++i) {
1215 if (mutex.tryLock() == NO_ERROR) {
1216 locked = true;
1217 break;
1218 }
1219 usleep(kDumpLockSleep);
1220 }
1221 return locked;
1222}
1223
1224status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001225 String8 result;
1226 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001227 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001228 "can't dump CameraService from pid=%d, uid=%d\n",
1229 getCallingPid(),
1230 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001231 write(fd, result.string(), result.size());
1232 } else {
1233 bool locked = tryLock(mServiceLock);
1234 // failed to lock - CameraService is probably deadlocked
1235 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001236 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001237 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001238 }
1239
1240 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001241 if (!mModule) {
1242 result = String8::format("No camera module available!\n");
1243 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001244 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001245 return NO_ERROR;
1246 }
1247
1248 result = String8::format("Camera module HAL API version: 0x%x\n",
1249 mModule->common.hal_api_version);
1250 result.appendFormat("Camera module API version: 0x%x\n",
1251 mModule->common.module_api_version);
1252 result.appendFormat("Camera module name: %s\n",
1253 mModule->common.name);
1254 result.appendFormat("Camera module author: %s\n",
1255 mModule->common.author);
1256 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1257 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001258 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001259 result = String8::format("Camera %d static information:\n", i);
1260 camera_info info;
1261
1262 status_t rc = mModule->get_camera_info(i, &info);
1263 if (rc != OK) {
1264 result.appendFormat(" Error reading static information!\n");
1265 write(fd, result.string(), result.size());
1266 } else {
1267 result.appendFormat(" Facing: %s\n",
1268 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1269 result.appendFormat(" Orientation: %d\n", info.orientation);
1270 int deviceVersion;
1271 if (mModule->common.module_api_version <
1272 CAMERA_MODULE_API_VERSION_2_0) {
1273 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1274 } else {
1275 deviceVersion = info.device_version;
1276 }
1277 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1278 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1279 result.appendFormat(" Device static metadata:\n");
1280 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001281 dump_indented_camera_metadata(info.static_camera_characteristics,
1282 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001283 } else {
1284 write(fd, result.string(), result.size());
1285 }
1286 }
1287
Igor Murashkine7ee7632013-06-11 18:10:18 -07001288 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001289 if (client == 0) {
1290 result = String8::format(" Device is closed, no client instance\n");
1291 write(fd, result.string(), result.size());
1292 continue;
1293 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001294 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001295 result = String8::format(" Device is open. Client instance dump:\n");
1296 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001297 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001298 }
1299 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001300 result = String8::format("\nNo active camera clients yet.\n");
1301 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001302 }
1303
1304 if (locked) mServiceLock.unlock();
1305
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001306 // Dump camera traces if there were any
1307 write(fd, "\n", 1);
1308 camera3::CameraTraces::dump(fd, args);
1309
Mathias Agopian65ab4712010-07-14 17:59:35 -07001310 // change logging level
1311 int n = args.size();
1312 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001313 String16 verboseOption("-v");
1314 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001315 String8 levelStr(args[i+1]);
1316 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001317 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001318 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001319 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001320 }
1321 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001322
Mathias Agopian65ab4712010-07-14 17:59:35 -07001323 }
1324 return NO_ERROR;
1325}
1326
Igor Murashkinecf17e82012-10-02 16:05:11 -07001327/*virtual*/void CameraService::binderDied(
1328 const wp<IBinder> &who) {
1329
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001330 /**
1331 * While tempting to promote the wp<IBinder> into a sp,
1332 * it's actually not supported by the binder driver
1333 */
1334
Igor Murashkinecf17e82012-10-02 16:05:11 -07001335 ALOGV("java clients' binder died");
1336
Igor Murashkin634a5152013-02-20 17:15:11 -08001337 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001338
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001339 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001340 ALOGV("java clients' binder death already cleaned up (normal case)");
1341 return;
1342 }
1343
Igor Murashkinecf17e82012-10-02 16:05:11 -07001344 ALOGW("Disconnecting camera client %p since the binder for it "
1345 "died (this pid %d)", cameraClient.get(), getCallingPid());
1346
1347 cameraClient->disconnect();
1348
1349}
1350
Igor Murashkinbfc99152013-02-27 12:55:20 -08001351void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001352 int32_t cameraId,
1353 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001354 // do not lock mServiceLock here or can get into a deadlock from
1355 // connect() -> ProClient::disconnect -> updateStatus
1356 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001357
1358 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1359
1360 mStatusList[cameraId] = status;
1361
1362 if (oldStatus != status) {
1363 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1364 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1365
Igor Murashkincba2c162013-03-20 15:56:31 -07001366 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1367 (status != ICameraServiceListener::STATUS_PRESENT &&
1368 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1369
1370 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1371 " or ENUMERATING", __FUNCTION__);
1372 mStatusList[cameraId] = oldStatus;
1373 return;
1374 }
1375
Igor Murashkin93747b92013-05-01 15:42:20 -07001376 if (rejectSourceStates != NULL) {
1377 const StatusVector &rejectList = *rejectSourceStates;
1378 StatusVector::const_iterator it = rejectList.begin();
1379
1380 /**
1381 * Sometimes we want to conditionally do a transition.
1382 * For example if a client disconnects, we want to go to PRESENT
1383 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1384 */
1385 for (; it != rejectList.end(); ++it) {
1386 if (oldStatus == *it) {
1387 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1388 " since the source state was was in one of the bad "
1389 " states.", __FUNCTION__, cameraId);
1390 mStatusList[cameraId] = oldStatus;
1391 return;
1392 }
1393 }
1394 }
1395
Igor Murashkinbfc99152013-02-27 12:55:20 -08001396 /**
1397 * ProClients lose their exclusive lock.
1398 * - Done before the CameraClient can initialize the HAL device,
1399 * since we want to be able to close it before they get to initialize
1400 */
1401 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1402 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1403 Vector<wp<ProClient> >::const_iterator it;
1404
1405 for (it = proClients.begin(); it != proClients.end(); ++it) {
1406 sp<ProClient> proCl = it->promote();
1407 if (proCl.get() != NULL) {
1408 proCl->onExclusiveLockStolen();
1409 }
1410 }
1411 }
1412
1413 Vector<sp<ICameraServiceListener> >::const_iterator it;
1414 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1415 (*it)->onStatusChanged(status, cameraId);
1416 }
1417 }
1418}
1419
Igor Murashkincba2c162013-03-20 15:56:31 -07001420ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1421 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1422 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1423 return ICameraServiceListener::STATUS_UNKNOWN;
1424 }
1425
1426 Mutex::Autolock al(mStatusMutex);
1427 return mStatusList[cameraId];
1428}
1429
Mathias Agopian65ab4712010-07-14 17:59:35 -07001430}; // namespace android