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