blob: f1203f998f5c26229e906cd0bbb24246f7b88b60 [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,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080045 String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080046 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,
Emilian Peev573291c2018-02-10 02:10:56 +0000266 mCameraIdStr, mCameraFacing, mClientPackageName,
267 hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700268 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);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800283
284 return res;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700285}
286
287// ----------------------------------------------------------------------------
288
289status_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) {
Eino-Ville Talvalaf7351172016-02-09 12:13:57 -0800312 mHardware->setPreviewScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
313 mHardware->setPreviewTransform(mOrientation);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700314 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
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700333// set the buffer consumer that the preview will use
334status_t CameraClient::setPreviewTarget(
Andy McFadden8ba01022012-12-18 09:46:54 -0800335 const sp<IGraphicBufferProducer>& bufferProducer) {
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700336 LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700337 getCallingPid());
338
339 sp<IBinder> binder;
340 sp<ANativeWindow> window;
Andy McFadden8ba01022012-12-18 09:46:54 -0800341 if (bufferProducer != 0) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800342 binder = IInterface::asBinder(bufferProducer);
Eino-Ville Talvala1ce7c342013-08-21 13:57:21 -0700343 // 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);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700347 }
348 return setPreviewWindow(binder, window);
349}
350
351// set the preview callback flag to affect how the received frames from
352// preview are handled.
353void 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
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700366status_t CameraClient::setPreviewCallbackTarget(
367 const sp<IGraphicBufferProducer>& callbackProducer) {
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700368 (void)callbackProducer;
Eino-Ville Talvala3ee35502013-04-02 15:45:11 -0700369 ALOGE("%s: Unimplemented!", __FUNCTION__);
370 return INVALID_OPERATION;
371}
372
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700373// start preview mode
374status_t CameraClient::startPreview() {
375 LOG1("startPreview (pid %d)", getCallingPid());
376 return startCameraMode(CAMERA_PREVIEW_MODE);
377}
378
379// start recording mode
380status_t CameraClient::startRecording() {
381 LOG1("startRecording (pid %d)", getCallingPid());
382 return startCameraMode(CAMERA_RECORDING_MODE);
383}
384
385// start preview or recording
386status_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
410status_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) {
Eino-Ville Talvalaf7351172016-02-09 12:13:57 -0800420 mHardware->setPreviewScalingMode(
421 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
422 mHardware->setPreviewTransform(mOrientation);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700423 }
424 mHardware->setPreviewWindow(mPreviewWindow);
425 result = mHardware->startPreview();
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700426 if (result == NO_ERROR) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800427 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700428 hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
Emilian Peev573291c2018-02-10 02:10:56 +0000429 mCameraIdStr, mCameraFacing, mClientPackageName,
430 hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700431 }
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700432 return result;
433}
434
435status_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);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800454 sCameraService->playSound(CameraService::SOUND_RECORDING_START);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700455 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
463void 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();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800471 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700472 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
Emilian Peev573291c2018-02-10 02:10:56 +0000473 mCameraIdStr, mCameraFacing, mClientPackageName,
474 hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700475 mPreviewBuffer.clear();
476}
477
478// stop recording mode
479void CameraClient::stopRecording() {
480 LOG1("stopRecording (pid %d)", getCallingPid());
Emilian Peev698f0a72017-04-05 11:20:09 +0100481 {
482 Mutex::Autolock lock(mLock);
483 if (checkPidAndHardware() != NO_ERROR) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700484
Emilian Peev698f0a72017-04-05 11:20:09 +0100485 disableMsgType(CAMERA_MSG_VIDEO_FRAME);
486 mHardware->stopRecording();
487 sCameraService->playSound(CameraService::SOUND_RECORDING_STOP);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700488
Emilian Peev698f0a72017-04-05 11:20:09 +0100489 mPreviewBuffer.clear();
490 }
491
492 {
493 Mutex::Autolock l(mAvailableCallbackBuffersLock);
494 if (!mAvailableCallbackBuffers.empty()) {
495 mAvailableCallbackBuffers.clear();
496 }
497 }
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700498}
499
500// release a recording frame
501void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
502 Mutex::Autolock lock(mLock);
503 if (checkPidAndHardware() != NO_ERROR) return;
Chien-Yu Chen42f27072016-01-11 17:39:17 -0800504 if (mem == nullptr) {
505 android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26164272",
506 IPCThreadState::self()->getCallingUid(), nullptr, 0);
507 return;
508 }
509
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700510 mHardware->releaseRecordingFrame(mem);
511}
512
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700513void CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
514 if (handle == nullptr) return;
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800515 Mutex::Autolock lock(mLock);
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700516 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
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800539 if (mHardware != nullptr) {
540 VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
541 metadata->eType = kMetadataBufferTypeNativeHandleSource;
542 metadata->pHandle = handle;
543 mHardware->releaseRecordingFrame(dataPtr);
544 }
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -0700545}
546
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700547void CameraClient::releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800548 Mutex::Autolock lock(mLock);
549 bool disconnected = (mHardware == nullptr);
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700550 size_t n = handles.size();
551 std::vector<sp<IMemory>> frames;
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800552 if (!disconnected) {
553 frames.reserve(n);
554 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700555 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
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800578 if (!disconnected) {
579 VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->pointer());
580 metadata->eType = kMetadataBufferTypeNativeHandleSource;
581 metadata->pHandle = handle;
582 frames.push_back(dataPtr);
583 }
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700584 }
585
586 if (error) {
587 for (auto& handle : handles) {
588 native_handle_close(handle);
589 native_handle_delete(handle);
590 }
Yin-Chia Yehf44c24a2018-01-09 10:34:29 -0800591 } else if (!disconnected) {
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700592 mHardware->releaseRecordingFrameBatch(frames);
593 }
594 return;
595}
596
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800597status_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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700609 Mutex::Autolock lock(mLock);
610 if (checkPidAndHardware() != NO_ERROR) {
611 return UNKNOWN_ERROR;
612 }
Chien-Yu Chen8cca0752015-11-13 15:28:48 -0800613
614 return mHardware->storeMetaDataInBuffers(enableMetadataInBuffers);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700615}
616
617bool 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
625bool 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
633status_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
643status_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
654status_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
683status_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
Igor Murashkinfcf5fea2014-09-11 14:43:24 -0700690 mLatestSetParameters = CameraParameters(params);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700691 CameraParameters p(params);
692 return mHardware->setParameters(p);
693}
694
695// get preview/capture parameters - key/value pairs
696String8 CameraClient::getParameters() const {
697 Mutex::Autolock lock(mLock);
Igor Murashkinebe865b2014-08-07 17:07:28 -0700698 // The camera service can unconditionally get the parameters at all times
699 if (getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) return String8();
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700700
701 String8 params(mHardware->getParameters().flatten());
702 LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
703 return params;
704}
705
706// enable shutter sound
707status_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
Igor Murashkina858ea02014-08-19 14:53:08 -0700718 // 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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700725 // 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
742status_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) {
Eino-Ville Talvalaf7351172016-02-09 12:13:57 -0800757 mHardware->setPreviewTransform(mOrientation);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700758 }
759 }
760 return OK;
761 } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
762 switch (arg1) {
763 case 0:
Eino-Ville Talvalac5268e82012-09-11 11:01:18 -0700764 return enableShutterSound(false);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700765 case 1:
Eino-Ville Talvalac5268e82012-09-11 11:01:18 -0700766 return enableShutterSound(true);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700767 default:
768 return BAD_VALUE;
769 }
770 return OK;
771 } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800772 sCameraService->playSound(CameraService::SOUND_RECORDING_START);
James Dong983cf232012-08-01 16:39:55 -0700773 } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
774 // Silently ignore this command
775 return INVALID_OPERATION;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700776 } 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
786void CameraClient::enableMsgType(int32_t msgType) {
787 android_atomic_or(msgType, &mMsgEnabled);
788 mHardware->enableMsgType(msgType);
789}
790
791void CameraClient::disableMsgType(int32_t msgType) {
792 android_atomic_and(~msgType, &mMsgEnabled);
793 mHardware->disableMsgType(msgType);
794}
795
796#define CHECK_MESSAGE_INTERVAL 10 // 10ms
797bool 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 }
Ruben Brunkcc776712015-02-17 20:18:47 -0800805
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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700812 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
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800823sp<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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700833// 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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700847
848void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
849 int32_t ext2, void* user) {
850 LOG2("notifyCallback(%d)", msgType);
851
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800852 sp<CameraClient> client = getClientFromCookie(user);
Ruben Brunkcc776712015-02-17 20:18:47 -0800853 if (client.get() == nullptr) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700854
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
868void CameraClient::dataCallback(int32_t msgType,
869 const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
870 LOG2("dataCallback(%d)", msgType);
871
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800872 sp<CameraClient> client = getClientFromCookie(user);
Ruben Brunkcc776712015-02-17 20:18:47 -0800873 if (client.get() == nullptr) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700874
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
901void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
902 int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
903 LOG2("dataCallbackTimestamp(%d)", msgType);
904
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800905 sp<CameraClient> client = getClientFromCookie(user);
Ruben Brunkcc776712015-02-17 20:18:47 -0800906 if (client.get() == nullptr) return;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700907
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
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700919void 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
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700962// snapshot taken callback
963void CameraClient::handleShutter(void) {
964 if (mPlayShutterSound) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800965 sCameraService->playSound(CameraService::SOUND_SHUTTER);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700966 }
967
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800968 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700969 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
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700976 // Shutters only happen in response to takePicture, so mark device as
977 // idle now, until preview is restarted
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800978 sCameraService->updateProxyDeviceState(
Eino-Ville Talvalae8c96c72017-06-27 12:24:07 -0700979 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
Emilian Peev573291c2018-02-10 02:10:56 +0000980 mCameraIdStr, mCameraFacing, mClientPackageName,
981 hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
Eino-Ville Talvala412fe562015-08-20 17:08:32 -0700982
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -0700983 mLock.unlock();
984}
985
986// preview callback - frame buffer update
987void 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
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001006 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001007
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
1033void CameraClient::handlePostview(const sp<IMemory>& mem) {
1034 disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
1035
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001036 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001037 mLock.unlock();
1038 if (c != 0) {
1039 c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
1040 }
1041}
1042
1043// picture callback - raw image ready
1044void 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
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001051 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001052 mLock.unlock();
1053 if (c != 0) {
1054 c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
1055 }
1056}
1057
1058// picture callback - compressed picture ready
1059void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
1060 disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
1061
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001062 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001063 mLock.unlock();
1064 if (c != 0) {
1065 c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
1066 }
1067}
1068
1069
1070void CameraClient::handleGenericNotify(int32_t msgType,
1071 int32_t ext1, int32_t ext2) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001072 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001073 mLock.unlock();
1074 if (c != 0) {
1075 c->notifyCallback(msgType, ext1, ext2);
1076 }
1077}
1078
1079void CameraClient::handleGenericData(int32_t msgType,
1080 const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001081 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001082 mLock.unlock();
1083 if (c != 0) {
1084 c->dataCallback(msgType, dataPtr, metadata);
1085 }
1086}
1087
1088void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
1089 int32_t msgType, const sp<IMemory>& dataPtr) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001090 sp<hardware::ICameraClient> c = mRemoteCallback;
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001091 mLock.unlock();
Chien-Yu Chen2d13b1d2016-04-28 12:11:20 -07001092 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 }
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001114 }
1115}
1116
1117void CameraClient::copyFrameAndPostCopiedFrame(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001118 int32_t msgType, const sp<hardware::ICameraClient>& client,
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001119 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
Ruben Brunk65e01f72014-08-29 17:25:13 -07001142 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);
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001156
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
1168int 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
Chien-Yu Chen8cca0752015-11-13 15:28:48 -08001189status_t CameraClient::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) {
Chien-Yu Chen98a668f2015-12-18 14:10:33 -08001190 (void)bufferProducer;
Chien-Yu Chen8cca0752015-11-13 15:28:48 -08001191 ALOGE("%s: %d: CameraClient doesn't support setting a video target.", __FUNCTION__, __LINE__);
1192 return INVALID_OPERATION;
1193}
1194
Eino-Ville Talvala5e08d602012-05-16 14:59:25 -07001195}; // namespace android