CameraNDK: implement abortCaptures API
Bug: 27102995
Change-Id: Idaf1db02e0bcc60bb9cdb2797b4479ea0389f5f9
diff --git a/camera/ndk/impl/ACameraCaptureSession.cpp b/camera/ndk/impl/ACameraCaptureSession.cpp
index b741e46..b9c159d 100644
--- a/camera/ndk/impl/ACameraCaptureSession.cpp
+++ b/camera/ndk/impl/ACameraCaptureSession.cpp
@@ -90,6 +90,24 @@
}
camera_status_t
+ACameraCaptureSession::abortCaptures() {
+ sp<CameraDevice> dev = getDeviceSp();
+ if (dev == nullptr) {
+ ALOGE("Error: Device associated with session %p has been closed!", this);
+ return ACAMERA_ERROR_SESSION_CLOSED;
+ }
+
+ camera_status_t ret;
+ dev->lockDeviceForSessionOps();
+ {
+ Mutex::Autolock _l(mSessionLock);
+ ret = dev->flushLocked(this);
+ }
+ dev->unlockDevice();
+ return ret;
+}
+
+camera_status_t
ACameraCaptureSession::setRepeatingRequest(
/*optional*/ACameraCaptureSession_captureCallbacks* cbs,
int numRequests, ACaptureRequest** requests,
diff --git a/camera/ndk/impl/ACameraCaptureSession.h b/camera/ndk/impl/ACameraCaptureSession.h
index f20b324..58428e6 100644
--- a/camera/ndk/impl/ACameraCaptureSession.h
+++ b/camera/ndk/impl/ACameraCaptureSession.h
@@ -77,6 +77,8 @@
camera_status_t stopRepeating();
+ camera_status_t abortCaptures();
+
camera_status_t setRepeatingRequest(
/*optional*/ACameraCaptureSession_captureCallbacks* cbs,
int numRequests, ACaptureRequest** requests,
@@ -104,7 +106,6 @@
const wp<CameraDevice> mDevice;
bool mIsClosed = false;
bool mClosedByApp = false;
- bool mIdle = true;
Mutex mSessionLock;
};
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 6bca692..8f1115a 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -170,6 +170,7 @@
// set new session as current session
newSession->incStrong((void *) ACameraDevice_createCaptureSession);
mCurrentSession = newSession;
+ mFlushing = false;
*session = newSession;
return ACAMERA_OK;
}
@@ -389,6 +390,58 @@
}
camera_status_t
+CameraDevice::flushLocked(ACameraCaptureSession* session) {
+ camera_status_t ret = checkCameraClosedOrErrorLocked();
+ if (ret != ACAMERA_OK) {
+ ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
+ return ret;
+ }
+
+ // This should never happen because creating a new session will close
+ // previous one and thus reject any API call from previous session.
+ // But still good to check here in case something unexpected happen.
+ if (session != mCurrentSession) {
+ ALOGE("Camera %s session %p is not current active session!", getId(), session);
+ return ACAMERA_ERROR_INVALID_OPERATION;
+ }
+
+ if (mFlushing) {
+ ALOGW("Camera %s is already aborting captures", getId());
+ return ACAMERA_OK;
+ }
+
+ mFlushing = true;
+ // Send onActive callback to guarantee there is always active->ready transition
+ sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+ msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+ msg->setObject(kSessionSpKey, session);
+ msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
+ msg->post();
+
+ // If device is already idling, send callback and exit early
+ if (mIdle) {
+ sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
+ msg->setPointer(kContextKey, session->mUserSessionCallback.context);
+ msg->setObject(kSessionSpKey, session);
+ msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
+ msg->post();
+ mFlushing = false;
+ return ACAMERA_OK;
+ }
+
+ int64_t lastFrameNumber;
+ binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
+ if (!remoteRet.isOk()) {
+ ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
+ return ACAMERA_ERROR_UNKNOWN;
+ }
+ if (mRepeatingSequenceId != REQUEST_ID_NONE) {
+ checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
+ }
+ return ACAMERA_OK;
+}
+
+camera_status_t
CameraDevice::waitUntilIdleLocked() {
camera_status_t ret = checkCameraClosedOrErrorLocked();
if (ret != ACAMERA_OK) {
@@ -1109,6 +1162,7 @@
msg->post();
}
dev->mIdle = true;
+ dev->mFlushing = false;
return ret;
}
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 46243b9..fd51a81 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -96,6 +96,8 @@
camera_status_t stopRepeatingLocked();
+ camera_status_t flushLocked(ACameraCaptureSession*);
+
camera_status_t waitUntilIdleLocked();
@@ -152,13 +154,13 @@
std::atomic_bool mClosing;
inline bool isClosed() { return mClosing; }
- bool mInError;
- camera_status_t mError;
+ bool mInError = false;
+ camera_status_t mError = ACAMERA_OK;
void onCaptureErrorLocked(
int32_t errorCode,
const CaptureResultExtras& resultExtras);
- bool mIdle;
+ bool mIdle = true;
// This will avoid a busy session being deleted before it's back to idle state
sp<ACameraCaptureSession> mBusySession;
@@ -203,6 +205,7 @@
***********************************/
// The current active session
ACameraCaptureSession* mCurrentSession = nullptr;
+ bool mFlushing = false;
int mNextSessionId = 0;
// TODO: might need another looper/handler to handle callbacks from service