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