Ensure display metrics on display service creation

This fixes a potential race condition where a VR app could request the
display metrics from the VR display service before it actually queries
them from the HWC.

Bug: None
Test: Compiled and ran Vr app.
Change-Id: Ie95b7f5a8ef2e286c7b2994ca94fd87214567e24
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index 5309acf..bb70c5c 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -25,7 +25,13 @@
 
 DisplayService::DisplayService(Hwc2::Composer* hidl)
     : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
-      hardware_composer_(hidl) {}
+      hardware_composer_(hidl) {
+  hardware_composer_.Initialize();
+}
+
+bool DisplayService::IsInitialized() const {
+  return BASE::IsInitialized() && hardware_composer_.IsInitialized();
+}
 
 std::string DisplayService::DumpState(size_t max_length) {
   std::vector<char> buffer(max_length);
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index 5de4f1d..b207e4d 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -23,6 +23,7 @@
 // DisplayService implements the displayd display service over ServiceFS.
 class DisplayService : public pdx::ServiceBase<DisplayService> {
  public:
+  bool IsInitialized() const override;
   std::string DumpState(size_t max_length) override;
 
   void OnChannelClose(pdx::Message& message,
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index e6ed665..f801d9b 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -100,7 +100,8 @@
 }
 
 HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
-    : hwc2_hidl_(hwc2_hidl),
+    : initialized_(false),
+      hwc2_hidl_(hwc2_hidl),
       display_transform_(HWC_TRANSFORM_NONE),
       display_surfaces_updated_(false),
       hardware_layers_need_update_(false),
@@ -126,6 +127,51 @@
   Suspend();
 }
 
+bool HardwareComposer::Initialize() {
+  if (initialized_) {
+    ALOGE("HardwareComposer::Initialize: already initialized.");
+    return false;
+  }
+
+  int32_t ret = HWC2_ERROR_NONE;
+
+  Hwc2::Config config;
+  ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
+
+  if (ret != HWC2_ERROR_NONE) {
+    ALOGE("HardwareComposer: Failed to get current display config : %d",
+          config);
+    return false;
+  }
+
+  ret =
+      GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
+
+  if (ret != HWC2_ERROR_NONE) {
+    ALOGE(
+        "HardwareComposer: Failed to get display attributes for current "
+        "configuration : %d",
+        ret);
+    return false;
+  }
+
+  ALOGI(
+      "HardwareComposer: primary display attributes: width=%d height=%d "
+      "vsync_period_ns=%d DPI=%dx%d",
+      native_display_metrics_.width, native_display_metrics_.height,
+      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
+      native_display_metrics_.dpi.y);
+
+  // Set the display metrics but never use rotation to avoid the long latency of
+  // rotation processing in hwc.
+  display_transform_ = HWC_TRANSFORM_NONE;
+  display_metrics_ = native_display_metrics_;
+
+  initialized_ = true;
+
+  return initialized_;
+}
+
 bool HardwareComposer::Resume() {
   std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
   if (post_thread_state_ == PostThreadState::kRunning) {
@@ -136,62 +182,6 @@
 
   int32_t ret = HWC2_ERROR_NONE;
 
-  static const uint32_t attributes[] = {
-      HWC_DISPLAY_WIDTH, HWC_DISPLAY_HEIGHT, HWC_DISPLAY_VSYNC_PERIOD,
-      HWC_DISPLAY_DPI_X, HWC_DISPLAY_DPI_Y,  HWC_DISPLAY_NO_ATTRIBUTE,
-  };
-
-  std::vector<Hwc2::Config> configs;
-  ret = (int32_t)hwc2_hidl_->getDisplayConfigs(HWC_DISPLAY_PRIMARY, &configs);
-
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Failed to get display configs");
-    return false;
-  }
-
-  uint32_t num_configs = configs.size();
-
-  for (size_t i = 0; i < num_configs; i++) {
-    ALOGI("HardwareComposer: cfg[%zd/%zd] = 0x%08x", i, num_configs,
-          configs[i]);
-
-    ret = GetDisplayMetrics(HWC_DISPLAY_PRIMARY, configs[i],
-                            &native_display_metrics_);
-
-    if (ret != HWC2_ERROR_NONE) {
-      ALOGE("HardwareComposer: Failed to get display attributes %d", ret);
-      continue;
-    } else {
-      ret =
-          (int32_t)hwc2_hidl_->setActiveConfig(HWC_DISPLAY_PRIMARY, configs[i]);
-
-      if (ret != HWC2_ERROR_NONE) {
-        ALOGE("HardwareComposer: Failed to set display configuration; ret=%d",
-              ret);
-        continue;
-      }
-
-      break;
-    }
-  }
-
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Could not set a valid display configuration.");
-    return false;
-  }
-
-  // Set the display metrics but never use rotation to avoid the long latency of
-  // rotation processing in hwc.
-  display_transform_ = HWC_TRANSFORM_NONE;
-  display_metrics_ = native_display_metrics_;
-
-  ALOGI(
-      "HardwareComposer: primary display attributes: width=%d height=%d "
-      "vsync_period_ns=%d DPI=%dx%d",
-      native_display_metrics_.width, native_display_metrics_.height,
-      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
-      native_display_metrics_.dpi.y);
-
   // Always turn off vsync when we start.
   EnableVsync(false);
 
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index b6aa807..e2a8b90 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -189,6 +189,10 @@
   HardwareComposer(Hwc2::Composer* hidl);
   ~HardwareComposer();
 
+  bool Initialize();
+
+  bool IsInitialized() const { return initialized_; }
+
   bool Suspend();
   bool Resume();
 
@@ -303,6 +307,8 @@
 
   void HandlePendingScreenshots();
 
+  bool initialized_;
+
   // Hardware composer HAL device.
   std::unique_ptr<Hwc2::Composer> hwc2_hidl_;
   sp<ComposerCallback> callbacks_;