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