CameraClient.cpp revision 1ce7c34e67c2cf58dd88c31f36f4bd62e375f7f0
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 buffer consumer that the preview will use
312status_t CameraClient::setPreviewTarget(
313        const sp<IGraphicBufferProducer>& bufferProducer) {
314    LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
315            getCallingPid());
316
317    sp<IBinder> binder;
318    sp<ANativeWindow> window;
319    if (bufferProducer != 0) {
320        binder = bufferProducer->asBinder();
321        // Using controlledByApp flag to ensure that the buffer queue remains in
322        // async mode for the old camera API, where many applications depend
323        // on that behavior.
324        window = new Surface(bufferProducer, /*controlledByApp*/ true);
325    }
326    return setPreviewWindow(binder, window);
327}
328
329// set the preview callback flag to affect how the received frames from
330// preview are handled.
331void CameraClient::setPreviewCallbackFlag(int callback_flag) {
332    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
333    Mutex::Autolock lock(mLock);
334    if (checkPidAndHardware() != NO_ERROR) return;
335
336    mPreviewCallbackFlag = callback_flag;
337    if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
338        enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
339    } else {
340        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
341    }
342}
343
344status_t CameraClient::setPreviewCallbackTarget(
345        const sp<IGraphicBufferProducer>& callbackProducer) {
346    (void)callbackProducer;
347    ALOGE("%s: Unimplemented!", __FUNCTION__);
348    return INVALID_OPERATION;
349}
350
351// start preview mode
352status_t CameraClient::startPreview() {
353    LOG1("startPreview (pid %d)", getCallingPid());
354    return startCameraMode(CAMERA_PREVIEW_MODE);
355}
356
357// start recording mode
358status_t CameraClient::startRecording() {
359    LOG1("startRecording (pid %d)", getCallingPid());
360    return startCameraMode(CAMERA_RECORDING_MODE);
361}
362
363// start preview or recording
364status_t CameraClient::startCameraMode(camera_mode mode) {
365    LOG1("startCameraMode(%d)", mode);
366    Mutex::Autolock lock(mLock);
367    status_t result = checkPidAndHardware();
368    if (result != NO_ERROR) return result;
369
370    switch(mode) {
371        case CAMERA_PREVIEW_MODE:
372            if (mSurface == 0 && mPreviewWindow == 0) {
373                LOG1("mSurface is not set yet.");
374                // still able to start preview in this case.
375            }
376            return startPreviewMode();
377        case CAMERA_RECORDING_MODE:
378            if (mSurface == 0 && mPreviewWindow == 0) {
379                ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
380                return INVALID_OPERATION;
381            }
382            return startRecordingMode();
383        default:
384            return UNKNOWN_ERROR;
385    }
386}
387
388status_t CameraClient::startPreviewMode() {
389    LOG1("startPreviewMode");
390    status_t result = NO_ERROR;
391
392    // if preview has been enabled, nothing needs to be done
393    if (mHardware->previewEnabled()) {
394        return NO_ERROR;
395    }
396
397    if (mPreviewWindow != 0) {
398        native_window_set_scaling_mode(mPreviewWindow.get(),
399                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
400        native_window_set_buffers_transform(mPreviewWindow.get(),
401                mOrientation);
402    }
403    mHardware->setPreviewWindow(mPreviewWindow);
404    result = mHardware->startPreview();
405
406    return result;
407}
408
409status_t CameraClient::startRecordingMode() {
410    LOG1("startRecordingMode");
411    status_t result = NO_ERROR;
412
413    // if recording has been enabled, nothing needs to be done
414    if (mHardware->recordingEnabled()) {
415        return NO_ERROR;
416    }
417
418    // if preview has not been started, start preview first
419    if (!mHardware->previewEnabled()) {
420        result = startPreviewMode();
421        if (result != NO_ERROR) {
422            return result;
423        }
424    }
425
426    // start recording mode
427    enableMsgType(CAMERA_MSG_VIDEO_FRAME);
428    mCameraService->playSound(CameraService::SOUND_RECORDING);
429    result = mHardware->startRecording();
430    if (result != NO_ERROR) {
431        ALOGE("mHardware->startRecording() failed with status %d", result);
432    }
433    return result;
434}
435
436// stop preview mode
437void CameraClient::stopPreview() {
438    LOG1("stopPreview (pid %d)", getCallingPid());
439    Mutex::Autolock lock(mLock);
440    if (checkPidAndHardware() != NO_ERROR) return;
441
442
443    disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
444    mHardware->stopPreview();
445
446    mPreviewBuffer.clear();
447}
448
449// stop recording mode
450void CameraClient::stopRecording() {
451    LOG1("stopRecording (pid %d)", getCallingPid());
452    Mutex::Autolock lock(mLock);
453    if (checkPidAndHardware() != NO_ERROR) return;
454
455    disableMsgType(CAMERA_MSG_VIDEO_FRAME);
456    mHardware->stopRecording();
457    mCameraService->playSound(CameraService::SOUND_RECORDING);
458
459    mPreviewBuffer.clear();
460}
461
462// release a recording frame
463void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
464    Mutex::Autolock lock(mLock);
465    if (checkPidAndHardware() != NO_ERROR) return;
466    mHardware->releaseRecordingFrame(mem);
467}
468
469status_t CameraClient::storeMetaDataInBuffers(bool enabled)
470{
471    LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
472    Mutex::Autolock lock(mLock);
473    if (checkPidAndHardware() != NO_ERROR) {
474        return UNKNOWN_ERROR;
475    }
476    return mHardware->storeMetaDataInBuffers(enabled);
477}
478
479bool CameraClient::previewEnabled() {
480    LOG1("previewEnabled (pid %d)", getCallingPid());
481
482    Mutex::Autolock lock(mLock);
483    if (checkPidAndHardware() != NO_ERROR) return false;
484    return mHardware->previewEnabled();
485}
486
487bool CameraClient::recordingEnabled() {
488    LOG1("recordingEnabled (pid %d)", getCallingPid());
489
490    Mutex::Autolock lock(mLock);
491    if (checkPidAndHardware() != NO_ERROR) return false;
492    return mHardware->recordingEnabled();
493}
494
495status_t CameraClient::autoFocus() {
496    LOG1("autoFocus (pid %d)", getCallingPid());
497
498    Mutex::Autolock lock(mLock);
499    status_t result = checkPidAndHardware();
500    if (result != NO_ERROR) return result;
501
502    return mHardware->autoFocus();
503}
504
505status_t CameraClient::cancelAutoFocus() {
506    LOG1("cancelAutoFocus (pid %d)", getCallingPid());
507
508    Mutex::Autolock lock(mLock);
509    status_t result = checkPidAndHardware();
510    if (result != NO_ERROR) return result;
511
512    return mHardware->cancelAutoFocus();
513}
514
515// take a picture - image is returned in callback
516status_t CameraClient::takePicture(int msgType) {
517    LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
518
519    Mutex::Autolock lock(mLock);
520    status_t result = checkPidAndHardware();
521    if (result != NO_ERROR) return result;
522
523    if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
524        (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
525        ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
526                " cannot be both enabled");
527        return BAD_VALUE;
528    }
529
530    // We only accept picture related message types
531    // and ignore other types of messages for takePicture().
532    int picMsgType = msgType
533                        & (CAMERA_MSG_SHUTTER |
534                           CAMERA_MSG_POSTVIEW_FRAME |
535                           CAMERA_MSG_RAW_IMAGE |
536                           CAMERA_MSG_RAW_IMAGE_NOTIFY |
537                           CAMERA_MSG_COMPRESSED_IMAGE);
538
539    enableMsgType(picMsgType);
540
541    return mHardware->takePicture();
542}
543
544// set preview/capture parameters - key/value pairs
545status_t CameraClient::setParameters(const String8& params) {
546    LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
547
548    Mutex::Autolock lock(mLock);
549    status_t result = checkPidAndHardware();
550    if (result != NO_ERROR) return result;
551
552    CameraParameters p(params);
553    return mHardware->setParameters(p);
554}
555
556// get preview/capture parameters - key/value pairs
557String8 CameraClient::getParameters() const {
558    Mutex::Autolock lock(mLock);
559    if (checkPidAndHardware() != NO_ERROR) return String8();
560
561    String8 params(mHardware->getParameters().flatten());
562    LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
563    return params;
564}
565
566// enable shutter sound
567status_t CameraClient::enableShutterSound(bool enable) {
568    LOG1("enableShutterSound (pid %d)", getCallingPid());
569
570    status_t result = checkPidAndHardware();
571    if (result != NO_ERROR) return result;
572
573    if (enable) {
574        mPlayShutterSound = true;
575        return OK;
576    }
577
578    // Disabling shutter sound may not be allowed. In that case only
579    // allow the mediaserver process to disable the sound.
580    char value[PROPERTY_VALUE_MAX];
581    property_get("ro.camera.sound.forced", value, "0");
582    if (strcmp(value, "0") != 0) {
583        // Disabling shutter sound is not allowed. Deny if the current
584        // process is not mediaserver.
585        if (getCallingPid() != getpid()) {
586            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
587            return PERMISSION_DENIED;
588        }
589    }
590
591    mPlayShutterSound = false;
592    return OK;
593}
594
595status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
596    LOG1("sendCommand (pid %d)", getCallingPid());
597    int orientation;
598    Mutex::Autolock lock(mLock);
599    status_t result = checkPidAndHardware();
600    if (result != NO_ERROR) return result;
601
602    if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
603        // Mirror the preview if the camera is front-facing.
604        orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
605        if (orientation == -1) return BAD_VALUE;
606
607        if (mOrientation != orientation) {
608            mOrientation = orientation;
609            if (mPreviewWindow != 0) {
610                native_window_set_buffers_transform(mPreviewWindow.get(),
611                        mOrientation);
612            }
613        }
614        return OK;
615    } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
616        switch (arg1) {
617            case 0:
618                return enableShutterSound(false);
619            case 1:
620                return enableShutterSound(true);
621            default:
622                return BAD_VALUE;
623        }
624        return OK;
625    } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
626        mCameraService->playSound(CameraService::SOUND_RECORDING);
627    } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
628        // Silently ignore this command
629        return INVALID_OPERATION;
630    } else if (cmd == CAMERA_CMD_PING) {
631        // If mHardware is 0, checkPidAndHardware will return error.
632        return OK;
633    }
634
635    return mHardware->sendCommand(cmd, arg1, arg2);
636}
637
638// ----------------------------------------------------------------------------
639
640void CameraClient::enableMsgType(int32_t msgType) {
641    android_atomic_or(msgType, &mMsgEnabled);
642    mHardware->enableMsgType(msgType);
643}
644
645void CameraClient::disableMsgType(int32_t msgType) {
646    android_atomic_and(~msgType, &mMsgEnabled);
647    mHardware->disableMsgType(msgType);
648}
649
650#define CHECK_MESSAGE_INTERVAL 10 // 10ms
651bool CameraClient::lockIfMessageWanted(int32_t msgType) {
652    int sleepCount = 0;
653    while (mMsgEnabled & msgType) {
654        if (mLock.tryLock() == NO_ERROR) {
655            if (sleepCount > 0) {
656                LOG1("lockIfMessageWanted(%d): waited for %d ms",
657                    msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
658            }
659            return true;
660        }
661        if (sleepCount++ == 0) {
662            LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
663        }
664        usleep(CHECK_MESSAGE_INTERVAL * 1000);
665    }
666    ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
667    return false;
668}
669
670// Callback messages can be dispatched to internal handlers or pass to our
671// client's callback functions, depending on the message type.
672//
673// notifyCallback:
674//      CAMERA_MSG_SHUTTER              handleShutter
675//      (others)                        c->notifyCallback
676// dataCallback:
677//      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
678//      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
679//      CAMERA_MSG_RAW_IMAGE            handleRawPicture
680//      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
681//      (others)                        c->dataCallback
682// dataCallbackTimestamp
683//      (others)                        c->dataCallbackTimestamp
684//
685// NOTE: the *Callback functions grab mLock of the client before passing
686// control to handle* functions. So the handle* functions must release the
687// lock before calling the ICameraClient's callbacks, so those callbacks can
688// invoke methods in the Client class again (For example, the preview frame
689// callback may want to releaseRecordingFrame). The handle* functions must
690// release the lock after all accesses to member variables, so it must be
691// handled very carefully.
692
693void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
694        int32_t ext2, void* user) {
695    LOG2("notifyCallback(%d)", msgType);
696
697    Mutex* lock = getClientLockFromCookie(user);
698    if (lock == NULL) return;
699    Mutex::Autolock alock(*lock);
700
701    CameraClient* client =
702            static_cast<CameraClient*>(getClientFromCookie(user));
703    if (client == NULL) return;
704
705    if (!client->lockIfMessageWanted(msgType)) return;
706
707    switch (msgType) {
708        case CAMERA_MSG_SHUTTER:
709            // ext1 is the dimension of the yuv picture.
710            client->handleShutter();
711            break;
712        default:
713            client->handleGenericNotify(msgType, ext1, ext2);
714            break;
715    }
716}
717
718void CameraClient::dataCallback(int32_t msgType,
719        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
720    LOG2("dataCallback(%d)", msgType);
721
722    Mutex* lock = getClientLockFromCookie(user);
723    if (lock == NULL) return;
724    Mutex::Autolock alock(*lock);
725
726    CameraClient* client =
727            static_cast<CameraClient*>(getClientFromCookie(user));
728    if (client == NULL) return;
729
730    if (!client->lockIfMessageWanted(msgType)) return;
731    if (dataPtr == 0 && metadata == NULL) {
732        ALOGE("Null data returned in data callback");
733        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
734        return;
735    }
736
737    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
738        case CAMERA_MSG_PREVIEW_FRAME:
739            client->handlePreviewData(msgType, dataPtr, metadata);
740            break;
741        case CAMERA_MSG_POSTVIEW_FRAME:
742            client->handlePostview(dataPtr);
743            break;
744        case CAMERA_MSG_RAW_IMAGE:
745            client->handleRawPicture(dataPtr);
746            break;
747        case CAMERA_MSG_COMPRESSED_IMAGE:
748            client->handleCompressedPicture(dataPtr);
749            break;
750        default:
751            client->handleGenericData(msgType, dataPtr, metadata);
752            break;
753    }
754}
755
756void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
757        int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
758    LOG2("dataCallbackTimestamp(%d)", msgType);
759
760    Mutex* lock = getClientLockFromCookie(user);
761    if (lock == NULL) return;
762    Mutex::Autolock alock(*lock);
763
764    CameraClient* client =
765            static_cast<CameraClient*>(getClientFromCookie(user));
766    if (client == NULL) return;
767
768    if (!client->lockIfMessageWanted(msgType)) return;
769
770    if (dataPtr == 0) {
771        ALOGE("Null data returned in data with timestamp callback");
772        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
773        return;
774    }
775
776    client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
777}
778
779// snapshot taken callback
780void CameraClient::handleShutter(void) {
781    if (mPlayShutterSound) {
782        mCameraService->playSound(CameraService::SOUND_SHUTTER);
783    }
784
785    sp<ICameraClient> c = mRemoteCallback;
786    if (c != 0) {
787        mLock.unlock();
788        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
789        if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
790    }
791    disableMsgType(CAMERA_MSG_SHUTTER);
792
793    mLock.unlock();
794}
795
796// preview callback - frame buffer update
797void CameraClient::handlePreviewData(int32_t msgType,
798                                              const sp<IMemory>& mem,
799                                              camera_frame_metadata_t *metadata) {
800    ssize_t offset;
801    size_t size;
802    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
803
804    // local copy of the callback flags
805    int flags = mPreviewCallbackFlag;
806
807    // is callback enabled?
808    if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
809        // If the enable bit is off, the copy-out and one-shot bits are ignored
810        LOG2("frame callback is disabled");
811        mLock.unlock();
812        return;
813    }
814
815    // hold a strong pointer to the client
816    sp<ICameraClient> c = mRemoteCallback;
817
818    // clear callback flags if no client or one-shot mode
819    if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
820        LOG2("Disable preview callback");
821        mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
822                                  CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
823                                  CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
824        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
825    }
826
827    if (c != 0) {
828        // Is the received frame copied out or not?
829        if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
830            LOG2("frame is copied");
831            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
832        } else {
833            LOG2("frame is forwarded");
834            mLock.unlock();
835            c->dataCallback(msgType, mem, metadata);
836        }
837    } else {
838        mLock.unlock();
839    }
840}
841
842// picture callback - postview image ready
843void CameraClient::handlePostview(const sp<IMemory>& mem) {
844    disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
845
846    sp<ICameraClient> c = mRemoteCallback;
847    mLock.unlock();
848    if (c != 0) {
849        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
850    }
851}
852
853// picture callback - raw image ready
854void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
855    disableMsgType(CAMERA_MSG_RAW_IMAGE);
856
857    ssize_t offset;
858    size_t size;
859    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
860
861    sp<ICameraClient> c = mRemoteCallback;
862    mLock.unlock();
863    if (c != 0) {
864        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
865    }
866}
867
868// picture callback - compressed picture ready
869void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
870    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
871
872    sp<ICameraClient> c = mRemoteCallback;
873    mLock.unlock();
874    if (c != 0) {
875        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
876    }
877}
878
879
880void CameraClient::handleGenericNotify(int32_t msgType,
881    int32_t ext1, int32_t ext2) {
882    sp<ICameraClient> c = mRemoteCallback;
883    mLock.unlock();
884    if (c != 0) {
885        c->notifyCallback(msgType, ext1, ext2);
886    }
887}
888
889void CameraClient::handleGenericData(int32_t msgType,
890    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
891    sp<ICameraClient> c = mRemoteCallback;
892    mLock.unlock();
893    if (c != 0) {
894        c->dataCallback(msgType, dataPtr, metadata);
895    }
896}
897
898void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
899    int32_t msgType, const sp<IMemory>& dataPtr) {
900    sp<ICameraClient> c = mRemoteCallback;
901    mLock.unlock();
902    if (c != 0) {
903        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
904    }
905}
906
907void CameraClient::copyFrameAndPostCopiedFrame(
908        int32_t msgType, const sp<ICameraClient>& client,
909        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
910        camera_frame_metadata_t *metadata) {
911    LOG2("copyFrameAndPostCopiedFrame");
912    // It is necessary to copy out of pmem before sending this to
913    // the callback. For efficiency, reuse the same MemoryHeapBase
914    // provided it's big enough. Don't allocate the memory or
915    // perform the copy if there's no callback.
916    // hold the preview lock while we grab a reference to the preview buffer
917    sp<MemoryHeapBase> previewBuffer;
918
919    if (mPreviewBuffer == 0) {
920        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
921    } else if (size > mPreviewBuffer->virtualSize()) {
922        mPreviewBuffer.clear();
923        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
924    }
925    if (mPreviewBuffer == 0) {
926        ALOGE("failed to allocate space for preview buffer");
927        mLock.unlock();
928        return;
929    }
930    previewBuffer = mPreviewBuffer;
931
932    memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
933
934    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
935    if (frame == 0) {
936        ALOGE("failed to allocate space for frame callback");
937        mLock.unlock();
938        return;
939    }
940
941    mLock.unlock();
942    client->dataCallback(msgType, frame, metadata);
943}
944
945int CameraClient::getOrientation(int degrees, bool mirror) {
946    if (!mirror) {
947        if (degrees == 0) return 0;
948        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
949        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
950        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
951    } else {  // Do mirror (horizontal flip)
952        if (degrees == 0) {           // FLIP_H and ROT_0
953            return HAL_TRANSFORM_FLIP_H;
954        } else if (degrees == 90) {   // FLIP_H and ROT_90
955            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
956        } else if (degrees == 180) {  // FLIP_H and ROT_180
957            return HAL_TRANSFORM_FLIP_V;
958        } else if (degrees == 270) {  // FLIP_H and ROT_270
959            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
960        }
961    }
962    ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
963    return -1;
964}
965
966}; // namespace android
967