Camera2: Add thermal adapter
Thermal adapter is a singleton class to abstract a
thermal daemon client. The adapter would notify
camera HAL of thermal events.
Based on thermal threshold and level, we may adjust
camera/camcorder FPS accordingly.
Change-Id: Ib5192243f5b20ea151bd18cdf743a04e926aaab9
diff --git a/QCamera2/HAL/Android.mk b/QCamera2/HAL/Android.mk
index 7d1d968..dce1cc1 100644
--- a/QCamera2/HAL/Android.mk
+++ b/QCamera2/HAL/Android.mk
@@ -14,7 +14,8 @@
QCameraStream.cpp \
QCameraPostProc.cpp \
QCamera2HWICallbacks.cpp \
- QCameraParameters.cpp
+ QCameraParameters.cpp \
+ QCameraThermalAdapter.cpp
LOCAL_CFLAGS = -Wall -Werror
@@ -31,7 +32,7 @@
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include/media
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-LOCAL_SHARED_LIBRARIES := libcamera_client liblog libhardware libutils libcutils
+LOCAL_SHARED_LIBRARIES := libcamera_client liblog libhardware libutils libcutils libdl
LOCAL_SHARED_LIBRARIES += libmmcamera_interface libmmjpeg_interface libgenlock
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
diff --git a/QCamera2/HAL/QCamera2HWI.cpp b/QCamera2/HAL/QCamera2HWI.cpp
index d2c4c43..4a87d58 100644
--- a/QCamera2/HAL/QCamera2HWI.cpp
+++ b/QCamera2/HAL/QCamera2HWI.cpp
@@ -564,6 +564,7 @@
mStoreMetaDataInFrame(0),
m_stateMachine(this),
m_postprocessor(this),
+ m_thermalAdapter(QCameraThermalAdapter::getInstance()),
m_bShutterSoundPlayed(false),
m_bAutoFocusRunning(false),
m_pHistBuf(NULL)
@@ -574,6 +575,7 @@
mCameraDevice.ops = &mCameraOps;
mCameraDevice.priv = this;
+
pthread_mutex_init(&m_lock, NULL);
pthread_cond_init(&m_cond, NULL);
memset(&m_apiResult, 0, sizeof(qcamera_api_result_t));
@@ -625,7 +627,7 @@
m_evtNotifyTh.launch(evtNotifyRoutine, this);
mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
- evtHandle,
+ camEvtHandle,
(void *) this);
int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
@@ -647,6 +649,11 @@
gCamCapability[mCameraId]->padding_info.plane_padding = padding_info.plane_padding;
}
+ rc = m_thermalAdapter.init(this);
+ if (rc != 0) {
+ ALOGE("Init thermal adapter failed");
+ }
+
mParameters.init(gCamCapability[mCameraId], mCameraHandle);
mCameraOpened = true;
@@ -665,6 +672,8 @@
m_postprocessor.stop();
m_postprocessor.deinit();
+ m_thermalAdapter.deinit();
+
// delete all channels if not already deleted
for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
if (m_channels[i] != NULL) {
@@ -1340,7 +1349,7 @@
return m_stateMachine.procEvt(evt, evt_payload);
}
-void QCamera2HardwareInterface::evtHandle(uint32_t /*camera_handle*/,
+void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
mm_camera_event_t *evt,
void *user_data)
{
@@ -1381,6 +1390,14 @@
}
}
+int QCamera2HardwareInterface::thermalEvtHandle(char *name,
+ int threshold,
+ int level)
+{
+ ALOGI("%s: name: %s, threshold: %d, level: %d", __func__, name, threshold, level);
+ return NO_ERROR;
+}
+
void *QCamera2HardwareInterface::evtNotifyRoutine(void *data)
{
int running = 1;
diff --git a/QCamera2/HAL/QCamera2HWI.h b/QCamera2/HAL/QCamera2HWI.h
index 92b902e..0e7bfca 100644
--- a/QCamera2/HAL/QCamera2HWI.h
+++ b/QCamera2/HAL/QCamera2HWI.h
@@ -40,6 +40,7 @@
#include "QCameraStateMachine.h"
#include "QCameraAllocator.h"
#include "QCameraPostProc.h"
+#include "QCameraThermalAdapter.h"
extern "C" {
#include <mm_camera_interface.h>
@@ -81,7 +82,8 @@
#define QCAMERA_DUMP_FRM_RAW 1<<4
#define QCAMERA_DUMP_FRM_JPEG 1<<5
-class QCamera2HardwareInterface : public QCameraAllocator
+class QCamera2HardwareInterface : public QCameraAllocator,
+ public QCameraThermalCallback
{
public:
/* static variable and functions accessed by camera service */
@@ -131,6 +133,10 @@
virtual QCameraMemory *allocateStreamBuf(cam_stream_type_t stream_type, int size);
virtual QCameraHeapMemory *allocateStreamInfoBuf(cam_stream_type_t stream_type);
+ // Implementation of QCameraThermalCallback
+ virtual int thermalEvtHandle(char *name,
+ int threshold, int level);
+
friend class QCameraStateMachine;
friend class QCameraPostProcessor;
@@ -226,7 +232,7 @@
bool isNoDisplayMode() {return mParameters.isNoDisplayMode();};
uint8_t numOfSnapshotsExpected() {return mParameters.getNumOfSnapshots();};
- static void evtHandle(uint32_t camera_handle,
+ static void camEvtHandle(uint32_t camera_handle,
mm_camera_event_t *evt,
void *user_data);
static void jpegEvtHandle(jpeg_job_status_t status,
@@ -284,6 +290,7 @@
QCameraStateMachine m_stateMachine; // state machine
QCameraPostProcessor m_postprocessor; // post processor
+ QCameraThermalAdapter &m_thermalAdapter;
pthread_mutex_t m_lock;
pthread_cond_t m_cond;
qcamera_api_result_t m_apiResult;
diff --git a/QCamera2/HAL/QCameraStateMachine.cpp b/QCamera2/HAL/QCameraStateMachine.cpp
index 82e9514..5773fcd 100644
--- a/QCamera2/HAL/QCameraStateMachine.cpp
+++ b/QCamera2/HAL/QCameraStateMachine.cpp
@@ -508,6 +508,7 @@
case QCAMERA_SM_EVT_EVT_NOTIFY:
case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
case QCAMERA_SM_EVT_SNAPSHOT_DONE:
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
default:
ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
break;
@@ -742,6 +743,7 @@
case QCAMERA_SM_EVT_EVT_NOTIFY:
case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
case QCAMERA_SM_EVT_SNAPSHOT_DONE:
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
default:
ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
break;
@@ -1028,6 +1030,9 @@
}
}
break;
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
+ //TODO: Adjust FPS.
+ break;
case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
case QCAMERA_SM_EVT_SNAPSHOT_DONE:
default:
@@ -1292,6 +1297,7 @@
m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
}
break;
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
default:
ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
break;
@@ -1567,6 +1573,9 @@
}
}
break;
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
+ //TODO: Adjust FPS
+ break;
case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
case QCAMERA_SM_EVT_SNAPSHOT_DONE:
default:
@@ -1845,6 +1854,9 @@
m_state = QCAMERA_SM_STATE_RECORDING;
}
break;
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
+ //TODO: Adjust FPS.
+ break;
default:
ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
break;
@@ -2128,6 +2140,9 @@
m_state = QCAMERA_SM_STATE_PREVIEWING;
}
break;
+ case QCAMERA_SM_EVT_THERMAL_NOTIFY:
+ //TODO: Adjust FPS
+ break;
default:
ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
break;
diff --git a/QCamera2/HAL/QCameraStateMachine.h b/QCamera2/HAL/QCameraStateMachine.h
index 8798b4e..0e7502f 100644
--- a/QCamera2/HAL/QCameraStateMachine.h
+++ b/QCamera2/HAL/QCameraStateMachine.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -82,6 +82,7 @@
QCAMERA_SM_EVT_EVT_NOTIFY, // evt notify from server
QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, // evt notify from jpeg
QCAMERA_SM_EVT_SNAPSHOT_DONE, // internal evt that snapshot is done
+ QCAMERA_SM_EVT_THERMAL_NOTIFY, // evt notify from thermal daemon
QCAMERA_SM_EVT_MAX
} qcamera_sm_evt_enum_t;
diff --git a/QCamera2/HAL/QCameraThermalAdapter.cpp b/QCamera2/HAL/QCameraThermalAdapter.cpp
new file mode 100644
index 0000000..e5ae096
--- /dev/null
+++ b/QCamera2/HAL/QCameraThermalAdapter.cpp
@@ -0,0 +1,146 @@
+/* Copyright (c) 2013, The Linux Foundataion. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_TAG "QCameraThermalAdapter"
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <utils/Errors.h>
+
+#include "QCameraThermalAdapter.h"
+
+using namespace android;
+
+namespace qcamera {
+
+
+QCameraThermalAdapter& QCameraThermalAdapter::getInstance()
+{
+ static QCameraThermalAdapter instance;
+ return instance;
+}
+
+QCameraThermalAdapter::QCameraThermalAdapter() :
+ mCallback(NULL),
+ mHandle(NULL),
+ mRegister(NULL),
+ mUnregister(NULL)
+{
+}
+
+int QCameraThermalAdapter::init(QCameraThermalCallback *thermalCb)
+{
+ const char *error = NULL;
+ int rc;
+
+ ALOGV("%s E", __func__);
+ mHandle = dlopen("/system/lib/libthermalclient.so", RTLD_NOW);
+ if (!mHandle) {
+ error = dlerror();
+ ALOGE("%s: dlopen failed with error %s",
+ __func__, error ? error : "");
+ rc = UNKNOWN_ERROR;
+ goto error;
+ }
+ *(void **)&mRegister = dlsym(mHandle, "thermal_register_callback");
+ if (!mRegister) {
+ error = dlerror();
+ ALOGE("%s: dlsym failed with error code %s",
+ __func__, error ? error: "");
+ rc = UNKNOWN_ERROR;
+ goto error2;
+ }
+ *(void **)&mUnregister = dlsym(mHandle, "thermal_unregister_callback");
+ if (!mUnregister) {
+ error = dlerror();
+ ALOGE("%s: dlsym failed with error code %s",
+ __func__, error ? error: "");
+ rc = UNKNOWN_ERROR;
+ goto error2;
+ }
+
+ // Register camera and camcorder callbacks
+ rc = mRegister(mStrCamera, thermalCallback, NULL);
+ if (rc < 0) {
+ ALOGE("%s: thermal_register_callback failed %d", __func__, rc);
+ goto error2;
+ }
+ rc = mRegister(mStrCamcorder, thermalCallback, NULL);
+ if (rc < 0) {
+ ALOGE("%s: thermal_register_callback failed %d", __func__, rc);
+ goto error3;
+ }
+
+ mCallback = thermalCb;
+ ALOGV("%s X", __func__);
+ return rc;
+
+error3:
+ mUnregister(mStrCamera);
+error2:
+ dlclose(mHandle);
+error:
+ ALOGV("%s X", __func__);
+ return rc;
+}
+
+void QCameraThermalAdapter::deinit()
+{
+ ALOGV("%s E", __func__);
+ if (mUnregister) {
+ mUnregister(mStrCamera);
+ mUnregister(mStrCamcorder);
+ }
+ if (mHandle)
+ dlclose(mHandle);
+
+ mHandle = NULL;
+ mRegister = NULL;
+ mUnregister = NULL;
+ mCallback = NULL;
+ ALOGV("%s X", __func__);
+}
+
+char QCameraThermalAdapter::mStrCamera[] = "camera";
+char QCameraThermalAdapter::mStrCamcorder[] = "camcorder";
+
+int QCameraThermalAdapter::thermalCallback(char * name,
+ int threshold, int level)
+{
+ int rc = 0;
+ ALOGV("%s E", __func__);
+ QCameraThermalAdapter& instance = getInstance();
+ if (instance.mCallback)
+ rc = instance.mCallback->thermalEvtHandle(name, threshold, level);
+ ALOGV("%s X", __func__);
+ return rc;
+}
+
+}; //namespace qcamera
diff --git a/QCamera2/HAL/QCameraThermalAdapter.h b/QCamera2/HAL/QCameraThermalAdapter.h
new file mode 100644
index 0000000..ca6f1c5
--- /dev/null
+++ b/QCamera2/HAL/QCameraThermalAdapter.h
@@ -0,0 +1,70 @@
+/* Copyright (c) 2013, The Linux Foundataion. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __QCAMERA_THERMAL_ADAPTER__
+#define __QCAMERA_THERMAL_ADAPTER__
+
+namespace qcamera {
+
+class QCameraThermalCallback
+{
+public:
+ virtual int thermalEvtHandle(char *name, int threshold,
+ int level) = 0;
+ virtual ~QCameraThermalCallback() {}
+};
+
+class QCameraThermalAdapter
+{
+public:
+ static QCameraThermalAdapter& getInstance();
+
+ int init(QCameraThermalCallback *thermalCb);
+ void deinit();
+
+private:
+ static char mStrCamera[];
+ static char mStrCamcorder[];
+
+ static int thermalCallback(char *name, int threshold, int level);
+
+ QCameraThermalCallback *mCallback;
+ void *mHandle;
+ int (*mRegister)(char *name, int (*callback)(char *, int, int), void *data);
+ int (*mUnregister)(char *name);
+
+ QCameraThermalAdapter();
+ QCameraThermalAdapter(QCameraThermalAdapter const& copy); // not implemented
+ QCameraThermalAdapter& operator=(QCameraThermalAdapter const& copy); // not implemented
+
+};
+
+}; // namespace qcamera
+
+#endif /* __QCAMERA_THERMAL_ADAPTER__ */