Camera: Add HAL module init method.

For use by Camera HAL libraries to perform one-time initialization
steps after the library is loaded.

Bug: 20016050
Change-Id: Ia01ae0eafcadece9124ac2cfcc3b1c3939352843
diff --git a/include/hardware/camera_common.h b/include/hardware/camera_common.h
index c2d4536..fe3b7d7 100644
--- a/include/hardware/camera_common.h
+++ b/include/hardware/camera_common.h
@@ -113,6 +113,10 @@
  *    To specify valid combinations of devices, the resource_cost and conflicting_devices
  *    fields should always be set in the camera_info structure returned by the
  *    get_camera_info call.
+ *
+ * 4. Module initialization method. This will be called by the camera service
+ *    right after the HAL module is loaded, to allow for one-time initialization
+ *    of the HAL. It is called before any other module methods are invoked.
  */
 
 /**
@@ -868,8 +872,39 @@
      */
     int (*set_torch_mode)(const char* camera_id, bool enabled);
 
+    /**
+     * init:
+     *
+     * This method is called by the camera service before any other methods
+     * are invoked, right after the camera HAL library has been successfully
+     * loaded. It may be left as NULL by the HAL module, if no initialization
+     * in needed.
+     *
+     * It can be used by HAL implementations to perform initialization and
+     * other one-time operations.
+     *
+     * Version information (based on camera_module_t.common.module_api_version):
+     *
+     * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3:
+     *   Not provided by HAL module. Framework will not call this function.
+     *
+     * CAMERA_MODULE_API_VERSION_2_4:
+     *   If not NULL, will always be called by the framework once after the HAL
+     *   module is loaded, before any other HAL module method is called.
+     *
+     * Return values:
+     *
+     * 0:           On a successful operation.
+     *
+     * -ENODEV:     Initialization cannot be completed due to an internal
+     *              error. The HAL must be assumed to be in a nonfunctional
+     *              state.
+     *
+     */
+    int (*init)();
+
     /* reserved for future use */
-    void* reserved[6];
+    void* reserved[5];
 } camera_module_t;
 
 __END_DECLS
diff --git a/modules/camera/CameraHAL.cpp b/modules/camera/CameraHAL.cpp
index 06f308f..62ee6d4 100644
--- a/modules/camera/CameraHAL.cpp
+++ b/modules/camera/CameraHAL.cpp
@@ -186,6 +186,7 @@
     get_vendor_tag_ops    : get_vendor_tag_ops,
     open_legacy           : NULL,
     set_torch_mode        : NULL,
+    init                  : NULL,
     reserved              : {0},
 };
 } // extern "C"
diff --git a/modules/usbcamera/CameraHAL.cpp b/modules/usbcamera/CameraHAL.cpp
index 98111ef..652e937 100644
--- a/modules/usbcamera/CameraHAL.cpp
+++ b/modules/usbcamera/CameraHAL.cpp
@@ -147,6 +147,7 @@
     get_vendor_tag_ops    : NULL,
     open_legacy           : NULL,
     set_torch_mode        : NULL,
+    init                  : NULL,
     reserved              : {0},
 };
 } // extern "C"
diff --git a/tests/hardware/struct-offset.cpp b/tests/hardware/struct-offset.cpp
index d6ea073..10c0895 100644
--- a/tests/hardware/struct-offset.cpp
+++ b/tests/hardware/struct-offset.cpp
@@ -214,7 +214,8 @@
     CHECK_MEMBER_AT(camera_module_t, get_vendor_tag_ops, 140, 272);
     CHECK_MEMBER_AT(camera_module_t, open_legacy, 144, 280);
     CHECK_MEMBER_AT(camera_module_t, set_torch_mode, 148, 288);
-    CHECK_MEMBER_AT(camera_module_t, reserved, 152, 296);
+    CHECK_MEMBER_AT(camera_module_t, init, 152, 296);
+    CHECK_MEMBER_AT(camera_module_t, reserved, 156, 304);
 
     //Types defined in camera3.h
     CHECK_MEMBER_AT(camera3_device_ops_t, initialize, 0, 0);