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    disconnect();
106    LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
107}
108
109status_t CameraClient::dump(int fd, const Vector<String16>& args) {
110    const size_t SIZE = 256;
111    char buffer[SIZE];
112
113    size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) PID: %d\n",
114            mCameraId,
115            getCameraClient()->asBinder().get(),
116            mClientPid);
117    len = (len > SIZE - 1) ? SIZE - 1 : len;
118    write(fd, buffer, len);
119    return mHardware->dump(fd, args);
120}
121
122// ----------------------------------------------------------------------------
123
124status_t CameraClient::checkPid() const {
125    int callingPid = getCallingPid();
126    if (callingPid == mClientPid) return NO_ERROR;
127
128    ALOGW("attempt to use a locked camera from a different process"
129         " (old pid %d, new pid %d)", mClientPid, callingPid);
130    return EBUSY;
131}
132
133status_t CameraClient::checkPidAndHardware() const {
134    status_t result = checkPid();
135    if (result != NO_ERROR) return result;
136    if (mHardware == 0) {
137        ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
138        return INVALID_OPERATION;
139    }
140    return NO_ERROR;
141}
142
143status_t CameraClient::lock() {
144    int callingPid = getCallingPid();
145    LOG1("lock (pid %d)", callingPid);
146    Mutex::Autolock lock(mLock);
147
148    // lock camera to this client if the the camera is unlocked
149    if (mClientPid == 0) {
150        mClientPid = callingPid;
151        return NO_ERROR;
152    }
153
154    // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
155    return checkPid();
156}
157
158status_t CameraClient::unlock() {
159    int callingPid = getCallingPid();
160    LOG1("unlock (pid %d)", callingPid);
161    Mutex::Autolock lock(mLock);
162
163    // allow anyone to use camera (after they lock the camera)
164    status_t result = checkPid();
165    if (result == NO_ERROR) {
166        if (mHardware->recordingEnabled()) {
167            ALOGE("Not allowed to unlock camera during recording.");
168            return INVALID_OPERATION;
169        }
170        mClientPid = 0;
171        LOG1("clear mCameraClient (pid %d)", callingPid);
172        // we need to remove the reference to ICameraClient so that when the app
173        // goes away, the reference count goes to 0.
174        mCameraClient.clear();
175    }
176    return result;
177}
178
179// connect a new client to the camera
180status_t CameraClient::connect(const sp<ICameraClient>& client) {
181    int callingPid = getCallingPid();
182    LOG1("connect E (pid %d)", callingPid);
183    Mutex::Autolock lock(mLock);
184
185    if (mClientPid != 0 && checkPid() != NO_ERROR) {
186        ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
187                mClientPid, callingPid);
188        return EBUSY;
189    }
190
191    if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) {
192        LOG1("Connect to the same client");
193        return NO_ERROR;
194    }
195
196    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
197    mClientPid = callingPid;
198    mCameraClient = client;
199
200    LOG1("connect X (pid %d)", callingPid);
201    return NO_ERROR;
202}
203
204static void disconnectWindow(const sp<ANativeWindow>& window) {
205    if (window != 0) {
206        status_t result = native_window_api_disconnect(window.get(),
207                NATIVE_WINDOW_API_CAMERA);
208        if (result != NO_ERROR) {
209            ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
210                    result);
211        }
212    }
213}
214
215void CameraClient::disconnect() {
216    int callingPid = getCallingPid();
217    LOG1("disconnect E (pid %d)", callingPid);
218    Mutex::Autolock lock(mLock);
219
220    // Allow both client and the media server to disconnect at all times
221    if (callingPid != mClientPid && callingPid != mServicePid) {
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    disableMsgType(CAMERA_MSG_VIDEO_FRAME);
449    mHardware->stopRecording();
450    mCameraService->playSound(CameraService::SOUND_RECORDING);
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                return enableShutterSound(false);
612            case 1:
613                return enableShutterSound(true);
614            default:
615                return BAD_VALUE;
616        }
617        return OK;
618    } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
619        mCameraService->playSound(CameraService::SOUND_RECORDING);
620    } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
621        // Silently ignore this command
622        return INVALID_OPERATION;
623    } else if (cmd == CAMERA_CMD_PING) {
624        // If mHardware is 0, checkPidAndHardware will return error.
625        return OK;
626    }
627
628    return mHardware->sendCommand(cmd, arg1, arg2);
629}
630
631// ----------------------------------------------------------------------------
632
633void CameraClient::enableMsgType(int32_t msgType) {
634    android_atomic_or(msgType, &mMsgEnabled);
635    mHardware->enableMsgType(msgType);
636}
637
638void CameraClient::disableMsgType(int32_t msgType) {
639    android_atomic_and(~msgType, &mMsgEnabled);
640    mHardware->disableMsgType(msgType);
641}
642
643#define CHECK_MESSAGE_INTERVAL 10 // 10ms
644bool CameraClient::lockIfMessageWanted(int32_t msgType) {
645    int sleepCount = 0;
646    while (mMsgEnabled & msgType) {
647        if (mLock.tryLock() == NO_ERROR) {
648            if (sleepCount > 0) {
649                LOG1("lockIfMessageWanted(%d): waited for %d ms",
650                    msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
651            }
652            return true;
653        }
654        if (sleepCount++ == 0) {
655            LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
656        }
657        usleep(CHECK_MESSAGE_INTERVAL * 1000);
658    }
659    ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
660    return false;
661}
662
663// Callback messages can be dispatched to internal handlers or pass to our
664// client's callback functions, depending on the message type.
665//
666// notifyCallback:
667//      CAMERA_MSG_SHUTTER              handleShutter
668//      (others)                        c->notifyCallback
669// dataCallback:
670//      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
671//      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
672//      CAMERA_MSG_RAW_IMAGE            handleRawPicture
673//      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
674//      (others)                        c->dataCallback
675// dataCallbackTimestamp
676//      (others)                        c->dataCallbackTimestamp
677//
678// NOTE: the *Callback functions grab mLock of the client before passing
679// control to handle* functions. So the handle* functions must release the
680// lock before calling the ICameraClient's callbacks, so those callbacks can
681// invoke methods in the Client class again (For example, the preview frame
682// callback may want to releaseRecordingFrame). The handle* functions must
683// release the lock after all accesses to member variables, so it must be
684// handled very carefully.
685
686void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
687        int32_t ext2, void* user) {
688    LOG2("notifyCallback(%d)", msgType);
689
690    Mutex* lock = getClientLockFromCookie(user);
691    if (lock == NULL) return;
692    Mutex::Autolock alock(*lock);
693
694    CameraClient* client =
695            static_cast<CameraClient*>(getClientFromCookie(user));
696    if (client == NULL) return;
697
698    if (!client->lockIfMessageWanted(msgType)) return;
699
700    switch (msgType) {
701        case CAMERA_MSG_SHUTTER:
702            // ext1 is the dimension of the yuv picture.
703            client->handleShutter();
704            break;
705        default:
706            client->handleGenericNotify(msgType, ext1, ext2);
707            break;
708    }
709}
710
711void CameraClient::dataCallback(int32_t msgType,
712        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
713    LOG2("dataCallback(%d)", msgType);
714
715    Mutex* lock = getClientLockFromCookie(user);
716    if (lock == NULL) return;
717    Mutex::Autolock alock(*lock);
718
719    CameraClient* client =
720            static_cast<CameraClient*>(getClientFromCookie(user));
721    if (client == NULL) return;
722
723    if (!client->lockIfMessageWanted(msgType)) return;
724    if (dataPtr == 0 && metadata == NULL) {
725        ALOGE("Null data returned in data callback");
726        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
727        return;
728    }
729
730    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
731        case CAMERA_MSG_PREVIEW_FRAME:
732            client->handlePreviewData(msgType, dataPtr, metadata);
733            break;
734        case CAMERA_MSG_POSTVIEW_FRAME:
735            client->handlePostview(dataPtr);
736            break;
737        case CAMERA_MSG_RAW_IMAGE:
738            client->handleRawPicture(dataPtr);
739            break;
740        case CAMERA_MSG_COMPRESSED_IMAGE:
741            client->handleCompressedPicture(dataPtr);
742            break;
743        default:
744            client->handleGenericData(msgType, dataPtr, metadata);
745            break;
746    }
747}
748
749void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
750        int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
751    LOG2("dataCallbackTimestamp(%d)", msgType);
752
753    Mutex* lock = getClientLockFromCookie(user);
754    if (lock == NULL) return;
755    Mutex::Autolock alock(*lock);
756
757    CameraClient* client =
758            static_cast<CameraClient*>(getClientFromCookie(user));
759    if (client == NULL) return;
760
761    if (!client->lockIfMessageWanted(msgType)) return;
762
763    if (dataPtr == 0) {
764        ALOGE("Null data returned in data with timestamp callback");
765        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
766        return;
767    }
768
769    client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
770}
771
772// snapshot taken callback
773void CameraClient::handleShutter(void) {
774    if (mPlayShutterSound) {
775        mCameraService->playSound(CameraService::SOUND_SHUTTER);
776    }
777
778    sp<ICameraClient> c = mCameraClient;
779    if (c != 0) {
780        mLock.unlock();
781        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
782        if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
783    }
784    disableMsgType(CAMERA_MSG_SHUTTER);
785
786    mLock.unlock();
787}
788
789// preview callback - frame buffer update
790void CameraClient::handlePreviewData(int32_t msgType,
791                                              const sp<IMemory>& mem,
792                                              camera_frame_metadata_t *metadata) {
793    ssize_t offset;
794    size_t size;
795    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
796
797    // local copy of the callback flags
798    int flags = mPreviewCallbackFlag;
799
800    // is callback enabled?
801    if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
802        // If the enable bit is off, the copy-out and one-shot bits are ignored
803        LOG2("frame callback is disabled");
804        mLock.unlock();
805        return;
806    }
807
808    // hold a strong pointer to the client
809    sp<ICameraClient> c = mCameraClient;
810
811    // clear callback flags if no client or one-shot mode
812    if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
813        LOG2("Disable preview callback");
814        mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
815                                  CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
816                                  CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
817        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
818    }
819
820    if (c != 0) {
821        // Is the received frame copied out or not?
822        if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
823            LOG2("frame is copied");
824            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
825        } else {
826            LOG2("frame is forwarded");
827            mLock.unlock();
828            c->dataCallback(msgType, mem, metadata);
829        }
830    } else {
831        mLock.unlock();
832    }
833}
834
835// picture callback - postview image ready
836void CameraClient::handlePostview(const sp<IMemory>& mem) {
837    disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
838
839    sp<ICameraClient> c = mCameraClient;
840    mLock.unlock();
841    if (c != 0) {
842        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
843    }
844}
845
846// picture callback - raw image ready
847void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
848    disableMsgType(CAMERA_MSG_RAW_IMAGE);
849
850    ssize_t offset;
851    size_t size;
852    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
853
854    sp<ICameraClient> c = mCameraClient;
855    mLock.unlock();
856    if (c != 0) {
857        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
858    }
859}
860
861// picture callback - compressed picture ready
862void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
863    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
864
865    sp<ICameraClient> c = mCameraClient;
866    mLock.unlock();
867    if (c != 0) {
868        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
869    }
870}
871
872
873void CameraClient::handleGenericNotify(int32_t msgType,
874    int32_t ext1, int32_t ext2) {
875    sp<ICameraClient> c = mCameraClient;
876    mLock.unlock();
877    if (c != 0) {
878        c->notifyCallback(msgType, ext1, ext2);
879    }
880}
881
882void CameraClient::handleGenericData(int32_t msgType,
883    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
884    sp<ICameraClient> c = mCameraClient;
885    mLock.unlock();
886    if (c != 0) {
887        c->dataCallback(msgType, dataPtr, metadata);
888    }
889}
890
891void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
892    int32_t msgType, const sp<IMemory>& dataPtr) {
893    sp<ICameraClient> c = mCameraClient;
894    mLock.unlock();
895    if (c != 0) {
896        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
897    }
898}
899
900void CameraClient::copyFrameAndPostCopiedFrame(
901        int32_t msgType, const sp<ICameraClient>& client,
902        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
903        camera_frame_metadata_t *metadata) {
904    LOG2("copyFrameAndPostCopiedFrame");
905    // It is necessary to copy out of pmem before sending this to
906    // the callback. For efficiency, reuse the same MemoryHeapBase
907    // provided it's big enough. Don't allocate the memory or
908    // perform the copy if there's no callback.
909    // hold the preview lock while we grab a reference to the preview buffer
910    sp<MemoryHeapBase> previewBuffer;
911
912    if (mPreviewBuffer == 0) {
913        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
914    } else if (size > mPreviewBuffer->virtualSize()) {
915        mPreviewBuffer.clear();
916        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
917    }
918    if (mPreviewBuffer == 0) {
919        ALOGE("failed to allocate space for preview buffer");
920        mLock.unlock();
921        return;
922    }
923    previewBuffer = mPreviewBuffer;
924
925    memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
926
927    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
928    if (frame == 0) {
929        ALOGE("failed to allocate space for frame callback");
930        mLock.unlock();
931        return;
932    }
933
934    mLock.unlock();
935    client->dataCallback(msgType, frame, metadata);
936}
937
938int CameraClient::getOrientation(int degrees, bool mirror) {
939    if (!mirror) {
940        if (degrees == 0) return 0;
941        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
942        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
943        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
944    } else {  // Do mirror (horizontal flip)
945        if (degrees == 0) {           // FLIP_H and ROT_0
946            return HAL_TRANSFORM_FLIP_H;
947        } else if (degrees == 90) {   // FLIP_H and ROT_90
948            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
949        } else if (degrees == 180) {  // FLIP_H and ROT_180
950            return HAL_TRANSFORM_FLIP_V;
951        } else if (degrees == 270) {  // FLIP_H and ROT_270
952            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
953        }
954    }
955    ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
956    return -1;
957}
958
959}; // namespace android
960