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