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