VR: Move VR HWC DVR API to libdvr

Moved VR HWC API into a common API library.

Bug: 36050795
Test: Compiled
Change-Id: I1af32f4dedb7a6d4bb77a18d3c48cfbc8ea00a66
(cherry picked from commit 3d3fb3960f9c3956074496fd7fa1beb230ac1043)
diff --git a/libs/vr/libdvr/Android.mk b/libs/vr/libdvr/Android.mk
index 5449cb5..3c6934b 100644
--- a/libs/vr/libdvr/Android.mk
+++ b/libs/vr/libdvr/Android.mk
@@ -33,6 +33,7 @@
     dvr_api.cpp \
     dvr_buffer.cpp \
     dvr_buffer_queue.cpp \
+    dvr_hardware_composer_client.cpp \
     dvr_surface.cpp \
     vsync_client_api.cpp \
 
@@ -42,12 +43,15 @@
     libdisplay \
     libvrsensor \
     libvirtualtouchpadclient \
+    libvr_hwc-impl \
+    libvr_hwc-binder \
 
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.graphics.bufferqueue@1.0 \
     android.hidl.token@1.0-utils \
     libandroid_runtime \
     libbase \
+    libnativewindow \
 
 include $(BUILD_STATIC_LIBRARY)
 
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index f464411..f786c29 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -11,6 +11,7 @@
 
 // Headers not yet moved into libdvr.
 // TODO(jwcai) Move these once their callers are moved into Google3.
+#include <dvr/dvr_hardware_composer_client.h>
 #include <dvr/pose_client.h>
 #include <dvr/virtual_touchpad_client.h>
 
@@ -100,6 +101,26 @@
     dvr_api->virtual_touchpad_touch = dvrVirtualTouchpadTouch;
     dvr_api->virtual_touchpad_button_state = dvrVirtualTouchpadButtonState;
 
+    // dvr_hardware_composer_client.h
+    dvr_api->hwc_client_create = dvrHwcClientCreate;
+    dvr_api->hwc_client_destroy = dvrHwcClientDestroy;
+    dvr_api->hwc_frame_destroy = dvrHwcFrameDestroy;
+    dvr_api->hwc_frame_get_display_id = dvrHwcFrameGetDisplayId;
+    dvr_api->hwc_frame_get_display_width = dvrHwcFrameGetDisplayWidth;
+    dvr_api->hwc_frame_get_display_height = dvrHwcFrameGetDisplayHeight;
+    dvr_api->hwc_frame_get_layer_count = dvrHwcFrameGetLayerCount;
+    dvr_api->hwc_frame_get_layer_id = dvrHwcFrameGetLayerId;
+    dvr_api->hwc_frame_get_layer_buffer = dvrHwcFrameGetLayerBuffer;
+    dvr_api->hwc_frame_get_layer_fence = dvrHwcFrameGetLayerFence;
+    dvr_api->hwc_frame_get_layer_display_frame =
+        dvrHwcFrameGetLayerDisplayFrame;
+    dvr_api->hwc_frame_get_layer_crop = dvrHwcFrameGetLayerCrop;
+    dvr_api->hwc_frame_get_layer_blend_mode = dvrHwcFrameGetLayerBlendMode;
+    dvr_api->hwc_frame_get_layer_alpha = dvrHwcFrameGetLayerAlpha;
+    dvr_api->hwc_frame_get_layer_type = dvrHwcFrameGetLayerType;
+    dvr_api->hwc_frame_get_layer_application_id =
+        dvrHwcFrameGetLayerApplicationId;
+
     return 0;
   }
   return -EINVAL;
diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
new file mode 100644
index 0000000..e5665e1
--- /dev/null
+++ b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
@@ -0,0 +1,156 @@
+#include "include/dvr/dvr_hardware_composer_client.h"
+
+#include <android/dvr/IVrComposer.h>
+#include <android/dvr/BnVrComposerCallback.h>
+#include <android/hardware_buffer.h>
+#include <binder/IServiceManager.h>
+#include <private/android/AHardwareBufferHelpers.h>
+
+#include <memory>
+
+struct DvrHwcFrame {
+  android::dvr::ComposerView::Frame frame;
+};
+
+namespace {
+
+class HwcCallback : public android::dvr::BnVrComposerCallback {
+ public:
+  explicit HwcCallback(DvrHwcOnFrameCallback callback,
+                       void* client_state);
+  ~HwcCallback() override;
+
+  std::unique_ptr<DvrHwcFrame> DequeueFrame();
+
+ private:
+  // android::dvr::BnVrComposerCallback:
+  android::binder::Status onNewFrame(
+      const android::dvr::ParcelableComposerFrame& frame,
+      android::dvr::ParcelableUniqueFd* fence) override;
+
+  DvrHwcOnFrameCallback callback_;
+  void* client_state_;
+
+  HwcCallback(const HwcCallback&) = delete;
+  void operator=(const HwcCallback&) = delete;
+};
+
+HwcCallback::HwcCallback(DvrHwcOnFrameCallback callback, void* client_state)
+    : callback_(callback), client_state_(client_state) {}
+
+HwcCallback::~HwcCallback() {}
+
+android::binder::Status HwcCallback::onNewFrame(
+    const android::dvr::ParcelableComposerFrame& frame,
+    android::dvr::ParcelableUniqueFd* fence) {
+  std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
+  dvr_frame->frame = frame.frame();
+
+  fence->set_fence(android::base::unique_fd(callback_(client_state_,
+                                                      dvr_frame.release())));
+  return android::binder::Status::ok();
+}
+
+}  // namespace
+
+struct DvrHwcClient {
+  android::sp<android::dvr::IVrComposer> composer;
+  android::sp<HwcCallback> callback;
+};
+
+DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
+  std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
+
+  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+  client->composer = android::interface_cast<android::dvr::IVrComposer>(
+      sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
+  if (!client->composer.get())
+    return nullptr;
+
+  client->callback = new HwcCallback(callback, data);
+  android::binder::Status status = client->composer->registerObserver(
+      client->callback);
+  if (!status.isOk())
+    return nullptr;
+
+  return client.release();
+}
+
+void dvrHwcClientDestroy(DvrHwcClient* client) {
+  delete client;
+}
+
+void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
+  delete frame;
+}
+
+Display dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
+  return frame->frame.display_id;
+}
+
+int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
+  return frame->frame.display_width;
+}
+
+int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
+  return frame->frame.display_height;
+}
+
+bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
+  return frame->frame.removed;
+}
+
+size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
+  return frame->frame.layers.size();
+}
+
+Layer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].id;
+}
+
+AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
+                                           size_t layer_index) {
+  AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
+      frame->frame.layers[layer_index].buffer.get());
+  AHardwareBuffer_acquire(buffer);
+  return buffer;
+}
+
+int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].fence->dup();
+}
+
+Recti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame, size_t layer_index) {
+  return Recti{
+    frame->frame.layers[layer_index].display_frame.left,
+    frame->frame.layers[layer_index].display_frame.top,
+    frame->frame.layers[layer_index].display_frame.right,
+    frame->frame.layers[layer_index].display_frame.bottom,
+  };
+}
+
+Rectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
+  return Rectf{
+    frame->frame.layers[layer_index].crop.left,
+    frame->frame.layers[layer_index].crop.top,
+    frame->frame.layers[layer_index].crop.right,
+    frame->frame.layers[layer_index].crop.bottom,
+  };
+}
+
+BlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame, size_t layer_index) {
+  return static_cast<BlendMode>(frame->frame.layers[layer_index].blend_mode);
+}
+
+float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].alpha;
+}
+
+uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].type;
+}
+
+uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
+                                          size_t layer_index) {
+  return frame->frame.layers[layer_index].app_id;
+}
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index d840b6c..053382f 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -5,6 +5,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <dvr/dvr_hardware_composer_defs.h>
 #include <jni.h>
 
 #ifdef __cplusplus
@@ -144,6 +145,37 @@
 typedef int (*DvrVirtualTouchpadButtonStatePtr)(DvrVirtualTouchpad* client,
                                                 int touchpad, int buttons);
 
+// dvr_hardware_composer_client.h
+typedef struct DvrHwcClient DvrHwcClient;
+typedef struct DvrHwcFrame DvrHwcFrame;
+typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
+typedef DvrHwcClient* (*DvrHwcClientCreatePtr)(DvrHwcOnFrameCallback callback,
+                                               void* client_state);
+typedef void (*DvrHwcClientDestroyPtr)(DvrHwcClient* client);
+typedef void (*DvrHwcFrameDestroyPtr)(DvrHwcFrame* frame);
+typedef Display (*DvrHwcFrameGetDisplayIdPtr)(DvrHwcFrame* frame);
+typedef int32_t (*DvrHwcFrameGetDisplayWidthPtr)(DvrHwcFrame* frame);
+typedef int32_t (*DvrHwcFrameGetDisplayHeightPtr)(DvrHwcFrame* frame);
+typedef bool (*DvrHwcFrameGetDisplayRemovedPtr)(DvrHwcFrame* frame);
+typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
+typedef Layer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame, size_t layer_index);
+typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
+                                                         size_t layer_index);
+typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
+                                           size_t layer_index);
+typedef Recti (*DvrHwcFrameGetLayerDisplayFramePtr)(DvrHwcFrame* frame,
+                                                    size_t layer_index);
+typedef Rectf (*DvrHwcFrameGetLayerCropPtr)(DvrHwcFrame* frame,
+                                            size_t layer_index);
+typedef BlendMode (*DvrHwcFrameGetLayerBlendModePtr)(DvrHwcFrame* frame,
+                                                     size_t layer_index);
+typedef float (*DvrHwcFrameGetLayerAlphaPtr)(DvrHwcFrame* frame,
+                                             size_t layer_index);
+typedef uint32_t (*DvrHwcFrameGetLayerTypePtr)(DvrHwcFrame* frame,
+                                               size_t layer_index);
+typedef uint32_t (*DvrHwcFrameGetLayerApplicationIdPtr)(DvrHwcFrame* frame,
+                                                        size_t layer_index);
+
 struct DvrApi_v1 {
   // Display manager client
   DvrDisplayManagerClientCreatePtr display_manager_client_create;
@@ -220,6 +252,25 @@
   DvrVirtualTouchpadDetachPtr virtual_touchpad_detach;
   DvrVirtualTouchpadTouchPtr virtual_touchpad_touch;
   DvrVirtualTouchpadButtonStatePtr virtual_touchpad_button_state;
+
+  // VR HWComposer client
+  DvrHwcClientCreatePtr hwc_client_create;
+  DvrHwcClientDestroyPtr hwc_client_destroy;
+  DvrHwcFrameDestroyPtr hwc_frame_destroy;
+  DvrHwcFrameGetDisplayIdPtr hwc_frame_get_display_id;
+  DvrHwcFrameGetDisplayWidthPtr hwc_frame_get_display_width;
+  DvrHwcFrameGetDisplayHeightPtr hwc_frame_get_display_height;
+  DvrHwcFrameGetDisplayRemovedPtr hwc_frame_get_display_removed;
+  DvrHwcFrameGetLayerCountPtr hwc_frame_get_layer_count;
+  DvrHwcFrameGetLayerIdPtr hwc_frame_get_layer_id;
+  DvrHwcFrameGetLayerBufferPtr hwc_frame_get_layer_buffer;
+  DvrHwcFrameGetLayerFencePtr hwc_frame_get_layer_fence;
+  DvrHwcFrameGetLayerDisplayFramePtr hwc_frame_get_layer_display_frame;
+  DvrHwcFrameGetLayerCropPtr hwc_frame_get_layer_crop;
+  DvrHwcFrameGetLayerBlendModePtr hwc_frame_get_layer_blend_mode;
+  DvrHwcFrameGetLayerAlphaPtr hwc_frame_get_layer_alpha;
+  DvrHwcFrameGetLayerTypePtr hwc_frame_get_layer_type;
+  DvrHwcFrameGetLayerApplicationIdPtr hwc_frame_get_layer_application_id;
 };
 
 int dvrGetApi(void* api, size_t struct_size, int version);
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
new file mode 100644
index 0000000..692864d
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
@@ -0,0 +1,78 @@
+#ifndef ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
+#define ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
+
+#include <dvr/dvr_hardware_composer_defs.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct AHardwareBuffer AHardwareBuffer;
+typedef struct DvrHwcClient DvrHwcClient;
+typedef struct DvrHwcFrame DvrHwcFrame;
+
+// Called when a new frame has arrived.
+//
+// @param client_state Pointer to client state passed in |dvrHwcCreateClient()|.
+// @param frame New frame. Owned by the client.
+// @return fence FD for the release of the last frame.
+typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
+
+// @param callback Called when a new frame is available.
+// @param client_state Pointer to client state passed back in the callback.
+DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback,
+                                 void* client_state);
+
+void dvrHwcClientDestroy(DvrHwcClient* client);
+
+// Called to free the frame information.
+void dvrHwcFrameDestroy(DvrHwcFrame* frame);
+
+Display dvrHwcFrameGetDisplayId(DvrHwcFrame* frame);
+
+int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame);
+
+int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame);
+
+// @return True if the display has been removed. In this case the current frame
+// does not contain any valid layers to display. It is a signal to clean up any
+// display related state.
+bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame);
+
+// @return Number of layers in the frame.
+size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame);
+
+Layer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index);
+
+// Return the graphic buffer associated with the layer at |layer_index| in
+// |frame|.
+//
+// @return Graphic buffer. Caller owns the buffer and is responsible for freeing
+// it. (see AHardwareBuffer_release())
+AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
+                                           size_t layer_index);
+
+// Returns the fence FD for the layer at index |layer_index| in |frame|.
+//
+// @return Fence FD. Caller owns the FD and is responsible for closing it.
+int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index);
+
+Recti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame, size_t layer_index);
+
+Rectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index);
+
+BlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame, size_t layer_index);
+
+float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
+                                          size_t layer_index);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_defs.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_defs.h
new file mode 100644
index 0000000..546ed7b
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_defs.h
@@ -0,0 +1,50 @@
+#ifndef ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
+#define ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// NOTE: These definitions must match the ones in
+// //hardware/libhardware/include/hardware/hwcomposer2.h. They are used by the
+// client side which does not have access to hwc2 headers.
+enum BlendMode {
+  BLEND_MODE_INVALID = 0,
+  BLEND_MODE_NONE = 1,
+  BLEND_MODE_PREMULTIPLIED = 2,
+  BLEND_MODE_COVERAGE = 3,
+};
+
+enum Composition {
+  COMPOSITION_INVALID = 0,
+  COMPOSITION_CLIENT = 1,
+  COMPOSITION_DEVICE = 2,
+  COMPOSITION_SOLID_COLOR = 3,
+  COMPOSITION_CURSOR = 4,
+  COMPOSITION_SIDEBAND = 5,
+};
+
+typedef uint64_t Display;
+typedef uint64_t Layer;
+
+struct Recti {
+  int32_t left;
+  int32_t top;
+  int32_t right;
+  int32_t bottom;
+};
+
+struct Rectf {
+  float left;
+  float top;
+  float right;
+  float bottom;
+};
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // ANDROID_DVR_HARDWARE_COMPOSER_DEFS_H