Merge "Fix HIDL token passing mechanism for non-Treble paths."
diff --git a/libs/vr/libsensor/Android.mk b/libs/vr/libsensor/Android.mk
index 89abcb0..8c7ad43 100644
--- a/libs/vr/libsensor/Android.mk
+++ b/libs/vr/libsensor/Android.mk
@@ -32,7 +32,6 @@
 	libhardware \
 	liblog \
 	libutils \
-	libandroid \
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(sourceFiles)
diff --git a/services/vr/vr_window_manager/Android.mk b/services/vr/vr_window_manager/Android.mk
index e9552bc..706efe5 100644
--- a/services/vr/vr_window_manager/Android.mk
+++ b/services/vr/vr_window_manager/Android.mk
@@ -61,12 +61,12 @@
   libperformance \
   libpdx_default_transport \
   libcutils \
+  libvr_manager \
 
 shared_libs := \
   android.dvr.composer@1.0 \
   android.hardware.graphics.composer@2.1 \
   libvrhwc \
-  libandroid \
   libbase \
   libbinder \
   libinput \
diff --git a/services/vr/vr_window_manager/application.cpp b/services/vr/vr_window_manager/application.cpp
index 467e95e..dba797f 100644
--- a/services/vr/vr_window_manager/application.cpp
+++ b/services/vr/vr_window_manager/application.cpp
@@ -17,9 +17,16 @@
 namespace android {
 namespace dvr {
 
-Application::Application() {}
+Application::Application() {
+  vr_mode_listener_ = new VrModeListener(this);
+}
 
 Application::~Application() {
+  sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
+      defaultServiceManager()->getService(String16("vrmanager")));
+  if (vrManagerService.get()) {
+    vrManagerService->unregisterListener(vr_mode_listener_);
+  }
 }
 
 int Application::Initialize() {
@@ -29,6 +36,11 @@
   elbow_model_.Enable(ElbowModel::kDefaultNeckPosition, is_right_handed);
   last_frame_time_ = std::chrono::system_clock::now();
 
+  sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
+      defaultServiceManager()->getService(String16("vrmanager")));
+  if (vrManagerService.get()) {
+    vrManagerService->registerListener(vr_mode_listener_);
+  }
   return 0;
 }
 
@@ -274,6 +286,11 @@
 }
 
 void Application::SetVisibility(bool visible) {
+  if (visible && !initialized_) {
+    if (AllocateResources())
+      ALOGE("Failed to allocate resources");
+  }
+
   bool changed = is_visible_ != visible;
   if (changed) {
     is_visible_ = visible;
@@ -296,5 +313,10 @@
   wake_up_init_and_render_.notify_one();
 }
 
+void Application::VrModeListener::onVrStateChanged(bool enabled) {
+  if (!enabled)
+    app_->QueueTask(MainThreadTask::ExitingVrMode);
+}
+
 }  // namespace dvr
 }  // namespace android
diff --git a/services/vr/vr_window_manager/application.h b/services/vr/vr_window_manager/application.h
index c7aa4dd..2c60e0a 100644
--- a/services/vr/vr_window_manager/application.h
+++ b/services/vr/vr_window_manager/application.h
@@ -4,6 +4,7 @@
 #include <memory>
 #include <private/dvr/types.h>
 #include <stdint.h>
+#include <vr/vr_manager/vr_manager.h>
 
 #include <chrono>
 #include <mutex>
@@ -43,6 +44,16 @@
     Show,
   };
 
+  class VrModeListener : public BnVrStateCallbacks {
+   public:
+    VrModeListener(Application *app) : app_(app) {}
+    void onVrStateChanged(bool enabled) override;
+
+   private:
+    Application *app_;
+  };
+
+  sp<VrModeListener> vr_mode_listener_;
   virtual void OnDrawFrame() = 0;
   virtual void DrawEye(EyeType eye, const mat4& perspective,
                        const mat4& eye_matrix, const mat4& head_matrix) = 0;
diff --git a/services/vr/vr_window_manager/hwc_callback.h b/services/vr/vr_window_manager/hwc_callback.h
index bcfeb97..be56856 100644
--- a/services/vr/vr_window_manager/hwc_callback.h
+++ b/services/vr/vr_window_manager/hwc_callback.h
@@ -25,7 +25,8 @@
   struct HwcLayer {
     enum LayerType : uint32_t {
       // These are from frameworks/base/core/java/android/view/WindowManager.java
-      kUndefinedWindow = 0,
+      kSurfaceFlingerLayer = 0,
+      kUndefinedWindow = ~0U,
       kFirstApplicationWindow = 1,
       kLastApplicationWindow = 99,
       kFirstSubWindow = 1000,
@@ -42,6 +43,19 @@
         // Always skip the following layer types
       case kNavigationBar:
       case kStatusBar:
+      case kSurfaceFlingerLayer:
+      case kUndefinedWindow:
+        return true;
+      default:
+        return false;
+      }
+    }
+
+    // This is a layer that provides some other functionality, eg dim layer.
+    // We use this to determine the point at which layers are "on top".
+    bool is_extra_layer() const {
+      switch(type) {
+      case kSurfaceFlingerLayer:
       case kUndefinedWindow:
         return true;
       default:
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index 9d0aaad..6cbd88d 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -195,7 +195,8 @@
                                             uint32_t vr_app) {
   auto& layers = frame.layers();
 
-  // We assume the first two layers are the VR app.
+  // We assume the first two layers are the VR app. In the case of a 2D app,
+  // there will be the app + at least one system layer so this is still safe.
   if (layers.size() < kVRAppLayerCount)
     return ViewMode::Hidden;
 
@@ -203,19 +204,23 @@
       layers[1].appid != layers[0].appid) {
     if (layers[1].appid != layers[0].appid && layers[0].appid) {
       // This might be a 2D app.
+      // If a dim layer exists afterwards it is much more likely that this is
+      // actually an app launch artifact.
+      for (size_t i = 2; i < layers.size(); i++) {
+        if (layers[i].is_extra_layer())
+          return ViewMode::Hidden;
+      }
       return ViewMode::App;
     }
     return ViewMode::Hidden;
   }
 
-  // If a non-VR-app, non-skipped layer appears, show.
   size_t index = kVRAppLayerCount;
   // Now, find a dim layer if it exists.
   // If it does, ignore any layers behind it for visibility determination.
   for (size_t i = index; i < layers.size(); i++) {
-    if (layers[i].appid == 0) {
+    if (layers[i].appid == HwcCallback::HwcLayer::kSurfaceFlingerLayer) {
       index = i + 1;
-      break;
     }
   }
 
@@ -419,7 +424,6 @@
   // so give it a kick.
   if (visibility != ViewMode::Hidden &&
       current_frame_.visibility == ViewMode::Hidden) {
-    QueueTask(MainThreadTask::EnteringVrMode);
     QueueTask(MainThreadTask::Show);
   }