Camera: Add initial offline client listener logic
Various camera notification callbacks need to be
propagated back to client.
Test: Camera CTS
Bug: 135142453
Change-Id: I11a1bc634e4c6f9540d1f7f9c20e4151fdcc5ec6
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index e7e72b2..ba17eb6 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1979,7 +1979,14 @@
mClientFeatureId, mCameraIdStr, mCameraFacing, mClientPid, mClientUid, mServicePid);
ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient);
if (ret == OK) {
- // TODO: We need to update mStreamMap, mConfiguredOutputs, mCompositeStreams
+ // A successful offline session switch must reset the current camera client
+ // and release any resources occupied by previously configured streams.
+ mStreamMap.clear();
+ mConfiguredOutputs.clear();
+ mDeferredStreams.clear();
+ mStreamInfoMap.clear();
+ mCompositeStreamMap.clear();
+ mInputStream = {false, 0, 0, 0, 0};
} else {
switch(ret) {
case BAD_VALUE:
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index f713419..af7b9e1 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
//#define LOG_NDEBUG 0
#include "CameraOfflineSessionClient.h"
+#include "utils/CameraThreadState.h"
#include <utils/Trace.h>
namespace android {
@@ -26,22 +27,71 @@
using binder::Status;
status_t CameraOfflineSessionClient::initialize(sp<CameraProviderManager>, const String8&) {
+ ATRACE_CALL();
+
+ // Verify ops permissions
+ auto res = startCameraOps();
+ if (res != OK) {
+ return res;
+ }
+
+ if (mOfflineSession.get() == nullptr) {
+ ALOGE("%s: Camera %s: No valid offline session",
+ __FUNCTION__, mCameraIdStr.string());
+ return NO_INIT;
+ }
+
+ wp<NotificationListener> weakThis(this);
+ res = mOfflineSession->initialize(weakThis);
+ if (res != OK) {
+ ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
+ __FUNCTION__, mCameraIdStr.string(), strerror(-res), res);
+ return res;
+ }
+
return OK;
}
-status_t CameraOfflineSessionClient::dump(int /*fd*/, const Vector<String16>& /*args*/) {
- return OK;
+status_t CameraOfflineSessionClient::dump(int fd, const Vector<String16>& args) {
+ return BasicClient::dump(fd, args);
}
-status_t CameraOfflineSessionClient::dumpClient(int /*fd*/, const Vector<String16>& /*args*/) {
+status_t CameraOfflineSessionClient::dumpClient(int fd, const Vector<String16>& /*args*/) {
+ String8 result;
+
+ result = " Offline session dump:\n";
+ write(fd, result.string(), result.size());
+
+ if (mOfflineSession.get() == nullptr) {
+ result = " *** Offline session is detached\n";
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+ }
+
+ auto res = mOfflineSession->dump(fd);
+ if (res != OK) {
+ result = String8::format(" Error dumping offline session: %s (%d)",
+ strerror(-res), res);
+ write(fd, result.string(), result.size());
+ }
+
return OK;
}
binder::Status CameraOfflineSessionClient::disconnect() {
+ Mutex::Autolock icl(mBinderSerializationLock);
+
binder::Status res = Status::ok();
if (mDisconnected) {
return res;
}
+ // Allow both client and the media server to disconnect at all times
+ int callingPid = CameraThreadState::getCallingPid();
+ if (callingPid != mClientPid &&
+ callingPid != mServicePid) {
+ return res;
+ }
+
mDisconnected = true;
sCameraService->removeByClient(this);
@@ -59,6 +109,15 @@
// client shouldn't be able to call into us anymore
mClientPid = 0;
+ if (mOfflineSession.get() != nullptr) {
+ auto ret = mOfflineSession->disconnect();
+ if (ret != OK) {
+ ALOGE("%s: Failed disconnecting from offline session %s (%d)", __FUNCTION__,
+ strerror(-ret), ret);
+ }
+ mOfflineSession = nullptr;
+ }
+
for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
auto ret = mCompositeStreamMap.valueAt(i)->deleteInternalStreams();
if (ret != OK) {
@@ -74,8 +133,6 @@
void CameraOfflineSessionClient::notifyError(int32_t errorCode,
const CaptureResultExtras& resultExtras) {
// Thread safe. Don't bother locking.
- sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
- //
// Composites can have multiple internal streams. Error notifications coming from such internal
// streams may need to remain within camera service.
bool skipClientNotification = false;
@@ -83,8 +140,8 @@
skipClientNotification |= mCompositeStreamMap.valueAt(i)->onError(errorCode, resultExtras);
}
- if ((remoteCb != 0) && (!skipClientNotification)) {
- remoteCb->onDeviceError(errorCode, resultExtras);
+ if ((mRemoteCallback.get() != nullptr) && (!skipClientNotification)) {
+ mRemoteCallback->onDeviceError(errorCode, resultExtras);
}
}
@@ -156,10 +213,8 @@
ATRACE_CALL();
ALOGV("%s", __FUNCTION__);
- // Thread-safe. No lock necessary.
- sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
- if (remoteCb != NULL) {
- remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
+ if (mRemoteCallback.get() != NULL) {
+ mRemoteCallback->onResultReceived(result.mMetadata, result.mResultExtras,
result.mPhysicalMetadatas);
}
@@ -170,10 +225,9 @@
void CameraOfflineSessionClient::notifyShutter(const CaptureResultExtras& resultExtras,
nsecs_t timestamp) {
- // Thread safe. Don't bother locking.
- sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
- if (remoteCb != 0) {
- remoteCb->onCaptureStarted(resultExtras, timestamp);
+
+ if (mRemoteCallback.get() != nullptr) {
+ mRemoteCallback->onCaptureStarted(resultExtras, timestamp);
}
for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
@@ -181,5 +235,53 @@
}
}
+void CameraOfflineSessionClient::notifyIdle() {
+ if (mRemoteCallback.get() != nullptr) {
+ mRemoteCallback->onDeviceIdle();
+ }
+}
+
+void CameraOfflineSessionClient::notifyAutoFocus(uint8_t newState, int triggerId) {
+ (void)newState;
+ (void)triggerId;
+
+ ALOGV("%s: Autofocus state now %d, last trigger %d",
+ __FUNCTION__, newState, triggerId);
+}
+
+void CameraOfflineSessionClient::notifyAutoExposure(uint8_t newState, int triggerId) {
+ (void)newState;
+ (void)triggerId;
+
+ ALOGV("%s: Autoexposure state now %d, last trigger %d",
+ __FUNCTION__, newState, triggerId);
+}
+
+void CameraOfflineSessionClient::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
+ (void)newState;
+ (void)triggerId;
+
+ ALOGV("%s: Auto-whitebalance state now %d, last trigger %d", __FUNCTION__, newState,
+ triggerId);
+}
+
+void CameraOfflineSessionClient::notifyPrepared(int /*streamId*/) {
+ ALOGE("%s: Unexpected stream prepare notification in offline mode!", __FUNCTION__);
+ notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
+ CaptureResultExtras());
+}
+
+void CameraOfflineSessionClient::notifyRequestQueueEmpty() {
+ if (mRemoteCallback.get() != nullptr) {
+ mRemoteCallback->onRequestQueueEmpty();
+ }
+}
+
+void CameraOfflineSessionClient::notifyRepeatingRequestError(long /*lastFrameNumber*/) {
+ ALOGE("%s: Unexpected repeating request error in offline mode!", __FUNCTION__);
+ notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
+ CaptureResultExtras());
+}
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index e92a05c..b0f000d 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -19,6 +19,8 @@
#include <android/hardware/camera2/BnCameraOfflineSession.h>
#include <android/hardware/camera2/ICameraDeviceCallbacks.h>
+#include "common/FrameProcessorBase.h"
+#include "common/CameraDeviceBase.h"
#include "CameraService.h"
#include "CompositeStream.h"
@@ -35,8 +37,9 @@
// is created through ICameraDeviceUser::switchToOffline call.
class CameraOfflineSessionClient :
public CameraService::BasicClient,
- public hardware::camera2::BnCameraOfflineSession
- // public camera2::FrameProcessorBase::FilteredListener?
+ public hardware::camera2::BnCameraOfflineSession,
+ public camera2::FrameProcessorBase::FilteredListener,
+ public NotificationListener
{
public:
CameraOfflineSessionClient(
@@ -58,42 +61,45 @@
virtual ~CameraOfflineSessionClient() {}
- virtual sp<IBinder> asBinderWrapper() override {
+ sp<IBinder> asBinderWrapper() override {
return IInterface::asBinder(this);
}
- virtual binder::Status disconnect() override;
+ binder::Status disconnect() override;
- virtual status_t dump(int /*fd*/, const Vector<String16>& /*args*/) override;
+ status_t dump(int /*fd*/, const Vector<String16>& /*args*/) override;
- virtual status_t dumpClient(int /*fd*/, const Vector<String16>& /*args*/) override;
+ status_t dumpClient(int /*fd*/, const Vector<String16>& /*args*/) override;
- virtual void notifyError(int32_t /*errorCode*/,
- const CaptureResultExtras& /*resultExtras*/) override;
-
- virtual status_t initialize(sp<CameraProviderManager> /*manager*/,
+ status_t initialize(sp<CameraProviderManager> /*manager*/,
const String8& /*monitorTags*/) override;
// permissions management
- virtual status_t startCameraOps() override;
- virtual status_t finishCameraOps() override;
+ status_t startCameraOps() override;
+ status_t finishCameraOps() override;
- // TODO: Those will be introduced when we implement FilteredListener and the device
- // callbacks respectively. Just adding for now.
- void onResultAvailable(const CaptureResult& result);
- void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp);
+ // FilteredResultListener API
+ void onResultAvailable(const CaptureResult& result) override;
+
+ // NotificationListener API
+ void notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) override;
+ void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) override;
+ void notifyIdle() override;
+ void notifyAutoFocus(uint8_t newState, int triggerId) override;
+ void notifyAutoExposure(uint8_t newState, int triggerId) override;
+ void notifyAutoWhitebalance(uint8_t newState, int triggerId) override;
+ void notifyPrepared(int streamId) override;
+ void notifyRequestQueueEmpty() override;
+ void notifyRepeatingRequestError(long lastFrameNumber) override;
private:
-
- const sp<hardware::camera2::ICameraDeviceCallbacks>& getRemoteCallback() {
- return mRemoteCallback;
- }
+ mutable Mutex mBinderSerializationLock;
sp<hardware::camera2::ICameraDeviceCallbacks> mRemoteCallback;
sp<CameraOfflineSessionBase> mOfflineSession;
- // Offline composite streams
+ // Offline composite stream map, output surface -> composite stream
KeyedVector<sp<IBinder>, sp<CompositeStream>> mCompositeStreamMap;
};