CameraClient.cpp revision 7b82efe7a376c882f8f938e1c41b8311a8cdda4a
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "CameraClient"
18//#define LOG_NDEBUG 0
19
20#include <cutils/properties.h>
21#include <gui/Surface.h>
22
23#include "api1/CameraClient.h"
24#include "device1/CameraHardwareInterface.h"
25#include "CameraService.h"
26
27namespace android {
28
29#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
30#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
31
32static int getCallingPid() {
33    return IPCThreadState::self()->getCallingPid();
34}
35
36CameraClient::CameraClient(const sp<CameraService>& cameraService,
37        const sp<ICameraClient>& cameraClient,
38        const String16& clientPackageName,
39        int cameraId, int cameraFacing,
40        int clientPid, int clientUid,
41        int servicePid):
42        Client(cameraService, cameraClient, clientPackageName,
43                cameraId, cameraFacing, clientPid, clientUid, servicePid)
44{
45    int callingPid = getCallingPid();
46    LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
47
48    mHardware = NULL;
49    mMsgEnabled = 0;
50    mSurface = 0;
51    mPreviewWindow = 0;
52    mDestructionStarted = false;
53
54    // Callback is disabled by default
55    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
56    mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
57    mPlayShutterSound = true;
58    LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
59}
60
61status_t CameraClient::initialize(camera_module_t *module) {
62    int callingPid = getCallingPid();
63    status_t res;
64
65    LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
66
67    // Verify ops permissions
68    res = startCameraOps();
69    if (res != OK) {
70        return res;
71    }
72
73    char camera_device_name[10];
74    snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
75
76    mHardware = new CameraHardwareInterface(camera_device_name);
77    res = mHardware->initialize(&module->common);
78    if (res != OK) {
79        ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
80                __FUNCTION__, mCameraId, strerror(-res), res);
81        mHardware.clear();
82        return NO_INIT;
83    }
84
85    mHardware->setCallbacks(notifyCallback,
86            dataCallback,
87            dataCallbackTimestamp,
88            (void *)mCameraId);
89
90    // Enable zoom, error, focus, and metadata messages by default
91    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
92                  CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
93
94    LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
95    return OK;
96}
97
98
99// tear down the client
100CameraClient::~CameraClient() {
101    // this lock should never be NULL
102    Mutex* lock = mCameraService->getClientLockById(mCameraId);
103    lock->lock();
104    mDestructionStarted = true;
105    // client will not be accessed from callback. should unlock to prevent dead-lock in disconnect
106    lock->unlock();
107    int callingPid = getCallingPid();
108    LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
109
110    disconnect();
111    LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
112}
113
114status_t CameraClient::dump(int fd, const Vector<String16>& args) {
115    const size_t SIZE = 256;
116    char buffer[SIZE];
117
118    size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) PID: %d\n",
119            mCameraId,
120            getRemoteCallback()->asBinder().get(),
121            mClientPid);
122    len = (len > SIZE - 1) ? SIZE - 1 : len;
123    write(fd, buffer, len);
124    return mHardware->dump(fd, args);
125}
126
127// ----------------------------------------------------------------------------
128
129status_t CameraClient::checkPid() const {
130    int callingPid = getCallingPid();
131    if (callingPid == mClientPid) return NO_ERROR;
132
133    ALOGW("attempt to use a locked camera from a different process"
134         " (old pid %d, new pid %d)", mClientPid, callingPid);
135    return EBUSY;
136}
137
138status_t CameraClient::checkPidAndHardware() const {
139    status_t result = checkPid();
140    if (result != NO_ERROR) return result;
141    if (mHardware == 0) {
142        ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
143        return INVALID_OPERATION;
144    }
145    return NO_ERROR;
146}
147
148status_t CameraClient::lock() {
149    int callingPid = getCallingPid();
150    LOG1("lock (pid %d)", callingPid);
151    Mutex::Autolock lock(mLock);
152
153    // lock camera to this client if the the camera is unlocked
154    if (mClientPid == 0) {
155        mClientPid = callingPid;
156        return NO_ERROR;
157    }
158
159    // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
160    return checkPid();
161}
162
163status_t CameraClient::unlock() {
164    int callingPid = getCallingPid();
165    LOG1("unlock (pid %d)", callingPid);
166    Mutex::Autolock lock(mLock);
167
168    // allow anyone to use camera (after they lock the camera)
169    status_t result = checkPid();
170    if (result == NO_ERROR) {
171        if (mHardware->recordingEnabled()) {
172            ALOGE("Not allowed to unlock camera during recording.");
173            return INVALID_OPERATION;
174        }
175        mClientPid = 0;
176        LOG1("clear mRemoteCallback (pid %d)", callingPid);
177        // we need to remove the reference to ICameraClient so that when the app
178        // goes away, the reference count goes to 0.
179        mRemoteCallback.clear();
180    }
181    return result;
182}
183
184// connect a new client to the camera
185status_t CameraClient::connect(const sp<ICameraClient>& client) {
186    int callingPid = getCallingPid();
187    LOG1("connect E (pid %d)", callingPid);
188    Mutex::Autolock lock(mLock);
189
190    if (mClientPid != 0 && checkPid() != NO_ERROR) {
191        ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
192                mClientPid, callingPid);
193        return EBUSY;
194    }
195
196    if (mRemoteCallback != 0 &&
197        (client->asBinder() == mRemoteCallback->asBinder())) {
198        LOG1("Connect to the same client");
199        return NO_ERROR;
200    }
201
202    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
203    mClientPid = callingPid;
204    mRemoteCallback = client;
205
206    LOG1("connect X (pid %d)", callingPid);
207    return NO_ERROR;
208}
209
210static void disconnectWindow(const sp<ANativeWindow>& window) {
211    if (window != 0) {
212        status_t result = native_window_api_disconnect(window.get(),
213                NATIVE_WINDOW_API_CAMERA);
214        if (result != NO_ERROR) {
215            ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
216                    result);
217        }
218    }
219}
220
221void CameraClient::disconnect() {
222    int callingPid = getCallingPid();
223    LOG1("disconnect E (pid %d)", callingPid);
224    Mutex::Autolock lock(mLock);
225
226    // Allow both client and the media server to disconnect at all times
227    if (callingPid != mClientPid && callingPid != mServicePid) {
228        ALOGW("different client - don't disconnect");
229        return;
230    }
231
232    if (mClientPid <= 0) {
233        LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
234        return;
235    }
236
237    // Make sure disconnect() is done once and once only, whether it is called
238    // from the user directly, or called by the destructor.
239    if (mHardware == 0) return;
240
241    LOG1("hardware teardown");
242    // Before destroying mHardware, we must make sure it's in the
243    // idle state.
244    // Turn off all messages.
245    disableMsgType(CAMERA_MSG_ALL_MSGS);
246    mHardware->stopPreview();
247    mHardware->cancelPicture();
248    // Release the hardware resources.
249    mHardware->release();
250
251    // Release the held ANativeWindow resources.
252    if (mPreviewWindow != 0) {
253        disconnectWindow(mPreviewWindow);
254        mPreviewWindow = 0;
255        mHardware->setPreviewWindow(mPreviewWindow);
256    }
257    mHardware.clear();
258
259    CameraService::Client::disconnect();
260
261    LOG1("disconnect X (pid %d)", callingPid);
262}
263
264// ----------------------------------------------------------------------------
265
266status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder,
267        const sp<ANativeWindow>& window) {
268    Mutex::Autolock lock(mLock);
269    status_t result = checkPidAndHardware();
270    if (result != NO_ERROR) return result;
271
272    // return if no change in surface.
273    if (binder == mSurface) {
274        return NO_ERROR;
275    }
276
277    if (window != 0) {
278        result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
279        if (result != NO_ERROR) {
280            ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
281                    result);
282            return result;
283        }
284    }
285
286    // If preview has been already started, register preview buffers now.
287    if (mHardware->previewEnabled()) {
288        if (window != 0) {
289            native_window_set_scaling_mode(window.get(),
290                    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
291            native_window_set_buffers_transform(window.get(), mOrientation);
292            result = mHardware->setPreviewWindow(window);
293        }
294    }
295
296    if (result == NO_ERROR) {
297        // Everything has succeeded.  Disconnect the old window and remember the
298        // new window.
299        disconnectWindow(mPreviewWindow);
300        mSurface = binder;
301        mPreviewWindow = window;
302    } else {
303        // Something went wrong after we connected to the new window, so
304        // disconnect here.
305        disconnectWindow(window);
306    }
307
308    return result;
309}
310
311// set the Surface that the preview will use
312status_t CameraClient::setPreviewDisplay(const sp<Surface>& surface) {
313    LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
314
315    sp<IBinder> binder(surface != 0 ? surface->getIGraphicBufferProducer()->asBinder() : 0);
316    sp<ANativeWindow> window(surface);
317    return setPreviewWindow(binder, window);
318}
319
320// set the SurfaceTextureClient that the preview will use
321status_t CameraClient::setPreviewTexture(
322        const sp<IGraphicBufferProducer>& bufferProducer) {
323    LOG1("setPreviewTexture(%p) (pid %d)", bufferProducer.get(),
324            getCallingPid());
325
326    sp<IBinder> binder;
327    sp<ANativeWindow> window;
328    if (bufferProducer != 0) {
329        binder = bufferProducer->asBinder();
330        window = new Surface(bufferProducer);
331    }
332    return setPreviewWindow(binder, window);
333}
334
335// set the preview callback flag to affect how the received frames from
336// preview are handled.
337void CameraClient::setPreviewCallbackFlag(int callback_flag) {
338    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
339    Mutex::Autolock lock(mLock);
340    if (checkPidAndHardware() != NO_ERROR) return;
341
342    mPreviewCallbackFlag = callback_flag;
343    if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
344        enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
345    } else {
346        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
347    }
348}
349
350status_t CameraClient::setPreviewCallbackTarget(
351        const sp<IGraphicBufferProducer>& callbackProducer) {
352    (void)callbackProducer;
353    ALOGE("%s: Unimplemented!", __FUNCTION__);
354    return INVALID_OPERATION;
355}
356
357// start preview mode
358status_t CameraClient::startPreview() {
359    LOG1("startPreview (pid %d)", getCallingPid());
360    return startCameraMode(CAMERA_PREVIEW_MODE);
361}
362
363// start recording mode
364status_t CameraClient::startRecording() {
365    LOG1("startRecording (pid %d)", getCallingPid());
366    return startCameraMode(CAMERA_RECORDING_MODE);
367}
368
369// start preview or recording
370status_t CameraClient::startCameraMode(camera_mode mode) {
371    LOG1("startCameraMode(%d)", mode);
372    Mutex::Autolock lock(mLock);
373    status_t result = checkPidAndHardware();
374    if (result != NO_ERROR) return result;
375
376    switch(mode) {
377        case CAMERA_PREVIEW_MODE:
378            if (mSurface == 0 && mPreviewWindow == 0) {
379                LOG1("mSurface is not set yet.");
380                // still able to start preview in this case.
381            }
382            return startPreviewMode();
383        case CAMERA_RECORDING_MODE:
384            if (mSurface == 0 && mPreviewWindow == 0) {
385                ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
386                return INVALID_OPERATION;
387            }
388            return startRecordingMode();
389        default:
390            return UNKNOWN_ERROR;
391    }
392}
393
394status_t CameraClient::startPreviewMode() {
395    LOG1("startPreviewMode");
396    status_t result = NO_ERROR;
397
398    // if preview has been enabled, nothing needs to be done
399    if (mHardware->previewEnabled()) {
400        return NO_ERROR;
401    }
402
403    if (mPreviewWindow != 0) {
404        native_window_set_scaling_mode(mPreviewWindow.get(),
405                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
406        native_window_set_buffers_transform(mPreviewWindow.get(),
407                mOrientation);
408    }
409    mHardware->setPreviewWindow(mPreviewWindow);
410    result = mHardware->startPreview();
411
412    return result;
413}
414
415status_t CameraClient::startRecordingMode() {
416    LOG1("startRecordingMode");
417    status_t result = NO_ERROR;
418
419    // if recording has been enabled, nothing needs to be done
420    if (mHardware->recordingEnabled()) {
421        return NO_ERROR;
422    }
423
424    // if preview has not been started, start preview first
425    if (!mHardware->previewEnabled()) {
426        result = startPreviewMode();
427        if (result != NO_ERROR) {
428            return result;
429        }
430    }
431
432    // start recording mode
433    enableMsgType(CAMERA_MSG_VIDEO_FRAME);
434    mCameraService->playSound(CameraService::SOUND_RECORDING);
435    result = mHardware->startRecording();
436    if (result != NO_ERROR) {
437        ALOGE("mHardware->startRecording() failed with status %d", result);
438    }
439    return result;
440}
441
442// stop preview mode
443void CameraClient::stopPreview() {
444    LOG1("stopPreview (pid %d)", getCallingPid());
445    Mutex::Autolock lock(mLock);
446    if (checkPidAndHardware() != NO_ERROR) return;
447
448
449    disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
450    mHardware->stopPreview();
451
452    mPreviewBuffer.clear();
453}
454
455// stop recording mode
456void CameraClient::stopRecording() {
457    LOG1("stopRecording (pid %d)", getCallingPid());
458    Mutex::Autolock lock(mLock);
459    if (checkPidAndHardware() != NO_ERROR) return;
460
461    disableMsgType(CAMERA_MSG_VIDEO_FRAME);
462    mHardware->stopRecording();
463    mCameraService->playSound(CameraService::SOUND_RECORDING);
464
465    mPreviewBuffer.clear();
466}
467
468// release a recording frame
469void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
470    Mutex::Autolock lock(mLock);
471    if (checkPidAndHardware() != NO_ERROR) return;
472    mHardware->releaseRecordingFrame(mem);
473}
474
475status_t CameraClient::storeMetaDataInBuffers(bool enabled)
476{
477    LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
478    Mutex::Autolock lock(mLock);
479    if (checkPidAndHardware() != NO_ERROR) {
480        return UNKNOWN_ERROR;
481    }
482    return mHardware->storeMetaDataInBuffers(enabled);
483}
484
485bool CameraClient::previewEnabled() {
486    LOG1("previewEnabled (pid %d)", getCallingPid());
487
488    Mutex::Autolock lock(mLock);
489    if (checkPidAndHardware() != NO_ERROR) return false;
490    return mHardware->previewEnabled();
491}
492
493bool CameraClient::recordingEnabled() {
494    LOG1("recordingEnabled (pid %d)", getCallingPid());
495
496    Mutex::Autolock lock(mLock);
497    if (checkPidAndHardware() != NO_ERROR) return false;
498    return mHardware->recordingEnabled();
499}
500
501status_t CameraClient::autoFocus() {
502    LOG1("autoFocus (pid %d)", getCallingPid());
503
504    Mutex::Autolock lock(mLock);
505    status_t result = checkPidAndHardware();
506    if (result != NO_ERROR) return result;
507
508    return mHardware->autoFocus();
509}
510
511status_t CameraClient::cancelAutoFocus() {
512    LOG1("cancelAutoFocus (pid %d)", getCallingPid());
513
514    Mutex::Autolock lock(mLock);
515    status_t result = checkPidAndHardware();
516    if (result != NO_ERROR) return result;
517
518    return mHardware->cancelAutoFocus();
519}
520
521// take a picture - image is returned in callback
522status_t CameraClient::takePicture(int msgType) {
523    LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
524
525    Mutex::Autolock lock(mLock);
526    status_t result = checkPidAndHardware();
527    if (result != NO_ERROR) return result;
528
529    if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
530        (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
531        ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
532                " cannot be both enabled");
533        return BAD_VALUE;
534    }
535
536    // We only accept picture related message types
537    // and ignore other types of messages for takePicture().
538    int picMsgType = msgType
539                        & (CAMERA_MSG_SHUTTER |
540                           CAMERA_MSG_POSTVIEW_FRAME |
541                           CAMERA_MSG_RAW_IMAGE |
542                           CAMERA_MSG_RAW_IMAGE_NOTIFY |
543                           CAMERA_MSG_COMPRESSED_IMAGE);
544
545    enableMsgType(picMsgType);
546
547    return mHardware->takePicture();
548}
549
550// set preview/capture parameters - key/value pairs
551status_t CameraClient::setParameters(const String8& params) {
552    LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
553
554    Mutex::Autolock lock(mLock);
555    status_t result = checkPidAndHardware();
556    if (result != NO_ERROR) return result;
557
558    CameraParameters p(params);
559    return mHardware->setParameters(p);
560}
561
562// get preview/capture parameters - key/value pairs
563String8 CameraClient::getParameters() const {
564    Mutex::Autolock lock(mLock);
565    if (checkPidAndHardware() != NO_ERROR) return String8();
566
567    String8 params(mHardware->getParameters().flatten());
568    LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
569    return params;
570}
571
572// enable shutter sound
573status_t CameraClient::enableShutterSound(bool enable) {
574    LOG1("enableShutterSound (pid %d)", getCallingPid());
575
576    status_t result = checkPidAndHardware();
577    if (result != NO_ERROR) return result;
578
579    if (enable) {
580        mPlayShutterSound = true;
581        return OK;
582    }
583
584    // Disabling shutter sound may not be allowed. In that case only
585    // allow the mediaserver process to disable the sound.
586    char value[PROPERTY_VALUE_MAX];
587    property_get("ro.camera.sound.forced", value, "0");
588    if (strcmp(value, "0") != 0) {
589        // Disabling shutter sound is not allowed. Deny if the current
590        // process is not mediaserver.
591        if (getCallingPid() != getpid()) {
592            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
593            return PERMISSION_DENIED;
594        }
595    }
596
597    mPlayShutterSound = false;
598    return OK;
599}
600
601status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
602    LOG1("sendCommand (pid %d)", getCallingPid());
603    int orientation;
604    Mutex::Autolock lock(mLock);
605    status_t result = checkPidAndHardware();
606    if (result != NO_ERROR) return result;
607
608    if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
609        // Mirror the preview if the camera is front-facing.
610        orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
611        if (orientation == -1) return BAD_VALUE;
612
613        if (mOrientation != orientation) {
614            mOrientation = orientation;
615            if (mPreviewWindow != 0) {
616                native_window_set_buffers_transform(mPreviewWindow.get(),
617                        mOrientation);
618            }
619        }
620        return OK;
621    } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
622        switch (arg1) {
623            case 0:
624                return enableShutterSound(false);
625            case 1:
626                return enableShutterSound(true);
627            default:
628                return BAD_VALUE;
629        }
630        return OK;
631    } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
632        mCameraService->playSound(CameraService::SOUND_RECORDING);
633    } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
634        // Silently ignore this command
635        return INVALID_OPERATION;
636    } else if (cmd == CAMERA_CMD_PING) {
637        // If mHardware is 0, checkPidAndHardware will return error.
638        return OK;
639    }
640
641    return mHardware->sendCommand(cmd, arg1, arg2);
642}
643
644// ----------------------------------------------------------------------------
645
646void CameraClient::enableMsgType(int32_t msgType) {
647    android_atomic_or(msgType, &mMsgEnabled);
648    mHardware->enableMsgType(msgType);
649}
650
651void CameraClient::disableMsgType(int32_t msgType) {
652    android_atomic_and(~msgType, &mMsgEnabled);
653    mHardware->disableMsgType(msgType);
654}
655
656#define CHECK_MESSAGE_INTERVAL 10 // 10ms
657bool CameraClient::lockIfMessageWanted(int32_t msgType) {
658    int sleepCount = 0;
659    while (mMsgEnabled & msgType) {
660        if (mLock.tryLock() == NO_ERROR) {
661            if (sleepCount > 0) {
662                LOG1("lockIfMessageWanted(%d): waited for %d ms",
663                    msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
664            }
665            return true;
666        }
667        if (sleepCount++ == 0) {
668            LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
669        }
670        usleep(CHECK_MESSAGE_INTERVAL * 1000);
671    }
672    ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
673    return false;
674}
675
676// Callback messages can be dispatched to internal handlers or pass to our
677// client's callback functions, depending on the message type.
678//
679// notifyCallback:
680//      CAMERA_MSG_SHUTTER              handleShutter
681//      (others)                        c->notifyCallback
682// dataCallback:
683//      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
684//      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
685//      CAMERA_MSG_RAW_IMAGE            handleRawPicture
686//      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
687//      (others)                        c->dataCallback
688// dataCallbackTimestamp
689//      (others)                        c->dataCallbackTimestamp
690//
691// NOTE: the *Callback functions grab mLock of the client before passing
692// control to handle* functions. So the handle* functions must release the
693// lock before calling the ICameraClient's callbacks, so those callbacks can
694// invoke methods in the Client class again (For example, the preview frame
695// callback may want to releaseRecordingFrame). The handle* functions must
696// release the lock after all accesses to member variables, so it must be
697// handled very carefully.
698
699void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
700        int32_t ext2, void* user) {
701    LOG2("notifyCallback(%d)", msgType);
702
703    Mutex* lock = getClientLockFromCookie(user);
704    if (lock == NULL) return;
705    Mutex::Autolock alock(*lock);
706
707    CameraClient* client =
708            static_cast<CameraClient*>(getClientFromCookie(user));
709    if (client == NULL) return;
710
711    if (!client->lockIfMessageWanted(msgType)) return;
712
713    switch (msgType) {
714        case CAMERA_MSG_SHUTTER:
715            // ext1 is the dimension of the yuv picture.
716            client->handleShutter();
717            break;
718        default:
719            client->handleGenericNotify(msgType, ext1, ext2);
720            break;
721    }
722}
723
724void CameraClient::dataCallback(int32_t msgType,
725        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
726    LOG2("dataCallback(%d)", msgType);
727
728    Mutex* lock = getClientLockFromCookie(user);
729    if (lock == NULL) return;
730    Mutex::Autolock alock(*lock);
731
732    CameraClient* client =
733            static_cast<CameraClient*>(getClientFromCookie(user));
734    if (client == NULL) return;
735
736    if (!client->lockIfMessageWanted(msgType)) return;
737    if (dataPtr == 0 && metadata == NULL) {
738        ALOGE("Null data returned in data callback");
739        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
740        return;
741    }
742
743    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
744        case CAMERA_MSG_PREVIEW_FRAME:
745            client->handlePreviewData(msgType, dataPtr, metadata);
746            break;
747        case CAMERA_MSG_POSTVIEW_FRAME:
748            client->handlePostview(dataPtr);
749            break;
750        case CAMERA_MSG_RAW_IMAGE:
751            client->handleRawPicture(dataPtr);
752            break;
753        case CAMERA_MSG_COMPRESSED_IMAGE:
754            client->handleCompressedPicture(dataPtr);
755            break;
756        default:
757            client->handleGenericData(msgType, dataPtr, metadata);
758            break;
759    }
760}
761
762void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
763        int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
764    LOG2("dataCallbackTimestamp(%d)", msgType);
765
766    Mutex* lock = getClientLockFromCookie(user);
767    if (lock == NULL) return;
768    Mutex::Autolock alock(*lock);
769
770    CameraClient* client =
771            static_cast<CameraClient*>(getClientFromCookie(user));
772    if (client == NULL) return;
773
774    if (!client->lockIfMessageWanted(msgType)) return;
775
776    if (dataPtr == 0) {
777        ALOGE("Null data returned in data with timestamp callback");
778        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
779        return;
780    }
781
782    client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
783}
784
785// snapshot taken callback
786void CameraClient::handleShutter(void) {
787    if (mPlayShutterSound) {
788        mCameraService->playSound(CameraService::SOUND_SHUTTER);
789    }
790
791    sp<ICameraClient> c = mRemoteCallback;
792    if (c != 0) {
793        mLock.unlock();
794        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
795        if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
796    }
797    disableMsgType(CAMERA_MSG_SHUTTER);
798
799    mLock.unlock();
800}
801
802// preview callback - frame buffer update
803void CameraClient::handlePreviewData(int32_t msgType,
804                                              const sp<IMemory>& mem,
805                                              camera_frame_metadata_t *metadata) {
806    ssize_t offset;
807    size_t size;
808    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
809
810    // local copy of the callback flags
811    int flags = mPreviewCallbackFlag;
812
813    // is callback enabled?
814    if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
815        // If the enable bit is off, the copy-out and one-shot bits are ignored
816        LOG2("frame callback is disabled");
817        mLock.unlock();
818        return;
819    }
820
821    // hold a strong pointer to the client
822    sp<ICameraClient> c = mRemoteCallback;
823
824    // clear callback flags if no client or one-shot mode
825    if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
826        LOG2("Disable preview callback");
827        mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
828                                  CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
829                                  CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
830        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
831    }
832
833    if (c != 0) {
834        // Is the received frame copied out or not?
835        if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
836            LOG2("frame is copied");
837            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
838        } else {
839            LOG2("frame is forwarded");
840            mLock.unlock();
841            c->dataCallback(msgType, mem, metadata);
842        }
843    } else {
844        mLock.unlock();
845    }
846}
847
848// picture callback - postview image ready
849void CameraClient::handlePostview(const sp<IMemory>& mem) {
850    disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
851
852    sp<ICameraClient> c = mRemoteCallback;
853    mLock.unlock();
854    if (c != 0) {
855        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
856    }
857}
858
859// picture callback - raw image ready
860void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
861    disableMsgType(CAMERA_MSG_RAW_IMAGE);
862
863    ssize_t offset;
864    size_t size;
865    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
866
867    sp<ICameraClient> c = mRemoteCallback;
868    mLock.unlock();
869    if (c != 0) {
870        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
871    }
872}
873
874// picture callback - compressed picture ready
875void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
876    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
877
878    sp<ICameraClient> c = mRemoteCallback;
879    mLock.unlock();
880    if (c != 0) {
881        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
882    }
883}
884
885
886void CameraClient::handleGenericNotify(int32_t msgType,
887    int32_t ext1, int32_t ext2) {
888    sp<ICameraClient> c = mRemoteCallback;
889    mLock.unlock();
890    if (c != 0) {
891        c->notifyCallback(msgType, ext1, ext2);
892    }
893}
894
895void CameraClient::handleGenericData(int32_t msgType,
896    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
897    sp<ICameraClient> c = mRemoteCallback;
898    mLock.unlock();
899    if (c != 0) {
900        c->dataCallback(msgType, dataPtr, metadata);
901    }
902}
903
904void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
905    int32_t msgType, const sp<IMemory>& dataPtr) {
906    sp<ICameraClient> c = mRemoteCallback;
907    mLock.unlock();
908    if (c != 0) {
909        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
910    }
911}
912
913void CameraClient::copyFrameAndPostCopiedFrame(
914        int32_t msgType, const sp<ICameraClient>& client,
915        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
916        camera_frame_metadata_t *metadata) {
917    LOG2("copyFrameAndPostCopiedFrame");
918    // It is necessary to copy out of pmem before sending this to
919    // the callback. For efficiency, reuse the same MemoryHeapBase
920    // provided it's big enough. Don't allocate the memory or
921    // perform the copy if there's no callback.
922    // hold the preview lock while we grab a reference to the preview buffer
923    sp<MemoryHeapBase> previewBuffer;
924
925    if (mPreviewBuffer == 0) {
926        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
927    } else if (size > mPreviewBuffer->virtualSize()) {
928        mPreviewBuffer.clear();
929        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
930    }
931    if (mPreviewBuffer == 0) {
932        ALOGE("failed to allocate space for preview buffer");
933        mLock.unlock();
934        return;
935    }
936    previewBuffer = mPreviewBuffer;
937
938    memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
939
940    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
941    if (frame == 0) {
942        ALOGE("failed to allocate space for frame callback");
943        mLock.unlock();
944        return;
945    }
946
947    mLock.unlock();
948    client->dataCallback(msgType, frame, metadata);
949}
950
951int CameraClient::getOrientation(int degrees, bool mirror) {
952    if (!mirror) {
953        if (degrees == 0) return 0;
954        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
955        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
956        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
957    } else {  // Do mirror (horizontal flip)
958        if (degrees == 0) {           // FLIP_H and ROT_0
959            return HAL_TRANSFORM_FLIP_H;
960        } else if (degrees == 90) {   // FLIP_H and ROT_90
961            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
962        } else if (degrees == 180) {  // FLIP_H and ROT_180
963            return HAL_TRANSFORM_FLIP_V;
964        } else if (degrees == 270) {  // FLIP_H and ROT_270
965            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
966        }
967    }
968    ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
969    return -1;
970}
971
972}; // namespace android
973