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