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