blob: 4192cac702c1c8f8cae4ff34f961475e0387e7a8 [file] [log] [blame]
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001/*
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
Mathias Agopian05d19b02017-02-28 16:28:19 -080020#include <cutils/atomic.h>
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070021#include <cutils/properties.h>
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070022#include <gui/Surface.h>
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -070023#include <media/hardware/HardwareAPI.h>
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070024
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070025#include "api1/CameraClient.h"
26#include "device1/CameraHardwareInterface.h"
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070027#include "CameraService.h"
28
29namespace android {
30
31#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
32#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
33
34static int getCallingPid() {
35 return IPCThreadState::self()->getCallingPid();
36}
37
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070038CameraClient::CameraClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080039 const sp<hardware::ICameraClient>& cameraClient,
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080040 const String16& clientPackageName,
41 int cameraId, int cameraFacing,
42 int clientPid, int clientUid,
Igor Murashkina858ea02014-08-19 14:53:08 -070043 int servicePid, bool legacyMode):
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080044 Client(cameraService, cameraClient, clientPackageName,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080045 String8::format("%d", cameraId), cameraFacing, clientPid,
46 clientUid, servicePid)
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070047{
48 int callingPid = getCallingPid();
49 LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
50
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070051 mHardware = NULL;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070052 mMsgEnabled = 0;
53 mSurface = 0;
54 mPreviewWindow = 0;
55 mDestructionStarted = false;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070056
57 // Callback is disabled by default
58 mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
59 mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
Igor Murashkina858ea02014-08-19 14:53:08 -070060 mLegacyMode = legacyMode;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -070061 mPlayShutterSound = true;
62 LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
63}
64
Emilian Peevbd8c5032018-02-14 23:05:40 +000065status_t CameraClient::initialize(sp<CameraProviderManager> manager,
66 const String8& /*monitorTags*/) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067 int callingPid = getCallingPid();
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080068 status_t res;
69
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070070 LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
71
Eino-Ville Talvalaceb388d2013-02-19 10:40:14 -080072 // Verify ops permissions
73 res = startCameraOps();
74 if (res != OK) {
75 return res;
76 }
77
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070078 char camera_device_name[10];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070079 snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
80
81 mHardware = new CameraHardwareInterface(camera_device_name);
Emilian Peevf53f66e2017-04-11 14:29:43 +010082 res = mHardware->initialize(manager);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070083 if (res != OK) {
84 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
85 __FUNCTION__, mCameraId, strerror(-res), res);
Igor Murashkin44f120f2012-10-09 14:45:37 -070086 mHardware.clear();
Zhijun Heb10cdad2014-06-16 16:38:35 -070087 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070088 }
89
90 mHardware->setCallbacks(notifyCallback,
91 dataCallback,
92 dataCallbackTimestamp,
Yin-Chia Yehb5df5472017-03-20 19:32:19 -070093 handleCallbackTimestampBatch,
Kévin PETIT377b2ec2014-02-03 12:35:36 +000094 (void *)(uintptr_t)mCameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070095
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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700105// tear down the client
106CameraClient::~CameraClient() {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700107 mDestructionStarted = true;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700108 int callingPid = getCallingPid();
109 LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
110
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700111 disconnect();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700112 LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
113}
114
115status_t CameraClient::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvalac4003962016-01-13 10:07:04 -0800116 return BasicClient::dump(fd, args);
117}
118
119status_t CameraClient::dumpClient(int fd, const Vector<String16>& args) {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700120 const size_t SIZE = 256;
121 char buffer[SIZE];
122
Ruben Brunkcc776712015-02-17 20:18:47 -0800123 size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) with UID %d\n",
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700124 mCameraId,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -0800125 (getRemoteCallback() != NULL ?
Marco Nelissen06b46062014-11-14 07:58:25 -0800126 IInterface::asBinder(getRemoteCallback()).get() : NULL),
Ruben Brunkcc776712015-02-17 20:18:47 -0800127 mClientUid);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700128 len = (len > SIZE - 1) ? SIZE - 1 : len;
129 write(fd, buffer, len);
Igor Murashkinfcf5fea2014-09-11 14:43:24 -0700130
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
Yin-Chia Yeh9cf785b2017-12-01 13:37:30 -0800140 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;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700146}
147
148// ----------------------------------------------------------------------------
149
150status_t CameraClient::checkPid() const {
151 int callingPid = getCallingPid();
Eino-Ville Talvalac0379202012-10-09 22:16:58 -0700152 if (callingPid == mClientPid) return NO_ERROR;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700153
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
159status_t CameraClient::checkPidAndHardware() const {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700160 if (mHardware == 0) {
161 ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
162 return INVALID_OPERATION;
163 }
Eino-Ville Talvala6192b892016-04-04 12:31:18 -0700164 status_t result = checkPid();
165 if (result != NO_ERROR) return result;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700166 return NO_ERROR;
167}
168
169status_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
184status_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;
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800197 LOG1("clear mRemoteCallback (pid %d)", callingPid);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700198 // we need to remove the reference to ICameraClient so that when the app
199 // goes away, the reference count goes to 0.
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800200 mRemoteCallback.clear();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700201 }
202 return result;
203}
204
205// connect a new client to the camera
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800206status_t CameraClient::connect(const sp<hardware::ICameraClient>& client) {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700207 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
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800217 if (mRemoteCallback != 0 &&
Marco Nelissen06b46062014-11-14 07:58:25 -0800218 (IInterface::asBinder(client) == IInterface::asBinder(mRemoteCallback))) {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700219 LOG1("Connect to the same client");
220 return NO_ERROR;
221 }
222
223 mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
224 mClientPid = callingPid;
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800225 mRemoteCallback = client;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700226
227 LOG1("connect X (pid %d)", callingPid);
228 return NO_ERROR;
229}
230
231static 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
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800242binder::Status CameraClient::disconnect() {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700243 int callingPid = getCallingPid();
244 LOG1("disconnect E (pid %d)", callingPid);
245 Mutex::Autolock lock(mLock);
246
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800247 binder::Status res = binder::Status::ok();
Chien-Yu Chen98a668f2015-12-18 14:10:33 -0800248 // Allow both client and the cameraserver to disconnect at all times
Eino-Ville Talvalac0379202012-10-09 22:16:58 -0700249 if (callingPid != mClientPid && callingPid != mServicePid) {
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700250 ALOGW("different client - don't disconnect");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800251 return res;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700252 }
253
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700254 // Make sure disconnect() is done once and once only, whether it is called
255 // from the user directly, or called by the destructor.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800256 if (mHardware == 0) return res;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700257
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();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800264 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700265 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
266 mCameraIdStr, mCameraFacing, mClientPackageName);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700267 mHardware->cancelPicture();
268 // Release the hardware resources.
269 mHardware->release();
270
271 // Release the held ANativeWindow resources.
272 if (mPreviewWindow != 0) {
273 disconnectWindow(mPreviewWindow);
274 mPreviewWindow = 0;
275 mHardware->setPreviewWindow(mPreviewWindow);
276 }
277 mHardware.clear();
278
279 CameraService::Client::disconnect();
280
281 LOG1("disconnect X (pid %d)", callingPid);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800282
283 return res;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700284}
285
286// ----------------------------------------------------------------------------
287
288status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder,
289 const sp<ANativeWindow>& window) {
290 Mutex::Autolock lock(mLock);
291 status_t result = checkPidAndHardware();
292 if (result != NO_ERROR) return result;
293
294 // return if no change in surface.
295 if (binder == mSurface) {
296 return NO_ERROR;
297 }
298
299 if (window != 0) {
300 result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
301 if (result != NO_ERROR) {
302 ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
303 result);
304 return result;
305 }
306 }
307
308 // If preview has been already started, register preview buffers now.
309 if (mHardware->previewEnabled()) {
310 if (window != 0) {
Eino-Ville Talvalaf7351172016-02-09 12:13:57 -0800311 mHardware->setPreviewScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
312 mHardware->setPreviewTransform(mOrientation);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700313 result = mHardware->setPreviewWindow(window);
314 }
315 }
316
317 if (result == NO_ERROR) {
318 // Everything has succeeded. Disconnect the old window and remember the
319 // new window.
320 disconnectWindow(mPreviewWindow);
321 mSurface = binder;
322 mPreviewWindow = window;
323 } else {
324 // Something went wrong after we connected to the new window, so
325 // disconnect here.
326 disconnectWindow(window);
327 }
328
329 return result;
330}
331
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700332// set the buffer consumer that the preview will use
333status_t CameraClient::setPreviewTarget(
Andy McFadden8ba01022012-12-18 09:46:54 -0800334 const sp<IGraphicBufferProducer>& bufferProducer) {
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700335 LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700336 getCallingPid());
337
338 sp<IBinder> binder;
339 sp<ANativeWindow> window;
Andy McFadden8ba01022012-12-18 09:46:54 -0800340 if (bufferProducer != 0) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800341 binder = IInterface::asBinder(bufferProducer);
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700342 // Using controlledByApp flag to ensure that the buffer queue remains in
343 // async mode for the old camera API, where many applications depend
344 // on that behavior.
345 window = new Surface(bufferProducer, /*controlledByApp*/ true);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700346 }
347 return setPreviewWindow(binder, window);
348}
349
350// set the preview callback flag to affect how the received frames from
351// preview are handled.
352void CameraClient::setPreviewCallbackFlag(int callback_flag) {
353 LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
354 Mutex::Autolock lock(mLock);
355 if (checkPidAndHardware() != NO_ERROR) return;
356
357 mPreviewCallbackFlag = callback_flag;
358 if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
359 enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
360 } else {
361 disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
362 }
363}
364
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700365status_t CameraClient::setPreviewCallbackTarget(
366 const sp<IGraphicBufferProducer>& callbackProducer) {
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700367 (void)callbackProducer;
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700368 ALOGE("%s: Unimplemented!", __FUNCTION__);
369 return INVALID_OPERATION;
370}
371
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700372// start preview mode
373status_t CameraClient::startPreview() {
374 LOG1("startPreview (pid %d)", getCallingPid());
375 return startCameraMode(CAMERA_PREVIEW_MODE);
376}
377
378// start recording mode
379status_t CameraClient::startRecording() {
380 LOG1("startRecording (pid %d)", getCallingPid());
381 return startCameraMode(CAMERA_RECORDING_MODE);
382}
383
384// start preview or recording
385status_t CameraClient::startCameraMode(camera_mode mode) {
386 LOG1("startCameraMode(%d)", mode);
387 Mutex::Autolock lock(mLock);
388 status_t result = checkPidAndHardware();
389 if (result != NO_ERROR) return result;
390
391 switch(mode) {
392 case CAMERA_PREVIEW_MODE:
393 if (mSurface == 0 && mPreviewWindow == 0) {
394 LOG1("mSurface is not set yet.");
395 // still able to start preview in this case.
396 }
397 return startPreviewMode();
398 case CAMERA_RECORDING_MODE:
399 if (mSurface == 0 && mPreviewWindow == 0) {
400 ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
401 return INVALID_OPERATION;
402 }
403 return startRecordingMode();
404 default:
405 return UNKNOWN_ERROR;
406 }
407}
408
409status_t CameraClient::startPreviewMode() {
410 LOG1("startPreviewMode");
411 status_t result = NO_ERROR;
412
413 // if preview has been enabled, nothing needs to be done
414 if (mHardware->previewEnabled()) {
415 return NO_ERROR;
416 }
417
418 if (mPreviewWindow != 0) {
Eino-Ville Talvalaf7351172016-02-09 12:13:57 -0800419 mHardware->setPreviewScalingMode(
420 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
421 mHardware->setPreviewTransform(mOrientation);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700422 }
423 mHardware->setPreviewWindow(mPreviewWindow);
424 result = mHardware->startPreview();
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700425 if (result == NO_ERROR) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800426 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700427 hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
428 mCameraIdStr, mCameraFacing, mClientPackageName);
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700429 }
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700430 return result;
431}
432
433status_t CameraClient::startRecordingMode() {
434 LOG1("startRecordingMode");
435 status_t result = NO_ERROR;
436
437 // if recording has been enabled, nothing needs to be done
438 if (mHardware->recordingEnabled()) {
439 return NO_ERROR;
440 }
441
442 // if preview has not been started, start preview first
443 if (!mHardware->previewEnabled()) {
444 result = startPreviewMode();
445 if (result != NO_ERROR) {
446 return result;
447 }
448 }
449
450 // start recording mode
451 enableMsgType(CAMERA_MSG_VIDEO_FRAME);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800452 sCameraService->playSound(CameraService::SOUND_RECORDING_START);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700453 result = mHardware->startRecording();
454 if (result != NO_ERROR) {
455 ALOGE("mHardware->startRecording() failed with status %d", result);
456 }
457 return result;
458}
459
460// stop preview mode
461void CameraClient::stopPreview() {
462 LOG1("stopPreview (pid %d)", getCallingPid());
463 Mutex::Autolock lock(mLock);
464 if (checkPidAndHardware() != NO_ERROR) return;
465
466
467 disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
468 mHardware->stopPreview();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800469 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700470 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
471 mCameraIdStr, mCameraFacing, mClientPackageName);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700472 mPreviewBuffer.clear();
473}
474
475// stop recording mode
476void CameraClient::stopRecording() {
477 LOG1("stopRecording (pid %d)", getCallingPid());
Emilian Peev698f0a72017-04-05 11:20:09 +0100478 {
479 Mutex::Autolock lock(mLock);
480 if (checkPidAndHardware() != NO_ERROR) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700481
Emilian Peev698f0a72017-04-05 11:20:09 +0100482 disableMsgType(CAMERA_MSG_VIDEO_FRAME);
483 mHardware->stopRecording();
484 sCameraService->playSound(CameraService::SOUND_RECORDING_STOP);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700485
Emilian Peev698f0a72017-04-05 11:20:09 +0100486 mPreviewBuffer.clear();
487 }
488
489 {
490 Mutex::Autolock l(mAvailableCallbackBuffersLock);
491 if (!mAvailableCallbackBuffers.empty()) {
492 mAvailableCallbackBuffers.clear();
493 }
494 }
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700495}
496
497// release a recording frame
498void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
499 Mutex::Autolock lock(mLock);
500 if (checkPidAndHardware() != NO_ERROR) return;
Chien-Yu Chen42f27072016-01-11 17:39:17 -0800501 if (mem == nullptr) {
502 android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26164272",
503 IPCThreadState::self()->getCallingUid(), nullptr, 0);
504 return;
505 }
506
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700507 mHardware->releaseRecordingFrame(mem);
508}
509
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700510void CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
511 if (handle == nullptr) return;
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800512 Mutex::Autolock lock(mLock);
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700513 sp<IMemory> dataPtr;
514 {
515 Mutex::Autolock l(mAvailableCallbackBuffersLock);
516 if (!mAvailableCallbackBuffers.empty()) {
517 dataPtr = mAvailableCallbackBuffers.back();
518 mAvailableCallbackBuffers.pop_back();
519 }
520 }
521
522 if (dataPtr == nullptr) {
523 ALOGE("%s: %d: No callback buffer available. Dropping a native handle.", __FUNCTION__,
524 __LINE__);
525 native_handle_close(handle);
526 native_handle_delete(handle);
527 return;
528 } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
529 ALOGE("%s: %d: Callback buffer size doesn't match VideoNativeHandleMetadata", __FUNCTION__,
530 __LINE__);
531 native_handle_close(handle);
532 native_handle_delete(handle);
533 return;
534 }
535
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800536 if (mHardware != nullptr) {
537 VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
538 metadata->eType = kMetadataBufferTypeNativeHandleSource;
539 metadata->pHandle = handle;
540 mHardware->releaseRecordingFrame(dataPtr);
541 }
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700542}
543
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700544void CameraClient::releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800545 Mutex::Autolock lock(mLock);
546 bool disconnected = (mHardware == nullptr);
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700547 size_t n = handles.size();
548 std::vector<sp<IMemory>> frames;
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800549 if (!disconnected) {
550 frames.reserve(n);
551 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700552 bool error = false;
553 for (auto& handle : handles) {
554 sp<IMemory> dataPtr;
555 {
556 Mutex::Autolock l(mAvailableCallbackBuffersLock);
557 if (!mAvailableCallbackBuffers.empty()) {
558 dataPtr = mAvailableCallbackBuffers.back();
559 mAvailableCallbackBuffers.pop_back();
560 }
561 }
562
563 if (dataPtr == nullptr) {
564 ALOGE("%s: %d: No callback buffer available. Dropping frames.", __FUNCTION__,
565 __LINE__);
566 error = true;
567 break;
568 } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
569 ALOGE("%s: %d: Callback buffer must be VideoNativeHandleMetadata", __FUNCTION__,
570 __LINE__);
571 error = true;
572 break;
573 }
574
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800575 if (!disconnected) {
576 VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
577 metadata->eType = kMetadataBufferTypeNativeHandleSource;
578 metadata->pHandle = handle;
579 frames.push_back(dataPtr);
580 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700581 }
582
583 if (error) {
584 for (auto& handle : handles) {
585 native_handle_close(handle);
586 native_handle_delete(handle);
587 }
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800588 } else if (!disconnected) {
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700589 mHardware->releaseRecordingFrameBatch(frames);
590 }
591 return;
592}
593
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800594status_t CameraClient::setVideoBufferMode(int32_t videoBufferMode) {
595 LOG1("setVideoBufferMode: %d", videoBufferMode);
596 bool enableMetadataInBuffers = false;
597
598 if (videoBufferMode == VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA) {
599 enableMetadataInBuffers = true;
600 } else if (videoBufferMode != VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) {
601 ALOGE("%s: %d: videoBufferMode %d is not supported.", __FUNCTION__, __LINE__,
602 videoBufferMode);
603 return BAD_VALUE;
604 }
605
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700606 Mutex::Autolock lock(mLock);
607 if (checkPidAndHardware() != NO_ERROR) {
608 return UNKNOWN_ERROR;
609 }
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800610
611 return mHardware->storeMetaDataInBuffers(enableMetadataInBuffers);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700612}
613
614bool CameraClient::previewEnabled() {
615 LOG1("previewEnabled (pid %d)", getCallingPid());
616
617 Mutex::Autolock lock(mLock);
618 if (checkPidAndHardware() != NO_ERROR) return false;
619 return mHardware->previewEnabled();
620}
621
622bool CameraClient::recordingEnabled() {
623 LOG1("recordingEnabled (pid %d)", getCallingPid());
624
625 Mutex::Autolock lock(mLock);
626 if (checkPidAndHardware() != NO_ERROR) return false;
627 return mHardware->recordingEnabled();
628}
629
630status_t CameraClient::autoFocus() {
631 LOG1("autoFocus (pid %d)", getCallingPid());
632
633 Mutex::Autolock lock(mLock);
634 status_t result = checkPidAndHardware();
635 if (result != NO_ERROR) return result;
636
637 return mHardware->autoFocus();
638}
639
640status_t CameraClient::cancelAutoFocus() {
641 LOG1("cancelAutoFocus (pid %d)", getCallingPid());
642
643 Mutex::Autolock lock(mLock);
644 status_t result = checkPidAndHardware();
645 if (result != NO_ERROR) return result;
646
647 return mHardware->cancelAutoFocus();
648}
649
650// take a picture - image is returned in callback
651status_t CameraClient::takePicture(int msgType) {
652 LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
653
654 Mutex::Autolock lock(mLock);
655 status_t result = checkPidAndHardware();
656 if (result != NO_ERROR) return result;
657
658 if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
659 (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
660 ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
661 " cannot be both enabled");
662 return BAD_VALUE;
663 }
664
665 // We only accept picture related message types
666 // and ignore other types of messages for takePicture().
667 int picMsgType = msgType
668 & (CAMERA_MSG_SHUTTER |
669 CAMERA_MSG_POSTVIEW_FRAME |
670 CAMERA_MSG_RAW_IMAGE |
671 CAMERA_MSG_RAW_IMAGE_NOTIFY |
672 CAMERA_MSG_COMPRESSED_IMAGE);
673
674 enableMsgType(picMsgType);
675
676 return mHardware->takePicture();
677}
678
679// set preview/capture parameters - key/value pairs
680status_t CameraClient::setParameters(const String8& params) {
681 LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
682
683 Mutex::Autolock lock(mLock);
684 status_t result = checkPidAndHardware();
685 if (result != NO_ERROR) return result;
686
Igor Murashkinfcf5fea2014-09-11 14:43:24 -0700687 mLatestSetParameters = CameraParameters(params);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700688 CameraParameters p(params);
689 return mHardware->setParameters(p);
690}
691
692// get preview/capture parameters - key/value pairs
693String8 CameraClient::getParameters() const {
694 Mutex::Autolock lock(mLock);
Igor Murashkinebe865b2014-08-07 17:07:28 -0700695 // The camera service can unconditionally get the parameters at all times
696 if (getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) return String8();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700697
698 String8 params(mHardware->getParameters().flatten());
699 LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
700 return params;
701}
702
703// enable shutter sound
704status_t CameraClient::enableShutterSound(bool enable) {
705 LOG1("enableShutterSound (pid %d)", getCallingPid());
706
707 status_t result = checkPidAndHardware();
708 if (result != NO_ERROR) return result;
709
710 if (enable) {
711 mPlayShutterSound = true;
712 return OK;
713 }
714
Igor Murashkina858ea02014-08-19 14:53:08 -0700715 // the camera2 api legacy mode can unconditionally disable the shutter sound
716 if (mLegacyMode) {
717 ALOGV("%s: Disable shutter sound in legacy mode", __FUNCTION__);
718 mPlayShutterSound = false;
719 return OK;
720 }
721
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700722 // Disabling shutter sound may not be allowed. In that case only
723 // allow the mediaserver process to disable the sound.
724 char value[PROPERTY_VALUE_MAX];
725 property_get("ro.camera.sound.forced", value, "0");
726 if (strcmp(value, "0") != 0) {
727 // Disabling shutter sound is not allowed. Deny if the current
728 // process is not mediaserver.
729 if (getCallingPid() != getpid()) {
730 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
731 return PERMISSION_DENIED;
732 }
733 }
734
735 mPlayShutterSound = false;
736 return OK;
737}
738
739status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
740 LOG1("sendCommand (pid %d)", getCallingPid());
741 int orientation;
742 Mutex::Autolock lock(mLock);
743 status_t result = checkPidAndHardware();
744 if (result != NO_ERROR) return result;
745
746 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
747 // Mirror the preview if the camera is front-facing.
748 orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
749 if (orientation == -1) return BAD_VALUE;
750
751 if (mOrientation != orientation) {
752 mOrientation = orientation;
753 if (mPreviewWindow != 0) {
Eino-Ville Talvalaf7351172016-02-09 12:13:57 -0800754 mHardware->setPreviewTransform(mOrientation);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700755 }
756 }
757 return OK;
758 } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
759 switch (arg1) {
760 case 0:
Eino-Ville Talvalac5268e82012-09-11 11:01:18 -0700761 return enableShutterSound(false);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700762 case 1:
Eino-Ville Talvalac5268e82012-09-11 11:01:18 -0700763 return enableShutterSound(true);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700764 default:
765 return BAD_VALUE;
766 }
767 return OK;
768 } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800769 sCameraService->playSound(CameraService::SOUND_RECORDING_START);
James Dong983cf232012-08-01 16:39:55 -0700770 } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
771 // Silently ignore this command
772 return INVALID_OPERATION;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700773 } else if (cmd == CAMERA_CMD_PING) {
774 // If mHardware is 0, checkPidAndHardware will return error.
775 return OK;
776 }
777
778 return mHardware->sendCommand(cmd, arg1, arg2);
779}
780
781// ----------------------------------------------------------------------------
782
783void CameraClient::enableMsgType(int32_t msgType) {
784 android_atomic_or(msgType, &mMsgEnabled);
785 mHardware->enableMsgType(msgType);
786}
787
788void CameraClient::disableMsgType(int32_t msgType) {
789 android_atomic_and(~msgType, &mMsgEnabled);
790 mHardware->disableMsgType(msgType);
791}
792
793#define CHECK_MESSAGE_INTERVAL 10 // 10ms
794bool CameraClient::lockIfMessageWanted(int32_t msgType) {
795 int sleepCount = 0;
796 while (mMsgEnabled & msgType) {
797 if (mLock.tryLock() == NO_ERROR) {
798 if (sleepCount > 0) {
799 LOG1("lockIfMessageWanted(%d): waited for %d ms",
800 msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
801 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800802
803 // If messages are no longer enabled after acquiring lock, release and drop message
804 if ((mMsgEnabled & msgType) == 0) {
805 mLock.unlock();
806 break;
807 }
808
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700809 return true;
810 }
811 if (sleepCount++ == 0) {
812 LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
813 }
814 usleep(CHECK_MESSAGE_INTERVAL * 1000);
815 }
816 ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
817 return false;
818}
819
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800820sp<CameraClient> CameraClient::getClientFromCookie(void* user) {
821 String8 cameraId = String8::format("%d", (int)(intptr_t) user);
822 auto clientDescriptor = sCameraService->mActiveClientManager.get(cameraId);
823 if (clientDescriptor != nullptr) {
824 return sp<CameraClient>{
825 static_cast<CameraClient*>(clientDescriptor->getValue().get())};
826 }
827 return sp<CameraClient>{nullptr};
828}
829
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700830// Callback messages can be dispatched to internal handlers or pass to our
831// client's callback functions, depending on the message type.
832//
833// notifyCallback:
834// CAMERA_MSG_SHUTTER handleShutter
835// (others) c->notifyCallback
836// dataCallback:
837// CAMERA_MSG_PREVIEW_FRAME handlePreviewData
838// CAMERA_MSG_POSTVIEW_FRAME handlePostview
839// CAMERA_MSG_RAW_IMAGE handleRawPicture
840// CAMERA_MSG_COMPRESSED_IMAGE handleCompressedPicture
841// (others) c->dataCallback
842// dataCallbackTimestamp
843// (others) c->dataCallbackTimestamp
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700844
845void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
846 int32_t ext2, void* user) {
847 LOG2("notifyCallback(%d)", msgType);
848
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800849 sp<CameraClient> client = getClientFromCookie(user);
Ruben Brunkcc776712015-02-17 20:18:47 -0800850 if (client.get() == nullptr) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700851
852 if (!client->lockIfMessageWanted(msgType)) return;
853
854 switch (msgType) {
855 case CAMERA_MSG_SHUTTER:
856 // ext1 is the dimension of the yuv picture.
857 client->handleShutter();
858 break;
859 default:
860 client->handleGenericNotify(msgType, ext1, ext2);
861 break;
862 }
863}
864
865void CameraClient::dataCallback(int32_t msgType,
866 const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
867 LOG2("dataCallback(%d)", msgType);
868
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800869 sp<CameraClient> client = getClientFromCookie(user);
Ruben Brunkcc776712015-02-17 20:18:47 -0800870 if (client.get() == nullptr) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700871
872 if (!client->lockIfMessageWanted(msgType)) return;
873 if (dataPtr == 0 && metadata == NULL) {
874 ALOGE("Null data returned in data callback");
875 client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
876 return;
877 }
878
879 switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
880 case CAMERA_MSG_PREVIEW_FRAME:
881 client->handlePreviewData(msgType, dataPtr, metadata);
882 break;
883 case CAMERA_MSG_POSTVIEW_FRAME:
884 client->handlePostview(dataPtr);
885 break;
886 case CAMERA_MSG_RAW_IMAGE:
887 client->handleRawPicture(dataPtr);
888 break;
889 case CAMERA_MSG_COMPRESSED_IMAGE:
890 client->handleCompressedPicture(dataPtr);
891 break;
892 default:
893 client->handleGenericData(msgType, dataPtr, metadata);
894 break;
895 }
896}
897
898void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
899 int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
900 LOG2("dataCallbackTimestamp(%d)", msgType);
901
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800902 sp<CameraClient> client = getClientFromCookie(user);
Ruben Brunkcc776712015-02-17 20:18:47 -0800903 if (client.get() == nullptr) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700904
905 if (!client->lockIfMessageWanted(msgType)) return;
906
907 if (dataPtr == 0) {
908 ALOGE("Null data returned in data with timestamp callback");
909 client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
910 return;
911 }
912
913 client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
914}
915
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700916void CameraClient::handleCallbackTimestampBatch(
917 int32_t msgType, const std::vector<HandleTimestampMessage>& msgs, void* user) {
918 LOG2("dataCallbackTimestampBatch");
919 sp<CameraClient> client = getClientFromCookie(user);
920 if (client.get() == nullptr) return;
921 if (!client->lockIfMessageWanted(msgType)) return;
922
923 sp<hardware::ICameraClient> c = client->mRemoteCallback;
924 client->mLock.unlock();
925 if (c != 0 && msgs.size() > 0) {
926 size_t n = msgs.size();
927 std::vector<nsecs_t> timestamps;
928 std::vector<native_handle_t*> handles;
929 timestamps.reserve(n);
930 handles.reserve(n);
931 for (auto& msg : msgs) {
932 native_handle_t* handle = nullptr;
933 if (msg.dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
934 ALOGE("%s: dataPtr does not contain VideoNativeHandleMetadata!", __FUNCTION__);
935 return;
936 }
937 VideoNativeHandleMetadata *metadata =
938 (VideoNativeHandleMetadata*)(msg.dataPtr->pointer());
939 if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
940 handle = metadata->pHandle;
941 }
942
943 if (handle == nullptr) {
944 ALOGE("%s: VideoNativeHandleMetadata type mismatch or null handle passed!",
945 __FUNCTION__);
946 return;
947 }
948 {
949 Mutex::Autolock l(client->mAvailableCallbackBuffersLock);
950 client->mAvailableCallbackBuffers.push_back(msg.dataPtr);
951 }
952 timestamps.push_back(msg.timestamp);
953 handles.push_back(handle);
954 }
955 c->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
956 }
957}
958
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700959// snapshot taken callback
960void CameraClient::handleShutter(void) {
961 if (mPlayShutterSound) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800962 sCameraService->playSound(CameraService::SOUND_SHUTTER);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700963 }
964
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800965 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700966 if (c != 0) {
967 mLock.unlock();
968 c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
969 if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
970 }
971 disableMsgType(CAMERA_MSG_SHUTTER);
972
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700973 // Shutters only happen in response to takePicture, so mark device as
974 // idle now, until preview is restarted
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800975 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700976 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
977 mCameraIdStr, mCameraFacing, mClientPackageName);
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700978
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700979 mLock.unlock();
980}
981
982// preview callback - frame buffer update
983void CameraClient::handlePreviewData(int32_t msgType,
984 const sp<IMemory>& mem,
985 camera_frame_metadata_t *metadata) {
986 ssize_t offset;
987 size_t size;
988 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
989
990 // local copy of the callback flags
991 int flags = mPreviewCallbackFlag;
992
993 // is callback enabled?
994 if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
995 // If the enable bit is off, the copy-out and one-shot bits are ignored
996 LOG2("frame callback is disabled");
997 mLock.unlock();
998 return;
999 }
1000
1001 // hold a strong pointer to the client
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001002 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001003
1004 // clear callback flags if no client or one-shot mode
1005 if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
1006 LOG2("Disable preview callback");
1007 mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
1008 CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
1009 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
1010 disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
1011 }
1012
1013 if (c != 0) {
1014 // Is the received frame copied out or not?
1015 if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
1016 LOG2("frame is copied");
1017 copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
1018 } else {
1019 LOG2("frame is forwarded");
1020 mLock.unlock();
1021 c->dataCallback(msgType, mem, metadata);
1022 }
1023 } else {
1024 mLock.unlock();
1025 }
1026}
1027
1028// picture callback - postview image ready
1029void CameraClient::handlePostview(const sp<IMemory>& mem) {
1030 disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
1031
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001032 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001033 mLock.unlock();
1034 if (c != 0) {
1035 c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
1036 }
1037}
1038
1039// picture callback - raw image ready
1040void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
1041 disableMsgType(CAMERA_MSG_RAW_IMAGE);
1042
1043 ssize_t offset;
1044 size_t size;
1045 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
1046
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001047 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001048 mLock.unlock();
1049 if (c != 0) {
1050 c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
1051 }
1052}
1053
1054// picture callback - compressed picture ready
1055void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
1056 disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
1057
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001058 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001059 mLock.unlock();
1060 if (c != 0) {
1061 c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
1062 }
1063}
1064
1065
1066void CameraClient::handleGenericNotify(int32_t msgType,
1067 int32_t ext1, int32_t ext2) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001068 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001069 mLock.unlock();
1070 if (c != 0) {
1071 c->notifyCallback(msgType, ext1, ext2);
1072 }
1073}
1074
1075void CameraClient::handleGenericData(int32_t msgType,
1076 const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001077 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001078 mLock.unlock();
1079 if (c != 0) {
1080 c->dataCallback(msgType, dataPtr, metadata);
1081 }
1082}
1083
1084void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
1085 int32_t msgType, const sp<IMemory>& dataPtr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001086 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001087 mLock.unlock();
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -07001088 if (c != 0 && dataPtr != nullptr) {
1089 native_handle_t* handle = nullptr;
1090
1091 // Check if dataPtr contains a VideoNativeHandleMetadata.
1092 if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) {
1093 VideoNativeHandleMetadata *metadata =
1094 (VideoNativeHandleMetadata*)(dataPtr->pointer());
1095 if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
1096 handle = metadata->pHandle;
1097 }
1098 }
1099
1100 // If dataPtr contains a native handle, send it via recordingFrameHandleCallbackTimestamp.
1101 if (handle != nullptr) {
1102 {
1103 Mutex::Autolock l(mAvailableCallbackBuffersLock);
1104 mAvailableCallbackBuffers.push_back(dataPtr);
1105 }
1106 c->recordingFrameHandleCallbackTimestamp(timestamp, handle);
1107 } else {
1108 c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
1109 }
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001110 }
1111}
1112
1113void CameraClient::copyFrameAndPostCopiedFrame(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001114 int32_t msgType, const sp<hardware::ICameraClient>& client,
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001115 const sp<IMemoryHeap>& heap, size_t offset, size_t size,
1116 camera_frame_metadata_t *metadata) {
1117 LOG2("copyFrameAndPostCopiedFrame");
1118 // It is necessary to copy out of pmem before sending this to
1119 // the callback. For efficiency, reuse the same MemoryHeapBase
1120 // provided it's big enough. Don't allocate the memory or
1121 // perform the copy if there's no callback.
1122 // hold the preview lock while we grab a reference to the preview buffer
1123 sp<MemoryHeapBase> previewBuffer;
1124
1125 if (mPreviewBuffer == 0) {
1126 mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
1127 } else if (size > mPreviewBuffer->virtualSize()) {
1128 mPreviewBuffer.clear();
1129 mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
1130 }
1131 if (mPreviewBuffer == 0) {
1132 ALOGE("failed to allocate space for preview buffer");
1133 mLock.unlock();
1134 return;
1135 }
1136 previewBuffer = mPreviewBuffer;
1137
Ruben Brunk65e01f72014-08-29 17:25:13 -07001138 void* previewBufferBase = previewBuffer->base();
1139 void* heapBase = heap->base();
1140
1141 if (heapBase == MAP_FAILED) {
1142 ALOGE("%s: Failed to mmap heap for preview frame.", __FUNCTION__);
1143 mLock.unlock();
1144 return;
1145 } else if (previewBufferBase == MAP_FAILED) {
1146 ALOGE("%s: Failed to mmap preview buffer for preview frame.", __FUNCTION__);
1147 mLock.unlock();
1148 return;
1149 }
1150
1151 memcpy(previewBufferBase, (uint8_t *) heapBase + offset, size);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001152
1153 sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
1154 if (frame == 0) {
1155 ALOGE("failed to allocate space for frame callback");
1156 mLock.unlock();
1157 return;
1158 }
1159
1160 mLock.unlock();
1161 client->dataCallback(msgType, frame, metadata);
1162}
1163
1164int CameraClient::getOrientation(int degrees, bool mirror) {
1165 if (!mirror) {
1166 if (degrees == 0) return 0;
1167 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
1168 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
1169 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
1170 } else { // Do mirror (horizontal flip)
1171 if (degrees == 0) { // FLIP_H and ROT_0
1172 return HAL_TRANSFORM_FLIP_H;
1173 } else if (degrees == 90) { // FLIP_H and ROT_90
1174 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
1175 } else if (degrees == 180) { // FLIP_H and ROT_180
1176 return HAL_TRANSFORM_FLIP_V;
1177 } else if (degrees == 270) { // FLIP_H and ROT_270
1178 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1179 }
1180 }
1181 ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
1182 return -1;
1183}
1184
Chien-Yu Chen8cca0752015-11-13 15:28:48 -08001185status_t CameraClient::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) {
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001186 (void)bufferProducer;
Chien-Yu Chen8cca0752015-11-13 15:28:48 -08001187 ALOGE("%s: %d: CameraClient doesn't support setting a video target.", __FUNCTION__, __LINE__);
1188 return INVALID_OPERATION;
1189}
1190
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001191}; // namespace android