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