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