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