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