CameraService.cpp revision cba2c163555cd329f49d40658ea3ee902e94dda3
1/*
2**
3** Copyright (C) 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "CameraService"
19//#define LOG_NDEBUG 0
20
21#include <stdio.h>
22#include <sys/types.h>
23#include <pthread.h>
24
25#include <binder/AppOpsManager.h>
26#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28#include <binder/MemoryBase.h>
29#include <binder/MemoryHeapBase.h>
30#include <cutils/atomic.h>
31#include <cutils/properties.h>
32#include <gui/Surface.h>
33#include <hardware/hardware.h>
34#include <media/AudioSystem.h>
35#include <media/mediaplayer.h>
36#include <utils/Errors.h>
37#include <utils/Log.h>
38#include <utils/String16.h>
39
40#include "CameraService.h"
41#include "CameraClient.h"
42#include "Camera2Client.h"
43#include "ProCamera2Client.h"
44
45namespace android {
46
47// ----------------------------------------------------------------------------
48// Logging support -- this is for debugging only
49// Use "adb shell dumpsys media.camera -v 1" to change it.
50volatile int32_t gLogLevel = 0;
51
52#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
53#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
54
55static void setLogLevel(int level) {
56    android_atomic_write(level, &gLogLevel);
57}
58
59// ----------------------------------------------------------------------------
60
61static int getCallingPid() {
62    return IPCThreadState::self()->getCallingPid();
63}
64
65static int getCallingUid() {
66    return IPCThreadState::self()->getCallingUid();
67}
68
69extern "C" {
70static void camera_device_status_change(
71        const struct camera_module_callbacks* callbacks,
72        int camera_id,
73        int new_status) {
74    sp<CameraService> cs = const_cast<CameraService*>(
75                                static_cast<const CameraService*>(callbacks));
76
77    cs->onDeviceStatusChanged(
78        camera_id,
79        new_status);
80}
81} // extern "C"
82
83// ----------------------------------------------------------------------------
84
85// This is ugly and only safe if we never re-create the CameraService, but
86// should be ok for now.
87static CameraService *gCameraService;
88
89CameraService::CameraService()
90    :mSoundRef(0), mModule(0)
91{
92    ALOGI("CameraService started (pid=%d)", getpid());
93    gCameraService = this;
94
95    for (size_t i = 0; i < MAX_CAMERAS; ++i) {
96        mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
97    }
98
99    this->camera_device_status_change = android::camera_device_status_change;
100}
101
102void CameraService::onFirstRef()
103{
104    LOG1("CameraService::onFirstRef");
105
106    BnCameraService::onFirstRef();
107
108    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
109                (const hw_module_t **)&mModule) < 0) {
110        ALOGE("Could not load camera HAL module");
111        mNumberOfCameras = 0;
112    }
113    else {
114        ALOGI("Loaded \"%s\" camera module", mModule->common.name);
115        mNumberOfCameras = mModule->get_number_of_cameras();
116        if (mNumberOfCameras > MAX_CAMERAS) {
117            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
118                    mNumberOfCameras, MAX_CAMERAS);
119            mNumberOfCameras = MAX_CAMERAS;
120        }
121        for (int i = 0; i < mNumberOfCameras; i++) {
122            setCameraFree(i);
123        }
124
125        if (mModule->common.module_api_version >=
126                CAMERA_MODULE_API_VERSION_2_1) {
127            mModule->set_callbacks(this);
128        }
129    }
130}
131
132CameraService::~CameraService() {
133    for (int i = 0; i < mNumberOfCameras; i++) {
134        if (mBusy[i]) {
135            ALOGE("camera %d is still in use in destructor!", i);
136        }
137    }
138
139    gCameraService = NULL;
140}
141
142void CameraService::onDeviceStatusChanged(int cameraId,
143                                          int newStatus)
144{
145    ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__,
146          cameraId, newStatus);
147
148    if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
149        ALOGE("%s: Bad camera ID %d", __FUNCTION__, cameraId);
150        return;
151    }
152
153    if ((int)getStatus(cameraId) == newStatus) {
154        ALOGE("%s: State transition to the same status 0x%x not allowed",
155              __FUNCTION__, (uint32_t)newStatus);
156        return;
157    }
158
159    /* don't do this in updateStatus
160       since it is also called from connect and we could get into a deadlock */
161    if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
162        Vector<sp<BasicClient> > clientsToDisconnect;
163        {
164           Mutex::Autolock al(mServiceLock);
165
166           /* Find all clients that we need to disconnect */
167           sp<Client> client = mClient[cameraId].promote();
168           if (client.get() != NULL) {
169               clientsToDisconnect.push_back(client);
170           }
171
172           int i = cameraId;
173           for (size_t j = 0; j < mProClientList[i].size(); ++j) {
174               sp<ProClient> cl = mProClientList[i][j].promote();
175               if (cl != NULL) {
176                   clientsToDisconnect.push_back(cl);
177               }
178           }
179        }
180
181        /* now disconnect them. don't hold the lock
182           or we can get into a deadlock */
183
184        for (size_t i = 0; i < clientsToDisconnect.size(); ++i) {
185            sp<BasicClient> client = clientsToDisconnect[i];
186
187            client->disconnect();
188            /**
189             * The remote app will no longer be able to call methods on the
190             * client since the client PID will be reset to 0
191             */
192        }
193
194        ALOGV("%s: After unplug, disconnected %d clients",
195              __FUNCTION__, clientsToDisconnect.size());
196    }
197
198    updateStatus(
199            static_cast<ICameraServiceListener::Status>(newStatus), cameraId);
200
201}
202
203int32_t CameraService::getNumberOfCameras() {
204    return mNumberOfCameras;
205}
206
207status_t CameraService::getCameraInfo(int cameraId,
208                                      struct CameraInfo* cameraInfo) {
209    if (!mModule) {
210        return NO_INIT;
211    }
212
213    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
214        return BAD_VALUE;
215    }
216
217    struct camera_info info;
218    status_t rc = mModule->get_camera_info(cameraId, &info);
219    cameraInfo->facing = info.facing;
220    cameraInfo->orientation = info.orientation;
221    return rc;
222}
223
224int CameraService::getDeviceVersion(int cameraId, int* facing) {
225    struct camera_info info;
226    if (mModule->get_camera_info(cameraId, &info) != OK) {
227        return -1;
228    }
229
230    int deviceVersion;
231    if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
232        deviceVersion = info.device_version;
233    } else {
234        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
235    }
236
237    if (facing) {
238        *facing = info.facing;
239    }
240
241    return deviceVersion;
242}
243
244bool CameraService::isValidCameraId(int cameraId) {
245    int facing;
246    int deviceVersion = getDeviceVersion(cameraId, &facing);
247
248    switch(deviceVersion) {
249      case CAMERA_DEVICE_API_VERSION_1_0:
250      case CAMERA_DEVICE_API_VERSION_2_0:
251      case CAMERA_DEVICE_API_VERSION_2_1:
252      case CAMERA_DEVICE_API_VERSION_3_0:
253        return true;
254      default:
255        return false;
256    }
257
258    return false;
259}
260
261bool CameraService::validateConnect(int cameraId,
262                                    /*inout*/
263                                    int& clientUid) const {
264
265    int callingPid = getCallingPid();
266
267    if (clientUid == USE_CALLING_UID) {
268        clientUid = getCallingUid();
269    } else {
270        // We only trust our own process to forward client UIDs
271        if (callingPid != getpid()) {
272            ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
273                    callingPid);
274            return false;
275        }
276    }
277
278    if (!mModule) {
279        ALOGE("Camera HAL module not loaded");
280        return false;
281    }
282
283    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
284        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
285            callingPid, cameraId);
286        return false;
287    }
288
289    char value[PROPERTY_VALUE_MAX];
290    property_get("sys.secpolicy.camera.disabled", value, "0");
291    if (strcmp(value, "1") == 0) {
292        // Camera is disabled by DevicePolicyManager.
293        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
294        return false;
295    }
296
297    ICameraServiceListener::Status currentStatus = getStatus(cameraId);
298    if (currentStatus == ICameraServiceListener::STATUS_NOT_PRESENT) {
299        ALOGI("Camera is not plugged in,"
300               " connect X (pid %d) rejected", callingPid);
301        return false;
302    } else if (currentStatus == ICameraServiceListener::STATUS_ENUMERATING) {
303        ALOGI("Camera is enumerating,"
304               " connect X (pid %d) rejected", callingPid);
305        return false;
306    }
307    // Else don't check for STATUS_NOT_AVAILABLE.
308    //  -- It's done implicitly in canConnectUnsafe /w the mBusy array
309
310    return true;
311}
312
313bool CameraService::canConnectUnsafe(int cameraId,
314                                     const String16& clientPackageName,
315                                     const sp<IBinder>& remoteCallback,
316                                     sp<Client> &client) {
317    String8 clientName8(clientPackageName);
318    int callingPid = getCallingPid();
319
320    if (mClient[cameraId] != 0) {
321        client = mClient[cameraId].promote();
322        if (client != 0) {
323            if (remoteCallback == client->getRemoteCallback()->asBinder()) {
324                LOG1("CameraService::connect X (pid %d) (the same client)",
325                     callingPid);
326                return true;
327            } else {
328                // TODOSC: need to support 1 regular client,
329                // multiple shared clients here
330                ALOGW("CameraService::connect X (pid %d) rejected"
331                      " (existing client).", callingPid);
332                return false;
333            }
334        }
335        mClient[cameraId].clear();
336    }
337
338    /*
339    mBusy is set to false as the last step of the Client destructor,
340    after which it is guaranteed that the Client destructor has finished (
341    including any inherited destructors)
342
343    We only need this for a Client subclasses since we don't allow
344    multiple Clents to be opened concurrently, but multiple BasicClient
345    would be fine
346    */
347    if (mBusy[cameraId]) {
348        ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
349                " (camera %d is still busy).", callingPid,
350                clientName8.string(), cameraId);
351        return false;
352    }
353
354    return true;
355}
356
357sp<ICamera> CameraService::connect(
358        const sp<ICameraClient>& cameraClient,
359        int cameraId,
360        const String16& clientPackageName,
361        int clientUid) {
362
363    String8 clientName8(clientPackageName);
364    int callingPid = getCallingPid();
365
366    LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
367            clientName8.string(), cameraId);
368
369    if (!validateConnect(cameraId, /*inout*/clientUid)) {
370        return NULL;
371    }
372
373    sp<Client> client;
374
375    {
376        Mutex::Autolock lock(mServiceLock);
377        if (!canConnectUnsafe(cameraId, clientPackageName,
378                              cameraClient->asBinder(),
379                              /*out*/client)) {
380            return NULL;
381        } else if (client.get() != NULL) {
382            return client;
383        }
384
385        int facing = -1;
386        int deviceVersion = getDeviceVersion(cameraId, &facing);
387
388        // If there are other non-exclusive users of the camera,
389        //  this will tear them down before we can reuse the camera
390        if (isValidCameraId(cameraId)) {
391            // transition from PRESENT -> NOT_AVAILABLE
392            updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
393                         cameraId);
394        }
395
396        switch(deviceVersion) {
397          case CAMERA_DEVICE_API_VERSION_1_0:
398            client = new CameraClient(this, cameraClient,
399                    clientPackageName, cameraId,
400                    facing, callingPid, clientUid, getpid());
401            break;
402          case CAMERA_DEVICE_API_VERSION_2_0:
403          case CAMERA_DEVICE_API_VERSION_2_1:
404          case CAMERA_DEVICE_API_VERSION_3_0:
405            client = new Camera2Client(this, cameraClient,
406                    clientPackageName, cameraId,
407                    facing, callingPid, clientUid, getpid(),
408                    deviceVersion);
409            break;
410          case -1:
411            ALOGE("Invalid camera id %d", cameraId);
412            return NULL;
413          default:
414            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
415            return NULL;
416        }
417
418        if (!connectFinishUnsafe(client, client->asBinder())) {
419            // this is probably not recoverable.. maybe the client can try again
420            // OK: we can only get here if we were originally in PRESENT state
421            updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
422
423            return NULL;
424        }
425
426        mClient[cameraId] = client;
427        LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
428             getpid());
429    }
430    // important: release the mutex here so the client can call back
431    //    into the service from its destructor (can be at the end of the call)
432
433    return client;
434}
435
436bool CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
437                                        const sp<IBinder>& clientBinder) {
438    if (client->initialize(mModule) != OK) {
439        return false;
440    }
441
442    clientBinder->linkToDeath(this);
443
444    return true;
445}
446
447sp<IProCameraUser> CameraService::connect(
448                                        const sp<IProCameraCallbacks>& cameraCb,
449                                        int cameraId,
450                                        const String16& clientPackageName,
451                                        int clientUid)
452{
453    String8 clientName8(clientPackageName);
454    int callingPid = getCallingPid();
455
456    LOG1("CameraService::connectPro E (pid %d \"%s\", id %d)", callingPid,
457            clientName8.string(), cameraId);
458
459    if (!validateConnect(cameraId, /*inout*/clientUid)) {
460        return NULL;
461    }
462
463    sp<ProClient> client;
464    {
465        Mutex::Autolock lock(mServiceLock);
466        {
467            sp<Client> client;
468            if (!canConnectUnsafe(cameraId, clientPackageName,
469                                  cameraCb->asBinder(),
470                                  /*out*/client)) {
471                return NULL;
472            }
473        }
474
475        int facing = -1;
476        int deviceVersion = getDeviceVersion(cameraId, &facing);
477
478        switch(deviceVersion) {
479          case CAMERA_DEVICE_API_VERSION_1_0:
480            ALOGE("Camera id %d uses HALv1, doesn't support ProCamera",
481                  cameraId);
482            return NULL;
483            break;
484          case CAMERA_DEVICE_API_VERSION_2_0:
485          case CAMERA_DEVICE_API_VERSION_2_1:
486            client = new ProCamera2Client(this, cameraCb, String16(),
487                    cameraId, facing, callingPid, USE_CALLING_UID, getpid());
488            break;
489          case -1:
490            ALOGE("Invalid camera id %d", cameraId);
491            return NULL;
492          default:
493            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
494            return NULL;
495        }
496
497        if (!connectFinishUnsafe(client, client->asBinder())) {
498            return NULL;
499        }
500
501        mProClientList[cameraId].push(client);
502
503        LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
504                getpid());
505    }
506    // important: release the mutex here so the client can call back
507    //    into the service from its destructor (can be at the end of the call)
508
509    return client;
510}
511
512status_t CameraService::addListener(
513                                const sp<ICameraServiceListener>& listener) {
514    ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
515
516    Mutex::Autolock lock(mServiceLock);
517
518    Vector<sp<ICameraServiceListener> >::iterator it, end;
519    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
520        if ((*it)->asBinder() == listener->asBinder()) {
521            ALOGW("%s: Tried to add listener %p which was already subscribed",
522                  __FUNCTION__, listener.get());
523            return ALREADY_EXISTS;
524        }
525    }
526
527    mListenerList.push_back(listener);
528
529    /* Immediately signal current status to this listener only */
530    {
531        Mutex::Autolock m(mStatusMutex) ;
532        int numCams = getNumberOfCameras();
533        for (int i = 0; i < numCams; ++i) {
534            listener->onStatusChanged(mStatusList[i], i);
535        }
536    }
537
538    return OK;
539}
540status_t CameraService::removeListener(
541                                const sp<ICameraServiceListener>& listener) {
542    ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
543
544    Mutex::Autolock lock(mServiceLock);
545
546    Vector<sp<ICameraServiceListener> >::iterator it;
547    for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
548        if ((*it)->asBinder() == listener->asBinder()) {
549            mListenerList.erase(it);
550            return OK;
551        }
552    }
553
554    ALOGW("%s: Tried to remove a listener %p which was not subscribed",
555          __FUNCTION__, listener.get());
556
557    return BAD_VALUE;
558}
559
560void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
561    int callingPid = getCallingPid();
562    LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
563
564    // Declare this before the lock to make absolutely sure the
565    // destructor won't be called with the lock held.
566    Mutex::Autolock lock(mServiceLock);
567
568    int outIndex;
569    sp<Client> client = findClientUnsafe(remoteBinder, outIndex);
570
571    if (client != 0) {
572        // Found our camera, clear and leave.
573        LOG1("removeClient: clear camera %d", outIndex);
574        mClient[outIndex].clear();
575
576        client->unlinkToDeath(this);
577    } else {
578
579        sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
580
581        if (clientPro != NULL) {
582            // Found our camera, clear and leave.
583            LOG1("removeClient: clear pro %p", clientPro.get());
584
585            clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
586        }
587    }
588
589    LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
590}
591
592sp<CameraService::ProClient> CameraService::findProClientUnsafe(
593                        const wp<IBinder>& cameraCallbacksRemote)
594{
595    sp<ProClient> clientPro;
596
597    for (int i = 0; i < mNumberOfCameras; ++i) {
598        Vector<size_t> removeIdx;
599
600        for (size_t j = 0; j < mProClientList[i].size(); ++j) {
601            wp<ProClient> cl = mProClientList[i][j];
602
603            sp<ProClient> clStrong = cl.promote();
604            if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
605                clientPro = clStrong;
606                break;
607            } else if (clStrong == NULL) {
608                // mark to clean up dead ptr
609                removeIdx.push(j);
610            }
611        }
612
613        // remove stale ptrs (in reverse so the indices dont change)
614        for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
615            mProClientList[i].removeAt(removeIdx[j]);
616        }
617
618    }
619
620    return clientPro;
621}
622
623sp<CameraService::Client> CameraService::findClientUnsafe(
624                        const wp<IBinder>& cameraClient, int& outIndex) {
625    sp<Client> client;
626
627    for (int i = 0; i < mNumberOfCameras; i++) {
628
629        // This happens when we have already disconnected (or this is
630        // just another unused camera).
631        if (mClient[i] == 0) continue;
632
633        // Promote mClient. It can fail if we are called from this path:
634        // Client::~Client() -> disconnect() -> removeClientByRemote().
635        client = mClient[i].promote();
636
637        // Clean up stale client entry
638        if (client == NULL) {
639            mClient[i].clear();
640            continue;
641        }
642
643        if (cameraClient == client->getRemoteCallback()->asBinder()) {
644            // Found our camera
645            outIndex = i;
646            return client;
647        }
648    }
649
650    outIndex = -1;
651    return NULL;
652}
653
654CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
655    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
656    return mClient[cameraId].unsafe_get();
657}
658
659Mutex* CameraService::getClientLockById(int cameraId) {
660    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
661    return &mClientLock[cameraId];
662}
663
664sp<CameraService::BasicClient> CameraService::getClientByRemote(
665                                const wp<IBinder>& cameraClient) {
666
667    // Declare this before the lock to make absolutely sure the
668    // destructor won't be called with the lock held.
669    sp<BasicClient> client;
670
671    Mutex::Autolock lock(mServiceLock);
672
673    int outIndex;
674    client = findClientUnsafe(cameraClient, outIndex);
675
676    return client;
677}
678
679status_t CameraService::onTransact(
680    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
681    // Permission checks
682    switch (code) {
683        case BnCameraService::CONNECT:
684        case BnCameraService::CONNECT_PRO:
685            const int pid = getCallingPid();
686            const int self_pid = getpid();
687            if (pid != self_pid) {
688                // we're called from a different process, do the real check
689                if (!checkCallingPermission(
690                        String16("android.permission.CAMERA"))) {
691                    const int uid = getCallingUid();
692                    ALOGE("Permission Denial: "
693                         "can't use the camera pid=%d, uid=%d", pid, uid);
694                    return PERMISSION_DENIED;
695                }
696            }
697            break;
698    }
699
700    return BnCameraService::onTransact(code, data, reply, flags);
701}
702
703// The reason we need this busy bit is a new CameraService::connect() request
704// may come in while the previous Client's destructor has not been run or is
705// still running. If the last strong reference of the previous Client is gone
706// but the destructor has not been finished, we should not allow the new Client
707// to be created because we need to wait for the previous Client to tear down
708// the hardware first.
709void CameraService::setCameraBusy(int cameraId) {
710    android_atomic_write(1, &mBusy[cameraId]);
711
712    ALOGV("setCameraBusy cameraId=%d", cameraId);
713}
714
715void CameraService::setCameraFree(int cameraId) {
716    android_atomic_write(0, &mBusy[cameraId]);
717
718    ALOGV("setCameraFree cameraId=%d", cameraId);
719}
720
721// We share the media players for shutter and recording sound for all clients.
722// A reference count is kept to determine when we will actually release the
723// media players.
724
725MediaPlayer* CameraService::newMediaPlayer(const char *file) {
726    MediaPlayer* mp = new MediaPlayer();
727    if (mp->setDataSource(file, NULL) == NO_ERROR) {
728        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
729        mp->prepare();
730    } else {
731        ALOGE("Failed to load CameraService sounds: %s", file);
732        return NULL;
733    }
734    return mp;
735}
736
737void CameraService::loadSound() {
738    Mutex::Autolock lock(mSoundLock);
739    LOG1("CameraService::loadSound ref=%d", mSoundRef);
740    if (mSoundRef++) return;
741
742    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
743    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
744}
745
746void CameraService::releaseSound() {
747    Mutex::Autolock lock(mSoundLock);
748    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
749    if (--mSoundRef) return;
750
751    for (int i = 0; i < NUM_SOUNDS; i++) {
752        if (mSoundPlayer[i] != 0) {
753            mSoundPlayer[i]->disconnect();
754            mSoundPlayer[i].clear();
755        }
756    }
757}
758
759void CameraService::playSound(sound_kind kind) {
760    LOG1("playSound(%d)", kind);
761    Mutex::Autolock lock(mSoundLock);
762    sp<MediaPlayer> player = mSoundPlayer[kind];
763    if (player != 0) {
764        player->seekTo(0);
765        player->start();
766    }
767}
768
769// ----------------------------------------------------------------------------
770
771CameraService::Client::Client(const sp<CameraService>& cameraService,
772        const sp<ICameraClient>& cameraClient,
773        const String16& clientPackageName,
774        int cameraId, int cameraFacing,
775        int clientPid, uid_t clientUid,
776        int servicePid) :
777        CameraService::BasicClient(cameraService, cameraClient->asBinder(),
778                clientPackageName,
779                cameraId, cameraFacing,
780                clientPid, clientUid,
781                servicePid)
782{
783    int callingPid = getCallingPid();
784    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
785
786    mRemoteCallback = cameraClient;
787
788    cameraService->setCameraBusy(cameraId);
789    cameraService->loadSound();
790
791    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
792}
793
794// tear down the client
795CameraService::Client::~Client() {
796    mDestructionStarted = true;
797
798    mCameraService->releaseSound();
799    // unconditionally disconnect. function is idempotent
800    Client::disconnect();
801}
802
803CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
804        const sp<IBinder>& remoteCallback,
805        const String16& clientPackageName,
806        int cameraId, int cameraFacing,
807        int clientPid, uid_t clientUid,
808        int servicePid):
809        mClientPackageName(clientPackageName)
810{
811    mCameraService = cameraService;
812    mRemoteBinder = remoteCallback;
813    mCameraId = cameraId;
814    mCameraFacing = cameraFacing;
815    mClientPid = clientPid;
816    mClientUid = clientUid;
817    mServicePid = servicePid;
818    mOpsActive = false;
819    mDestructionStarted = false;
820}
821
822CameraService::BasicClient::~BasicClient() {
823    mDestructionStarted = true;
824}
825
826void CameraService::BasicClient::disconnect() {
827    mCameraService->removeClientByRemote(mRemoteBinder);
828    // client shouldn't be able to call into us anymore
829    mClientPid = 0;
830}
831
832status_t CameraService::BasicClient::startCameraOps() {
833    int32_t res;
834
835    mOpsCallback = new OpsCallback(this);
836
837    {
838        ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
839              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
840    }
841
842    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
843            mClientPackageName, mOpsCallback);
844    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
845            mClientUid, mClientPackageName);
846
847    if (res != AppOpsManager::MODE_ALLOWED) {
848        ALOGI("Camera %d: Access for \"%s\" has been revoked",
849                mCameraId, String8(mClientPackageName).string());
850        return PERMISSION_DENIED;
851    }
852    mOpsActive = true;
853    return OK;
854}
855
856status_t CameraService::BasicClient::finishCameraOps() {
857    if (mOpsActive) {
858        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
859                mClientPackageName);
860        mOpsActive = false;
861    }
862    mAppOpsManager.stopWatchingMode(mOpsCallback);
863    mOpsCallback.clear();
864
865    return OK;
866}
867
868void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
869    String8 name(packageName);
870    String8 myName(mClientPackageName);
871
872    if (op != AppOpsManager::OP_CAMERA) {
873        ALOGW("Unexpected app ops notification received: %d", op);
874        return;
875    }
876
877    int32_t res;
878    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
879            mClientUid, mClientPackageName);
880    ALOGV("checkOp returns: %d, %s ", res,
881            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
882            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
883            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
884            "UNKNOWN");
885
886    if (res != AppOpsManager::MODE_ALLOWED) {
887        ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
888                myName.string());
889        // Reset the client PID to allow server-initiated disconnect,
890        // and to prevent further calls by client.
891        mClientPid = getCallingPid();
892        notifyError();
893        disconnect();
894    }
895}
896
897// ----------------------------------------------------------------------------
898
899Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
900    return gCameraService->getClientLockById((int) user);
901}
902
903// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
904// be acquired for this to be safe
905CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
906    Client* client = gCameraService->getClientByIdUnsafe((int) user);
907
908    // This could happen if the Client is in the process of shutting down (the
909    // last strong reference is gone, but the destructor hasn't finished
910    // stopping the hardware).
911    if (client == NULL) return NULL;
912
913    // destruction already started, so should not be accessed
914    if (client->mDestructionStarted) return NULL;
915
916    return client;
917}
918
919void CameraService::Client::notifyError() {
920    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
921}
922
923// NOTE: function is idempotent
924void CameraService::Client::disconnect() {
925    BasicClient::disconnect();
926    mCameraService->setCameraFree(mCameraId);
927    mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
928                                 mCameraId);
929}
930
931CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
932        mClient(client) {
933}
934
935void CameraService::Client::OpsCallback::opChanged(int32_t op,
936        const String16& packageName) {
937    sp<BasicClient> client = mClient.promote();
938    if (client != NULL) {
939        client->opChanged(op, packageName);
940    }
941}
942
943// ----------------------------------------------------------------------------
944//                  IProCamera
945// ----------------------------------------------------------------------------
946
947CameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
948        const sp<IProCameraCallbacks>& remoteCallback,
949        const String16& clientPackageName,
950        int cameraId,
951        int cameraFacing,
952        int clientPid,
953        uid_t clientUid,
954        int servicePid)
955        : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
956                clientPackageName, cameraId, cameraFacing,
957                clientPid,  clientUid, servicePid)
958{
959    mRemoteCallback = remoteCallback;
960}
961
962CameraService::ProClient::~ProClient() {
963}
964
965void CameraService::ProClient::notifyError() {
966    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
967}
968
969// ----------------------------------------------------------------------------
970
971static const int kDumpLockRetries = 50;
972static const int kDumpLockSleep = 60000;
973
974static bool tryLock(Mutex& mutex)
975{
976    bool locked = false;
977    for (int i = 0; i < kDumpLockRetries; ++i) {
978        if (mutex.tryLock() == NO_ERROR) {
979            locked = true;
980            break;
981        }
982        usleep(kDumpLockSleep);
983    }
984    return locked;
985}
986
987status_t CameraService::dump(int fd, const Vector<String16>& args) {
988    String8 result;
989    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
990        result.appendFormat("Permission Denial: "
991                "can't dump CameraService from pid=%d, uid=%d\n",
992                getCallingPid(),
993                getCallingUid());
994        write(fd, result.string(), result.size());
995    } else {
996        bool locked = tryLock(mServiceLock);
997        // failed to lock - CameraService is probably deadlocked
998        if (!locked) {
999            result.append("CameraService may be deadlocked\n");
1000            write(fd, result.string(), result.size());
1001        }
1002
1003        bool hasClient = false;
1004        if (!mModule) {
1005            result = String8::format("No camera module available!\n");
1006            write(fd, result.string(), result.size());
1007            return NO_ERROR;
1008        }
1009
1010        result = String8::format("Camera module HAL API version: 0x%x\n",
1011                mModule->common.hal_api_version);
1012        result.appendFormat("Camera module API version: 0x%x\n",
1013                mModule->common.module_api_version);
1014        result.appendFormat("Camera module name: %s\n",
1015                mModule->common.name);
1016        result.appendFormat("Camera module author: %s\n",
1017                mModule->common.author);
1018        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
1019        write(fd, result.string(), result.size());
1020        for (int i = 0; i < mNumberOfCameras; i++) {
1021            result = String8::format("Camera %d static information:\n", i);
1022            camera_info info;
1023
1024            status_t rc = mModule->get_camera_info(i, &info);
1025            if (rc != OK) {
1026                result.appendFormat("  Error reading static information!\n");
1027                write(fd, result.string(), result.size());
1028            } else {
1029                result.appendFormat("  Facing: %s\n",
1030                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
1031                result.appendFormat("  Orientation: %d\n", info.orientation);
1032                int deviceVersion;
1033                if (mModule->common.module_api_version <
1034                        CAMERA_MODULE_API_VERSION_2_0) {
1035                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
1036                } else {
1037                    deviceVersion = info.device_version;
1038                }
1039                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
1040                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
1041                    result.appendFormat("  Device static metadata:\n");
1042                    write(fd, result.string(), result.size());
1043                    dump_indented_camera_metadata(info.static_camera_characteristics,
1044                            fd, 2, 4);
1045                } else {
1046                    write(fd, result.string(), result.size());
1047                }
1048            }
1049
1050            sp<Client> client = mClient[i].promote();
1051            if (client == 0) {
1052                result = String8::format("  Device is closed, no client instance\n");
1053                write(fd, result.string(), result.size());
1054                continue;
1055            }
1056            hasClient = true;
1057            result = String8::format("  Device is open. Client instance dump:\n");
1058            write(fd, result.string(), result.size());
1059            client->dump(fd, args);
1060        }
1061        if (!hasClient) {
1062            result = String8::format("\nNo active camera clients yet.\n");
1063            write(fd, result.string(), result.size());
1064        }
1065
1066        if (locked) mServiceLock.unlock();
1067
1068        // change logging level
1069        int n = args.size();
1070        for (int i = 0; i + 1 < n; i++) {
1071            String16 verboseOption("-v");
1072            if (args[i] == verboseOption) {
1073                String8 levelStr(args[i+1]);
1074                int level = atoi(levelStr.string());
1075                result = String8::format("\nSetting log level to %d.\n", level);
1076                setLogLevel(level);
1077                write(fd, result.string(), result.size());
1078            }
1079        }
1080
1081    }
1082    return NO_ERROR;
1083}
1084
1085/*virtual*/void CameraService::binderDied(
1086    const wp<IBinder> &who) {
1087
1088    /**
1089      * While tempting to promote the wp<IBinder> into a sp,
1090      * it's actually not supported by the binder driver
1091      */
1092
1093    ALOGV("java clients' binder died");
1094
1095    sp<BasicClient> cameraClient = getClientByRemote(who);
1096
1097    if (cameraClient == 0) {
1098        ALOGV("java clients' binder death already cleaned up (normal case)");
1099        return;
1100    }
1101
1102    ALOGW("Disconnecting camera client %p since the binder for it "
1103          "died (this pid %d)", cameraClient.get(), getCallingPid());
1104
1105    cameraClient->disconnect();
1106
1107}
1108
1109void CameraService::updateStatus(ICameraServiceListener::Status status,
1110                                 int32_t cameraId) {
1111    // do not lock mServiceLock here or can get into a deadlock from
1112    //  connect() -> ProClient::disconnect -> updateStatus
1113    Mutex::Autolock lock(mStatusMutex);
1114    updateStatusUnsafe(status, cameraId);
1115}
1116
1117void CameraService::updateStatusUnsafe(ICameraServiceListener::Status status,
1118                                       int32_t cameraId) {
1119
1120    ICameraServiceListener::Status oldStatus = mStatusList[cameraId];
1121
1122    mStatusList[cameraId] = status;
1123
1124    if (oldStatus != status) {
1125        ALOGV("%s: Status has changed for camera ID %d from 0x%x to 0x%x",
1126              __FUNCTION__, cameraId, (uint32_t)oldStatus, (uint32_t)status);
1127
1128        if (oldStatus == ICameraServiceListener::STATUS_NOT_PRESENT &&
1129            (status != ICameraServiceListener::STATUS_PRESENT &&
1130             status != ICameraServiceListener::STATUS_ENUMERATING)) {
1131
1132            ALOGW("%s: From NOT_PRESENT can only transition into PRESENT"
1133                  " or ENUMERATING", __FUNCTION__);
1134            mStatusList[cameraId] = oldStatus;
1135            return;
1136        }
1137
1138        /**
1139          * ProClients lose their exclusive lock.
1140          * - Done before the CameraClient can initialize the HAL device,
1141          *   since we want to be able to close it before they get to initialize
1142          */
1143        if (status == ICameraServiceListener::STATUS_NOT_AVAILABLE) {
1144            Vector<wp<ProClient> > proClients(mProClientList[cameraId]);
1145            Vector<wp<ProClient> >::const_iterator it;
1146
1147            for (it = proClients.begin(); it != proClients.end(); ++it) {
1148                sp<ProClient> proCl = it->promote();
1149                if (proCl.get() != NULL) {
1150                    proCl->onExclusiveLockStolen();
1151                }
1152            }
1153        }
1154
1155        Vector<sp<ICameraServiceListener> >::const_iterator it;
1156        for (it = mListenerList.begin(); it != mListenerList.end(); ++it) {
1157            (*it)->onStatusChanged(status, cameraId);
1158        }
1159    }
1160}
1161
1162ICameraServiceListener::Status CameraService::getStatus(int cameraId) const {
1163    if (cameraId < 0 || cameraId >= MAX_CAMERAS) {
1164        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
1165        return ICameraServiceListener::STATUS_UNKNOWN;
1166    }
1167
1168    Mutex::Autolock al(mStatusMutex);
1169    return mStatusList[cameraId];
1170}
1171
1172}; // namespace android
1173