blob: c6b46701063bb5d63b53a95d7bd57fed2509c664 [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{
Natalie Silvanoviche1b55da2014-05-01 14:44:52 -0700578 if (cameraCb == 0) {
579 ALOGE("%s: Callback must not be null", __FUNCTION__);
580 return BAD_VALUE;
581 }
582
Igor Murashkinbfc99152013-02-27 12:55:20 -0800583 String8 clientName8(clientPackageName);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700584 int callingPid = getCallingPid();
Igor Murashkin634a5152013-02-20 17:15:11 -0800585
Igor Murashkine6800ce2013-03-04 17:25:57 -0800586 LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
587 clientName8.string(), cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700588 status_t status = validateConnect(cameraId, /*inout*/clientUid);
589 if (status != OK) {
590 return status;
Igor Murashkin634a5152013-02-20 17:15:11 -0800591 }
592
Igor Murashkinacd695c2013-03-13 17:23:00 -0700593 sp<ProClient> client;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800594 {
Igor Murashkinacd695c2013-03-13 17:23:00 -0700595 Mutex::Autolock lock(mServiceLock);
596 {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700597 sp<BasicClient> client;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700598 if (!canConnectUnsafe(cameraId, clientPackageName,
599 cameraCb->asBinder(),
600 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700601 return -EBUSY;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700602 }
603 }
604
605 int facing = -1;
606 int deviceVersion = getDeviceVersion(cameraId, &facing);
607
608 switch(deviceVersion) {
609 case CAMERA_DEVICE_API_VERSION_1_0:
610 ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
611 cameraId);
Ruben Brunk17963d12013-08-19 15:21:19 -0700612 return -EOPNOTSUPP;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700613 break;
614 case CAMERA_DEVICE_API_VERSION_2_0:
615 case CAMERA_DEVICE_API_VERSION_2_1:
Zhijun He47110052013-07-22 17:34:34 -0700616 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -0700617 case CAMERA_DEVICE_API_VERSION_3_1:
618 case CAMERA_DEVICE_API_VERSION_3_2:
Igor Murashkinacd695c2013-03-13 17:23:00 -0700619 client = new ProCamera2Client(this, cameraCb, String16(),
620 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
621 break;
622 case -1:
623 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700624 return BAD_VALUE;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700625 default:
626 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700627 return INVALID_OPERATION;
Igor Murashkine6800ce2013-03-04 17:25:57 -0800628 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700629
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700630 status_t status = connectFinishUnsafe(client, client->getRemote());
631 if (status != OK) {
632 return status;
Igor Murashkinacd695c2013-03-13 17:23:00 -0700633 }
634
635 mProClientList[cameraId].push(client);
636
637 LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
638 getpid());
Igor Murashkine6800ce2013-03-04 17:25:57 -0800639 }
Igor Murashkinacd695c2013-03-13 17:23:00 -0700640 // important: release the mutex here so the client can call back
641 // into the service from its destructor (can be at the end of the call)
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700642 device = client;
643 return OK;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800644}
Igor Murashkin634a5152013-02-20 17:15:11 -0800645
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700646status_t CameraService::connectDevice(
Igor Murashkine7ee7632013-06-11 18:10:18 -0700647 const sp<ICameraDeviceCallbacks>& cameraCb,
648 int cameraId,
649 const String16& clientPackageName,
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700650 int clientUid,
651 /*out*/
652 sp<ICameraDeviceUser>& device)
Igor Murashkine7ee7632013-06-11 18:10:18 -0700653{
Igor Murashkine7ee7632013-06-11 18:10:18 -0700654
655 String8 clientName8(clientPackageName);
656 int callingPid = getCallingPid();
657
658 LOG1("CameraService::connectDevice E (pid %d \"%s\", id %d)", callingPid,
659 clientName8.string(), cameraId);
660
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700661 status_t status = validateConnect(cameraId, /*inout*/clientUid);
662 if (status != OK) {
663 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700664 }
665
666 sp<CameraDeviceClient> client;
667 {
668 Mutex::Autolock lock(mServiceLock);
669 {
670 sp<BasicClient> client;
671 if (!canConnectUnsafe(cameraId, clientPackageName,
672 cameraCb->asBinder(),
673 /*out*/client)) {
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700674 return -EBUSY;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700675 }
676 }
677
678 int facing = -1;
679 int deviceVersion = getDeviceVersion(cameraId, &facing);
680
681 // If there are other non-exclusive users of the camera,
682 // this will tear them down before we can reuse the camera
683 if (isValidCameraId(cameraId)) {
684 // transition from PRESENT -> NOT_AVAILABLE
685 updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
686 cameraId);
687 }
688
689 switch(deviceVersion) {
690 case CAMERA_DEVICE_API_VERSION_1_0:
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700691 ALOGW("Camera using old HAL version: %d", deviceVersion);
Ruben Brunk17963d12013-08-19 15:21:19 -0700692 return -EOPNOTSUPP;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700693 // TODO: don't allow 2.0 Only allow 2.1 and higher
694 case CAMERA_DEVICE_API_VERSION_2_0:
695 case CAMERA_DEVICE_API_VERSION_2_1:
696 case CAMERA_DEVICE_API_VERSION_3_0:
Zhijun He95dd5ba2014-03-26 18:18:00 -0700697 case CAMERA_DEVICE_API_VERSION_3_1:
698 case CAMERA_DEVICE_API_VERSION_3_2:
Igor Murashkine7ee7632013-06-11 18:10:18 -0700699 client = new CameraDeviceClient(this, cameraCb, String16(),
700 cameraId, facing, callingPid, USE_CALLING_UID, getpid());
701 break;
702 case -1:
703 ALOGE("Invalid camera id %d", cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700704 return BAD_VALUE;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700705 default:
706 ALOGE("Unknown camera device HAL version: %d", deviceVersion);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700707 return INVALID_OPERATION;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700708 }
709
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700710 status_t status = connectFinishUnsafe(client, client->getRemote());
711 if (status != OK) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700712 // this is probably not recoverable.. maybe the client can try again
713 // OK: we can only get here if we were originally in PRESENT state
714 updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700715 return status;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700716 }
717
718 LOG1("CameraService::connectDevice X (id %d, this pid is %d)", cameraId,
719 getpid());
720
721 mClient[cameraId] = client;
722 }
723 // important: release the mutex here so the client can call back
724 // into the service from its destructor (can be at the end of the call)
725
Ruben Brunk0f61d8f2013-08-08 13:07:18 -0700726 device = client;
727 return OK;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700728}
729
730
Igor Murashkinbfc99152013-02-27 12:55:20 -0800731status_t CameraService::addListener(
732 const sp<ICameraServiceListener>& listener) {
733 ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
Igor Murashkin634a5152013-02-20 17:15:11 -0800734
Igor Murashkinbd3e2e02014-03-17 13:01:41 -0700735 if (listener == 0) {
736 ALOGE("%s: Listener must not be null", __FUNCTION__);
737 return BAD_VALUE;
738 }
739
Igor Murashkinbfc99152013-02-27 12:55:20 -0800740 Mutex::Autolock lock(mServiceLock);
741
742 Vector<sp<ICameraServiceListener> >::iterator it, end;
743 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
744 if ((*it)->asBinder() == listener->asBinder()) {
745 ALOGW("%s: Tried to add listener %p which was already subscribed",
746 __FUNCTION__, listener.get());
747 return ALREADY_EXISTS;
748 }
749 }
750
751 mListenerList.push_back(listener);
752
Igor Murashkincba2c162013-03-20 15:56:31 -0700753 /* Immediately signal current status to this listener only */
754 {
755 Mutex::Autolock m(mStatusMutex) ;
756 int numCams = getNumberOfCameras();
757 for (int i = 0; i < numCams; ++i) {
758 listener->onStatusChanged(mStatusList[i], i);
759 }
760 }
761
Igor Murashkinbfc99152013-02-27 12:55:20 -0800762 return OK;
763}
764status_t CameraService::removeListener(
765 const sp<ICameraServiceListener>& listener) {
766 ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
767
Igor Murashkinbd3e2e02014-03-17 13:01:41 -0700768 if (listener == 0) {
769 ALOGE("%s: Listener must not be null", __FUNCTION__);
770 return BAD_VALUE;
771 }
772
Igor Murashkinbfc99152013-02-27 12:55:20 -0800773 Mutex::Autolock lock(mServiceLock);
774
775 Vector<sp<ICameraServiceListener> >::iterator it;
776 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
777 if ((*it)->asBinder() == listener->asBinder()) {
778 mListenerList.erase(it);
779 return OK;
780 }
781 }
782
783 ALOGW("%s: Tried to remove a listener %p which was not subscribed",
784 __FUNCTION__, listener.get());
785
786 return BAD_VALUE;
Igor Murashkin634a5152013-02-20 17:15:11 -0800787}
788
789void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
790 int callingPid = getCallingPid();
791 LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700792
Igor Murashkinecf17e82012-10-02 16:05:11 -0700793 // Declare this before the lock to make absolutely sure the
794 // destructor won't be called with the lock held.
795 Mutex::Autolock lock(mServiceLock);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700796
Igor Murashkinecf17e82012-10-02 16:05:11 -0700797 int outIndex;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700798 sp<BasicClient> client = findClientUnsafe(remoteBinder, outIndex);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700799
800 if (client != 0) {
801 // Found our camera, clear and leave.
802 LOG1("removeClient: clear camera %d", outIndex);
803 mClient[outIndex].clear();
804
Igor Murashkine7ee7632013-06-11 18:10:18 -0700805 client->getRemote()->unlinkToDeath(this);
Igor Murashkin634a5152013-02-20 17:15:11 -0800806 } else {
807
808 sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
809
810 if (clientPro != NULL) {
811 // Found our camera, clear and leave.
812 LOG1("removeClient: clear pro %p", clientPro.get());
813
814 clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
815 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700816 }
817
Igor Murashkin634a5152013-02-20 17:15:11 -0800818 LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
819}
820
821sp<CameraService::ProClient> CameraService::findProClientUnsafe(
822 const wp<IBinder>& cameraCallbacksRemote)
823{
824 sp<ProClient> clientPro;
825
826 for (int i = 0; i < mNumberOfCameras; ++i) {
827 Vector<size_t> removeIdx;
828
829 for (size_t j = 0; j < mProClientList[i].size(); ++j) {
830 wp<ProClient> cl = mProClientList[i][j];
831
832 sp<ProClient> clStrong = cl.promote();
833 if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
834 clientPro = clStrong;
835 break;
836 } else if (clStrong == NULL) {
837 // mark to clean up dead ptr
838 removeIdx.push(j);
839 }
840 }
841
842 // remove stale ptrs (in reverse so the indices dont change)
843 for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
844 mProClientList[i].removeAt(removeIdx[j]);
845 }
846
847 }
848
849 return clientPro;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700850}
851
Igor Murashkine7ee7632013-06-11 18:10:18 -0700852sp<CameraService::BasicClient> CameraService::findClientUnsafe(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700853 const wp<IBinder>& cameraClient, int& outIndex) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700854 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700855
856 for (int i = 0; i < mNumberOfCameras; i++) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700857
858 // This happens when we have already disconnected (or this is
859 // just another unused camera).
860 if (mClient[i] == 0) continue;
861
862 // Promote mClient. It can fail if we are called from this path:
Igor Murashkin634a5152013-02-20 17:15:11 -0800863 // Client::~Client() -> disconnect() -> removeClientByRemote().
Mathias Agopian65ab4712010-07-14 17:59:35 -0700864 client = mClient[i].promote();
865
Igor Murashkinecf17e82012-10-02 16:05:11 -0700866 // Clean up stale client entry
867 if (client == NULL) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700868 mClient[i].clear();
869 continue;
870 }
871
Igor Murashkine7ee7632013-06-11 18:10:18 -0700872 if (cameraClient == client->getRemote()) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700873 // Found our camera
874 outIndex = i;
875 return client;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700876 }
877 }
878
Igor Murashkinecf17e82012-10-02 16:05:11 -0700879 outIndex = -1;
880 return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700881}
882
Igor Murashkine7ee7632013-06-11 18:10:18 -0700883CameraService::BasicClient* CameraService::getClientByIdUnsafe(int cameraId) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700884 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
Keun young Parkd8973a72012-03-28 14:13:09 -0700885 return mClient[cameraId].unsafe_get();
886}
887
888Mutex* CameraService::getClientLockById(int cameraId) {
889 if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
890 return &mClientLock[cameraId];
Mathias Agopian65ab4712010-07-14 17:59:35 -0700891}
892
Igor Murashkin634a5152013-02-20 17:15:11 -0800893sp<CameraService::BasicClient> CameraService::getClientByRemote(
Igor Murashkin294d0ec2012-10-05 10:44:57 -0700894 const wp<IBinder>& cameraClient) {
Igor Murashkinecf17e82012-10-02 16:05:11 -0700895
896 // Declare this before the lock to make absolutely sure the
897 // destructor won't be called with the lock held.
Igor Murashkin634a5152013-02-20 17:15:11 -0800898 sp<BasicClient> client;
Igor Murashkinecf17e82012-10-02 16:05:11 -0700899
900 Mutex::Autolock lock(mServiceLock);
901
902 int outIndex;
903 client = findClientUnsafe(cameraClient, outIndex);
904
905 return client;
906}
907
Mathias Agopian65ab4712010-07-14 17:59:35 -0700908status_t CameraService::onTransact(
909 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
910 // Permission checks
911 switch (code) {
912 case BnCameraService::CONNECT:
Igor Murashkin634a5152013-02-20 17:15:11 -0800913 case BnCameraService::CONNECT_PRO:
Mathias Agopian65ab4712010-07-14 17:59:35 -0700914 const int pid = getCallingPid();
915 const int self_pid = getpid();
916 if (pid != self_pid) {
917 // we're called from a different process, do the real check
918 if (!checkCallingPermission(
919 String16("android.permission.CAMERA"))) {
920 const int uid = getCallingUid();
Steve Block29357bc2012-01-06 19:20:56 +0000921 ALOGE("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -0700922 "can't use the camera pid=%d, uid=%d", pid, uid);
923 return PERMISSION_DENIED;
924 }
925 }
926 break;
927 }
928
929 return BnCameraService::onTransact(code, data, reply, flags);
930}
931
932// The reason we need this busy bit is a new CameraService::connect() request
933// may come in while the previous Client's destructor has not been run or is
934// still running. If the last strong reference of the previous Client is gone
935// but the destructor has not been finished, we should not allow the new Client
936// to be created because we need to wait for the previous Client to tear down
937// the hardware first.
938void CameraService::setCameraBusy(int cameraId) {
939 android_atomic_write(1, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700940
941 ALOGV("setCameraBusy cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700942}
943
944void CameraService::setCameraFree(int cameraId) {
945 android_atomic_write(0, &mBusy[cameraId]);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700946
947 ALOGV("setCameraFree cameraId=%d", cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700948}
949
950// We share the media players for shutter and recording sound for all clients.
951// A reference count is kept to determine when we will actually release the
952// media players.
953
Chih-Chung Changff4f55c2011-10-17 19:03:12 +0800954MediaPlayer* CameraService::newMediaPlayer(const char *file) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700955 MediaPlayer* mp = new MediaPlayer();
Andreas Huber1b86fe02014-01-29 11:13:26 -0800956 if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
Eino-Ville Talvala60a78ac2012-01-05 15:34:53 -0800957 mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700958 mp->prepare();
959 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000960 ALOGE("Failed to load CameraService sounds: %s", file);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700961 return NULL;
962 }
963 return mp;
964}
965
966void CameraService::loadSound() {
967 Mutex::Autolock lock(mSoundLock);
968 LOG1("CameraService::loadSound ref=%d", mSoundRef);
969 if (mSoundRef++) return;
970
971 mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
972 mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
973}
974
975void CameraService::releaseSound() {
976 Mutex::Autolock lock(mSoundLock);
977 LOG1("CameraService::releaseSound ref=%d", mSoundRef);
978 if (--mSoundRef) return;
979
980 for (int i = 0; i < NUM_SOUNDS; i++) {
981 if (mSoundPlayer[i] != 0) {
982 mSoundPlayer[i]->disconnect();
983 mSoundPlayer[i].clear();
984 }
985 }
986}
987
988void CameraService::playSound(sound_kind kind) {
989 LOG1("playSound(%d)", kind);
990 Mutex::Autolock lock(mSoundLock);
991 sp<MediaPlayer> player = mSoundPlayer[kind];
992 if (player != 0) {
Chih-Chung Chang8888a752011-10-20 10:47:26 +0800993 player->seekTo(0);
994 player->start();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700995 }
996}
997
998// ----------------------------------------------------------------------------
999
1000CameraService::Client::Client(const sp<CameraService>& cameraService,
Wu-cheng Lib7a67942010-08-17 15:45:37 -07001001 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001002 const String16& clientPackageName,
1003 int cameraId, int cameraFacing,
1004 int clientPid, uid_t clientUid,
1005 int servicePid) :
Igor Murashkin634a5152013-02-20 17:15:11 -08001006 CameraService::BasicClient(cameraService, cameraClient->asBinder(),
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001007 clientPackageName,
1008 cameraId, cameraFacing,
1009 clientPid, clientUid,
1010 servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001011{
Mathias Agopian65ab4712010-07-14 17:59:35 -07001012 int callingPid = getCallingPid();
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001013 LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001014
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001015 mRemoteCallback = cameraClient;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016
Mathias Agopian65ab4712010-07-14 17:59:35 -07001017 cameraService->setCameraBusy(cameraId);
1018 cameraService->loadSound();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001019
Wu-cheng Li2fd24402012-02-23 19:01:00 -08001020 LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001021}
1022
Mathias Agopian65ab4712010-07-14 17:59:35 -07001023// tear down the client
1024CameraService::Client::~Client() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001025 ALOGV("~Client");
Igor Murashkin634a5152013-02-20 17:15:11 -08001026 mDestructionStarted = true;
1027
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001028 mCameraService->releaseSound();
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001029 // unconditionally disconnect. function is idempotent
1030 Client::disconnect();
Mathias Agopian65ab4712010-07-14 17:59:35 -07001031}
1032
Igor Murashkin634a5152013-02-20 17:15:11 -08001033CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001034 const sp<IBinder>& remoteCallback,
1035 const String16& clientPackageName,
1036 int cameraId, int cameraFacing,
1037 int clientPid, uid_t clientUid,
1038 int servicePid):
1039 mClientPackageName(clientPackageName)
Igor Murashkin634a5152013-02-20 17:15:11 -08001040{
1041 mCameraService = cameraService;
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001042 mRemoteBinder = remoteCallback;
Igor Murashkin634a5152013-02-20 17:15:11 -08001043 mCameraId = cameraId;
1044 mCameraFacing = cameraFacing;
1045 mClientPid = clientPid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001046 mClientUid = clientUid;
Igor Murashkin634a5152013-02-20 17:15:11 -08001047 mServicePid = servicePid;
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001048 mOpsActive = false;
Igor Murashkin634a5152013-02-20 17:15:11 -08001049 mDestructionStarted = false;
1050}
1051
1052CameraService::BasicClient::~BasicClient() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001053 ALOGV("~BasicClient");
Igor Murashkin634a5152013-02-20 17:15:11 -08001054 mDestructionStarted = true;
1055}
1056
1057void CameraService::BasicClient::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001058 ALOGV("BasicClient::disconnect");
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001059 mCameraService->removeClientByRemote(mRemoteBinder);
Igor Murashkincba2c162013-03-20 15:56:31 -07001060 // client shouldn't be able to call into us anymore
1061 mClientPid = 0;
Igor Murashkin634a5152013-02-20 17:15:11 -08001062}
1063
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001064status_t CameraService::BasicClient::startCameraOps() {
1065 int32_t res;
1066
1067 mOpsCallback = new OpsCallback(this);
1068
Igor Murashkine6800ce2013-03-04 17:25:57 -08001069 {
1070 ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
1071 __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
1072 }
1073
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001074 mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
1075 mClientPackageName, mOpsCallback);
1076 res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
1077 mClientUid, mClientPackageName);
1078
1079 if (res != AppOpsManager::MODE_ALLOWED) {
1080 ALOGI("Camera %d: Access for \"%s\" has been revoked",
1081 mCameraId, String8(mClientPackageName).string());
1082 return PERMISSION_DENIED;
1083 }
1084 mOpsActive = true;
1085 return OK;
1086}
1087
1088status_t CameraService::BasicClient::finishCameraOps() {
1089 if (mOpsActive) {
1090 mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
1091 mClientPackageName);
1092 mOpsActive = false;
1093 }
1094 mAppOpsManager.stopWatchingMode(mOpsCallback);
1095 mOpsCallback.clear();
1096
1097 return OK;
1098}
1099
1100void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
1101 String8 name(packageName);
1102 String8 myName(mClientPackageName);
1103
1104 if (op != AppOpsManager::OP_CAMERA) {
1105 ALOGW("Unexpected app ops notification received: %d", op);
1106 return;
1107 }
1108
1109 int32_t res;
1110 res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
1111 mClientUid, mClientPackageName);
1112 ALOGV("checkOp returns: %d, %s ", res,
1113 res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
1114 res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
1115 res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
1116 "UNKNOWN");
1117
1118 if (res != AppOpsManager::MODE_ALLOWED) {
1119 ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
1120 myName.string());
1121 // Reset the client PID to allow server-initiated disconnect,
1122 // and to prevent further calls by client.
1123 mClientPid = getCallingPid();
Jianing Weicb0652e2014-03-12 18:29:36 -07001124 CaptureResultExtras resultExtras; // a dummy result (invalid)
1125 notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001126 disconnect();
1127 }
1128}
1129
Mathias Agopian65ab4712010-07-14 17:59:35 -07001130// ----------------------------------------------------------------------------
1131
Keun young Parkd8973a72012-03-28 14:13:09 -07001132Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001133 return gCameraService->getClientLockById((int)(intptr_t) user);
Keun young Parkd8973a72012-03-28 14:13:09 -07001134}
1135
1136// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
1137// be acquired for this to be safe
1138CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001139 BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001140 // OK: only CameraClient calls this, and they already cast anyway.
1141 Client* client = static_cast<Client*>(basicClient);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001142
1143 // This could happen if the Client is in the process of shutting down (the
1144 // last strong reference is gone, but the destructor hasn't finished
1145 // stopping the hardware).
Keun young Parkd8973a72012-03-28 14:13:09 -07001146 if (client == NULL) return NULL;
1147
1148 // destruction already started, so should not be accessed
1149 if (client->mDestructionStarted) return NULL;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001150
Mathias Agopian65ab4712010-07-14 17:59:35 -07001151 return client;
1152}
1153
Jianing Weicb0652e2014-03-12 18:29:36 -07001154void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1155 const CaptureResultExtras& resultExtras) {
Igor Murashkin44cfcf02013-03-01 16:22:28 -08001156 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001157}
1158
Igor Murashkin036bc3e2012-10-08 15:09:46 -07001159// NOTE: function is idempotent
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001160void CameraService::Client::disconnect() {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -07001161 ALOGV("Client::disconnect");
Igor Murashkin634a5152013-02-20 17:15:11 -08001162 BasicClient::disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001163 mCameraService->setCameraFree(mCameraId);
Igor Murashkin93747b92013-05-01 15:42:20 -07001164
1165 StatusVector rejectSourceStates;
1166 rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
1167 rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
1168
1169 // Transition to PRESENT if the camera is not in either of above 2 states
Igor Murashkincba2c162013-03-20 15:56:31 -07001170 mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
Igor Murashkin93747b92013-05-01 15:42:20 -07001171 mCameraId,
1172 &rejectSourceStates);
Wu-cheng Lie09591e2010-10-14 20:17:44 +08001173}
1174
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001175CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
1176 mClient(client) {
1177}
1178
1179void CameraService::Client::OpsCallback::opChanged(int32_t op,
1180 const String16& packageName) {
1181 sp<BasicClient> client = mClient.promote();
1182 if (client != NULL) {
1183 client->opChanged(op, packageName);
1184 }
1185}
1186
Mathias Agopian65ab4712010-07-14 17:59:35 -07001187// ----------------------------------------------------------------------------
Igor Murashkin634a5152013-02-20 17:15:11 -08001188// IProCamera
1189// ----------------------------------------------------------------------------
1190
1191CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001192 const sp<IProCameraCallbacks>& remoteCallback,
1193 const String16& clientPackageName,
1194 int cameraId,
1195 int cameraFacing,
1196 int clientPid,
1197 uid_t clientUid,
1198 int servicePid)
1199 : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
1200 clientPackageName, cameraId, cameraFacing,
1201 clientPid, clientUid, servicePid)
Igor Murashkin634a5152013-02-20 17:15:11 -08001202{
1203 mRemoteCallback = remoteCallback;
1204}
1205
1206CameraService::ProClient::~ProClient() {
Igor Murashkin634a5152013-02-20 17:15:11 -08001207}
1208
Jianing Weicb0652e2014-03-12 18:29:36 -07001209void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
1210 const CaptureResultExtras& resultExtras) {
Igor Murashkine6800ce2013-03-04 17:25:57 -08001211 mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -08001212}
1213
Igor Murashkin634a5152013-02-20 17:15:11 -08001214// ----------------------------------------------------------------------------
Mathias Agopian65ab4712010-07-14 17:59:35 -07001215
1216static const int kDumpLockRetries = 50;
1217static const int kDumpLockSleep = 60000;
1218
1219static bool tryLock(Mutex& mutex)
1220{
1221 bool locked = false;
1222 for (int i = 0; i < kDumpLockRetries; ++i) {
1223 if (mutex.tryLock() == NO_ERROR) {
1224 locked = true;
1225 break;
1226 }
1227 usleep(kDumpLockSleep);
1228 }
1229 return locked;
1230}
1231
1232status_t CameraService::dump(int fd, const Vector<String16>& args) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001233 String8 result;
1234 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001235 result.appendFormat("Permission Denial: "
Mathias Agopian65ab4712010-07-14 17:59:35 -07001236 "can't dump CameraService from pid=%d, uid=%d\n",
1237 getCallingPid(),
1238 getCallingUid());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001239 write(fd, result.string(), result.size());
1240 } else {
1241 bool locked = tryLock(mServiceLock);
1242 // failed to lock - CameraService is probably deadlocked
1243 if (!locked) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001244 result.append("CameraService may be deadlocked\n");
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001245 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001246 }
1247
1248 bool hasClient = false;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001249 if (!mModule) {
1250 result = String8::format("No camera module available!\n");
1251 write(fd, result.string(), result.size());
Kalle Lampila6ec3a152013-04-30 15:27:19 +03001252 if (locked) mServiceLock.unlock();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001253 return NO_ERROR;
1254 }
1255
1256 result = String8::format("Camera module HAL API version: 0x%x\n",
1257 mModule->common.hal_api_version);
1258 result.appendFormat("Camera module API version: 0x%x\n",
1259 mModule->common.module_api_version);
1260 result.appendFormat("Camera module name: %s\n",
1261 mModule->common.name);
1262 result.appendFormat("Camera module author: %s\n",
1263 mModule->common.author);
1264 result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1265 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001266 for (int i = 0; i < mNumberOfCameras; i++) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001267 result = String8::format("Camera %d static information:\n", i);
1268 camera_info info;
1269
1270 status_t rc = mModule->get_camera_info(i, &info);
1271 if (rc != OK) {
1272 result.appendFormat(" Error reading static information!\n");
1273 write(fd, result.string(), result.size());
1274 } else {
1275 result.appendFormat(" Facing: %s\n",
1276 info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1277 result.appendFormat(" Orientation: %d\n", info.orientation);
1278 int deviceVersion;
1279 if (mModule->common.module_api_version <
1280 CAMERA_MODULE_API_VERSION_2_0) {
1281 deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1282 } else {
1283 deviceVersion = info.device_version;
1284 }
1285 result.appendFormat(" Device version: 0x%x\n", deviceVersion);
1286 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1287 result.appendFormat(" Device static metadata:\n");
1288 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -07001289 dump_indented_camera_metadata(info.static_camera_characteristics,
1290 fd, 2, 4);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001291 } else {
1292 write(fd, result.string(), result.size());
1293 }
1294 }
1295
Igor Murashkine7ee7632013-06-11 18:10:18 -07001296 sp<BasicClient> client = mClient[i].promote();
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001297 if (client == 0) {
1298 result = String8::format(" Device is closed, no client instance\n");
1299 write(fd, result.string(), result.size());
1300 continue;
1301 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001302 hasClient = true;
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001303 result = String8::format(" Device is open. Client instance dump:\n");
1304 write(fd, result.string(), result.size());
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001305 client->dump(fd, args);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001306 }
1307 if (!hasClient) {
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001308 result = String8::format("\nNo active camera clients yet.\n");
1309 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001310 }
1311
1312 if (locked) mServiceLock.unlock();
1313
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001314 // Dump camera traces if there were any
1315 write(fd, "\n", 1);
1316 camera3::CameraTraces::dump(fd, args);
1317
Mathias Agopian65ab4712010-07-14 17:59:35 -07001318 // change logging level
1319 int n = args.size();
1320 for (int i = 0; i + 1 < n; i++) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -07001321 String16 verboseOption("-v");
1322 if (args[i] == verboseOption) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001323 String8 levelStr(args[i+1]);
1324 int level = atoi(levelStr.string());
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001325 result = String8::format("\nSetting log level to %d.\n", level);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001326 setLogLevel(level);
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001327 write(fd, result.string(), result.size());
Mathias Agopian65ab4712010-07-14 17:59:35 -07001328 }
1329 }
Eino-Ville Talvalaf5926132012-07-17 13:54:20 -07001330
Mathias Agopian65ab4712010-07-14 17:59:35 -07001331 }
1332 return NO_ERROR;
1333}
1334
Igor Murashkinecf17e82012-10-02 16:05:11 -07001335/*virtual*/void CameraService::binderDied(
1336 const wp<IBinder> &who) {
1337
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001338 /**
1339 * While tempting to promote the wp<IBinder> into a sp,
1340 * it's actually not supported by the binder driver
1341 */
1342
Igor Murashkinecf17e82012-10-02 16:05:11 -07001343 ALOGV("java clients' binder died");
1344
Igor Murashkin634a5152013-02-20 17:15:11 -08001345 sp<BasicClient> cameraClient = getClientByRemote(who);
Igor Murashkinecf17e82012-10-02 16:05:11 -07001346
Igor Murashkin294d0ec2012-10-05 10:44:57 -07001347 if (cameraClient == 0) {
Igor Murashkinecf17e82012-10-02 16:05:11 -07001348 ALOGV("java clients' binder death already cleaned up (normal case)");
1349 return;
1350 }
1351
Igor Murashkinecf17e82012-10-02 16:05:11 -07001352 ALOGW("Disconnecting camera client %p since the binder for it "
1353 "died (this pid %d)", cameraClient.get(), getCallingPid());
1354
1355 cameraClient->disconnect();
1356
1357}
1358
Igor Murashkinbfc99152013-02-27 12:55:20 -08001359void CameraService::updateStatus(ICameraServiceListener::Status status,
Igor Murashkin93747b92013-05-01 15:42:20 -07001360 int32_t cameraId,
1361 const StatusVector *rejectSourceStates) {
Igor Murashkinbfc99152013-02-27 12:55:20 -08001362 // do not lock mServiceLock here or can get into a deadlock from
1363 // connect() -> ProClient::disconnect -> updateStatus
1364 Mutex::Autolock lock(mStatusMutex);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001365
1366 ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1367
1368 mStatusList[cameraId] = status;
1369
1370 if (oldStatus != status) {
1371 ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1372 __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1373
Igor Murashkincba2c162013-03-20 15:56:31 -07001374 if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1375 (status != ICameraServiceListener::STATUS_PRESENT &&
1376 status != ICameraServiceListener::STATUS_ENUMERATING)) {
1377
1378 ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1379 " or ENUMERATING", __FUNCTION__);
1380 mStatusList[cameraId] = oldStatus;
1381 return;
1382 }
1383
Igor Murashkin93747b92013-05-01 15:42:20 -07001384 if (rejectSourceStates != NULL) {
1385 const StatusVector &rejectList = *rejectSourceStates;
1386 StatusVector::const_iterator it = rejectList.begin();
1387
1388 /**
1389 * Sometimes we want to conditionally do a transition.
1390 * For example if a client disconnects, we want to go to PRESENT
1391 * only if we weren't already in NOT_PRESENT or ENUMERATING.
1392 */
1393 for (; it != rejectList.end(); ++it) {
1394 if (oldStatus == *it) {
1395 ALOGV("%s: Rejecting status transition for Camera ID %d, "
1396 " since the source state was was in one of the bad "
1397 " states.", __FUNCTION__, cameraId);
1398 mStatusList[cameraId] = oldStatus;
1399 return;
1400 }
1401 }
1402 }
1403
Igor Murashkinbfc99152013-02-27 12:55:20 -08001404 /**
1405 * ProClients lose their exclusive lock.
1406 * - Done before the CameraClient can initialize the HAL device,
1407 * since we want to be able to close it before they get to initialize
1408 */
1409 if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1410 Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1411 Vector<wp<ProClient> >::const_iterator it;
1412
1413 for (it = proClients.begin(); it != proClients.end(); ++it) {
1414 sp<ProClient> proCl = it->promote();
1415 if (proCl.get() != NULL) {
1416 proCl->onExclusiveLockStolen();
1417 }
1418 }
1419 }
1420
1421 Vector<sp<ICameraServiceListener> >::const_iterator it;
1422 for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1423 (*it)->onStatusChanged(status, cameraId);
1424 }
1425 }
1426}
1427
Igor Murashkincba2c162013-03-20 15:56:31 -07001428ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1429 if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1430 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1431 return ICameraServiceListener::STATUS_UNKNOWN;
1432 }
1433
1434 Mutex::Autolock al(mStatusMutex);
1435 return mStatusList[cameraId];
1436}
1437
Mathias Agopian65ab4712010-07-14 17:59:35 -07001438}; // namespace android