Camera2: Add notification handling skeleton.

Wire up skeleton methods for handling all currently defined
notifications.

Bug: 6243944
Change-Id: I84b3f60111416ba6fbcdb086f1310225142e2b70
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 0d45596..dfcc8c0 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -116,7 +116,6 @@
     // Rewrite mClientPid to allow shutdown by CameraService
     mClientPid = getCallingPid();
     disconnect();
-
 }
 
 status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
@@ -1660,6 +1659,30 @@
 
 /** Device-related methods */
 
+void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
+    ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
+}
+
+void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
+    ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
+            frameNumber, timestamp);
+}
+
+void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
+    ALOGV("%s: Autofocus state now %d, last trigger %d",
+            __FUNCTION__, newState, triggerId);
+}
+
+void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
+    ALOGV("%s: Autoexposure state now %d, last trigger %d",
+            __FUNCTION__, newState, triggerId);
+}
+
+void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
+    ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
+            __FUNCTION__, newState, triggerId);
+}
+
 void Camera2Client::onCaptureAvailable() {
     ATRACE_CALL();
     status_t res;
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 6651507..2e6a36c 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -31,10 +31,12 @@
  * Implements the android.hardware.camera API on top of
  * camera device HAL version 2.
  */
-class Camera2Client : public CameraService::Client
+class Camera2Client : public CameraService::Client,
+                      public Camera2Device::NotificationListener
 {
 public:
     // ICamera interface (see ICamera for details)
+
     virtual void            disconnect();
     virtual status_t        connect(const sp<ICameraClient>& client);
     virtual status_t        lock();
@@ -59,17 +61,26 @@
     virtual status_t        sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
 
     // Interface used by CameraService
+
     Camera2Client(const sp<CameraService>& cameraService,
             const sp<ICameraClient>& cameraClient,
             int cameraId,
             int cameraFacing,
             int clientPid);
-    ~Camera2Client();
+    virtual ~Camera2Client();
 
     status_t initialize(camera_module_t *module);
 
     virtual status_t dump(int fd, const Vector<String16>& args);
 
+    // Interface used by CameraDevice
+
+    virtual void notifyError(int errorCode, int arg1, int arg2);
+    virtual void notifyShutter(int frameNumber, nsecs_t timestamp);
+    virtual void notifyAutoFocus(uint8_t newState, int triggerId);
+    virtual void notifyAutoExposure(uint8_t newState, int triggerId);
+    virtual void notifyAutoWhitebalance(uint8_t newState, int triggerId);
+
 private:
     enum State {
         DISCONNECTED,
@@ -389,6 +400,7 @@
 
     // Map from camera orientation + facing to gralloc transform enum
     static int degToTransform(int degrees, bool mirror);
+
 };
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index b09fdcc..f6253d2 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -109,6 +109,8 @@
         return res;
     }
 
+    setNotifyCallback(NULL);
+
     return OK;
 }
 
@@ -286,6 +288,57 @@
     return OK;
 }
 
+status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
+    status_t res;
+    res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
+            reinterpret_cast<void*>(listener) );
+    if (res != OK) {
+        ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
+    }
+    return res;
+}
+
+void Camera2Device::notificationCallback(int32_t msg_type,
+        int32_t ext1,
+        int32_t ext2,
+        int32_t ext3,
+        void *user) {
+    NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
+    ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
+            ext1, ext2, ext3);
+    if (listener != NULL) {
+        switch (msg_type) {
+            case CAMERA2_MSG_ERROR:
+                listener->notifyError(ext1, ext2, ext3);
+                break;
+            case CAMERA2_MSG_SHUTTER: {
+                nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
+                listener->notifyShutter(ext1, timestamp);
+                break;
+            }
+            case CAMERA2_MSG_AUTOFOCUS:
+                listener->notifyAutoFocus(ext1, ext2);
+                break;
+            case CAMERA2_MSG_AUTOEXPOSURE:
+                listener->notifyAutoExposure(ext1, ext2);
+                break;
+            case CAMERA2_MSG_AUTOWB:
+                listener->notifyAutoWhitebalance(ext1, ext2);
+                break;
+            default:
+                ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
+                        __FUNCTION__, msg_type, ext1, ext2, ext3);
+        }
+    }
+}
+
+/**
+ * Camera2Device::NotificationListener
+ */
+
+Camera2Device::NotificationListener::~NotificationListener() {
+}
+
 /**
  * Camera2Device::MetadataQueue
  */
diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h
index 4ac63df..91a3fbd 100644
--- a/services/camera/libcameraservice/Camera2Device.h
+++ b/services/camera/libcameraservice/Camera2Device.h
@@ -102,6 +102,27 @@
      */
     status_t waitUntilDrained();
 
+    /**
+     * Abstract class for HAL notification listeners
+     */
+    class NotificationListener {
+      public:
+        // Refer to the Camera2 HAL definition for notification definitions
+        virtual void notifyError(int errorCode, int arg1, int arg2) = 0;
+        virtual void notifyShutter(int frameNumber, nsecs_t timestamp) = 0;
+        virtual void notifyAutoFocus(uint8_t newState, int triggerId) = 0;
+        virtual void notifyAutoExposure(uint8_t newState, int triggerId) = 0;
+        virtual void notifyAutoWhitebalance(uint8_t newState, int triggerId) = 0;
+      protected:
+        virtual ~NotificationListener();
+    };
+
+    /**
+     * Connect HAL notifications to a listener. Overwrites previous
+     * listener. Set to NULL to stop receiving notifications.
+     */
+    status_t setNotifyCallback(NotificationListener *listener);
+
   private:
 
     const int mId;
@@ -282,6 +303,13 @@
     typedef List<sp<StreamAdapter> > StreamList;
     StreamList mStreams;
 
+    // Receives HAL notifications and routes them to the NotificationListener
+    static void notificationCallback(int32_t msg_type,
+            int32_t ext1,
+            int32_t ext2,
+            int32_t ext3,
+            void *user);
+
 }; // class Camera2Device
 
 }; // namespace android