Revert "Tie vr flinger to persistent vr mode"

This reverts commit f43d13e4e35ae7d3cdafc4b97c819669d42cef78.

Change-Id: Ib67db8e51b7ea2dbbe6faccce36962bf5b44a6e2
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index c87a8d9..a6ea750 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -53,6 +53,7 @@
     LOCAL_CFLAGS += -DUSE_HWC2
     LOCAL_SRC_FILES += \
         SurfaceFlinger.cpp \
+        VrStateCallbacks.cpp \
         DisplayHardware/HWComposer.cpp
     ifeq ($(TARGET_USES_HWC2ON1ADAPTER), true)
         LOCAL_CFLAGS += -DBYPASS_IHWC
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0aaab0c..06dd903 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -73,6 +73,7 @@
 #include "LayerDim.h"
 #include "MonitoredProducer.h"
 #include "SurfaceFlinger.h"
+#include "VrStateCallbacks.h"
 
 #include "DisplayHardware/FramebufferSurface.h"
 #include "DisplayHardware/HWComposer.h"
@@ -117,7 +118,6 @@
 bool SurfaceFlinger::useHwcForRgbToYuv;
 uint64_t SurfaceFlinger::maxVirtualDisplaySize;
 bool SurfaceFlinger::hasSyncFramework;
-bool SurfaceFlinger::useVrFlinger;
 
 SurfaceFlinger::SurfaceFlinger()
     :   BnSurfaceComposer(),
@@ -136,6 +136,7 @@
         mVisibleRegionsDirty(false),
         mGeometryInvalid(false),
         mAnimCompositionPending(false),
+        mVrModeSupported(0),
         mDebugRegion(0),
         mDebugDDMS(0),
         mDebugDisableHWC(0),
@@ -155,8 +156,10 @@
         mFrameBuckets(),
         mTotalTime(0),
         mLastSwapTime(0),
-        mNumLayers(0),
-        mVrFlingerRequestsDisplay(false)
+        mNumLayers(0)
+#ifdef USE_HWC2
+        ,mEnterVrMode(false)
+#endif
 {
     ALOGI("SurfaceFlinger is starting");
 
@@ -181,13 +184,13 @@
     maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
 
-    // Vr flinger is only enabled on Daydream ready devices.
-    useVrFlinger = getBool< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::useVrFlinger>(false);
-
     // debugging stuff...
     char value[PROPERTY_VALUE_MAX];
 
+    // TODO (urbanus): remove once b/35319396 is fixed.
+    property_get("ro.boot.vr", value, "0");
+    mVrModeSupported = atoi(value);
+
     property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
     mGpuToCpuSupported = !atoi(value);
 
@@ -228,6 +231,14 @@
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglTerminate(display);
+
+    if (mVrStateCallbacks.get()) {
+        sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
+            defaultServiceManager()->checkService(String16("vrmanager")));
+        if (vrManagerService.get()) {
+            vrManagerService->unregisterListener(mVrStateCallbacks);
+        }
+    }
 }
 
 void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
@@ -354,10 +365,6 @@
         window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
     }
 
-    if (mVrFlinger) {
-      mVrFlinger->OnBootFinished();
-    }
-
     // stop boot animation
     // formerly we would just kill the process, but we now ask it to exit so it
     // can choose where to stop the animation.
@@ -366,6 +373,13 @@
     const int LOGTAG_SF_STOP_BOOTANIM = 60110;
     LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
                    ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
+
+    sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
+        defaultServiceManager()->checkService(String16("vrmanager")));
+    if (vrManagerService.get()) {
+        mVrStateCallbacks = new VrStateCallbacks(*this);
+        vrManagerService->registerListener(mVrStateCallbacks);
+    }
 }
 
 void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
@@ -561,26 +575,13 @@
     // Drop the state lock while we initialize the hardware composer. We drop
     // the lock because on creation, it will call back into SurfaceFlinger to
     // initialize the primary display.
-    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
-        "Starting with vr flinger active is not currently supported.");
+    LOG_ALWAYS_FATAL_IF(mEnterVrMode, "Starting in vr mode is not currently supported.");
     mRealHwc = new HWComposer(false);
     mHwc = mRealHwc;
     mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
 
     Mutex::Autolock _l(mStateLock);
 
-    if (useVrFlinger) {
-        auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
-            mVrFlingerRequestsDisplay = requestDisplay;
-            signalTransaction();
-        };
-        mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
-                                            vrFlingerRequestDisplayCallback);
-        if (!mVrFlinger) {
-            ALOGE("Failed to start vrflinger");
-        }
-    }
-
     // retrieve the EGL context that was selected/created
     mEGLContext = mRenderEngine->getEGLContext();
 
@@ -1212,17 +1213,14 @@
     // transition.
     mDrawingState.displays.clear();
     mDisplays.clear();
-    initializeDisplays();
 }
 
-void SurfaceFlinger::updateVrFlinger() {
-    if (!mVrFlinger)
-        return;
-    bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
-    if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
+void SurfaceFlinger::updateVrMode() {
+    bool enteringVrMode = mEnterVrMode;
+    if (enteringVrMode == mHwc->isUsingVrComposer()) {
         return;
     }
-    if (vrFlingerRequestsDisplay && !mVrHwc) {
+    if (enteringVrMode && !mVrHwc) {
         // Construct new HWComposer without holding any locks.
         mVrHwc = new HWComposer(true);
         ALOGV("Vr HWC created");
@@ -1230,13 +1228,25 @@
     {
         Mutex::Autolock _l(mStateLock);
 
-        if (vrFlingerRequestsDisplay) {
+        if (enteringVrMode) {
+            // Start vrflinger thread, if it hasn't been started already.
+            if (!mVrFlinger) {
+                mVrFlinger = std::make_unique<dvr::VrFlinger>();
+                int err = mVrFlinger->Run(mHwc->getComposer());
+                if (err != NO_ERROR) {
+                    ALOGE("Failed to run vrflinger: %s (%d)", strerror(-err), err);
+                    mVrFlinger.reset();
+                    mEnterVrMode = false;
+                    return;
+                }
+            }
+
             resetHwc();
 
             mHwc = mVrHwc;
-            mVrFlinger->GrantDisplayOwnership();
+            mVrFlinger->EnterVrMode();
         } else {
-            mVrFlinger->SeizeDisplayOwnership();
+            mVrFlinger->ExitVrMode();
 
             resetHwc();
 
@@ -1258,6 +1268,12 @@
     ATRACE_CALL();
     switch (what) {
         case MessageQueue::INVALIDATE: {
+            // TODO(eieio): Tied to a conditional until SELinux issues
+            // are resolved.
+            if (mVrModeSupported) {
+                updateVrMode();
+            }
+
             bool frameMissed = !mHadClientComposition &&
                     mPreviousPresentFence != Fence::NO_FENCE &&
                     (mPreviousPresentFence->getSignalTime() ==
@@ -1269,11 +1285,6 @@
                 break;
             }
 
-            // Now that we're going to make it to the handleMessageTransaction()
-            // call below it's safe to call updateVrFlinger(), which will
-            // potentially trigger a display handoff.
-            updateVrFlinger();
-
             bool refreshNeeded = handleMessageTransaction();
             refreshNeeded |= handleMessageInvalidate();
             refreshNeeded |= mRepaintEverything;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e3637f5..921ecf6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -84,6 +84,7 @@
 class EventControlThread;
 class VSyncSource;
 class InjectVSyncSource;
+class VrStateCallbacks;
 
 namespace dvr {
 class VrFlinger;
@@ -210,6 +211,7 @@
     friend class EventThread;
     friend class Layer;
     friend class MonitoredProducer;
+    friend class VrStateCallbacks;
 
     // This value is specified in number of frames.  Log frame stats at most
     // every half hour.
@@ -530,8 +532,9 @@
     void clearHwcLayers(const LayerVector& layers);
     void resetHwc();
 
-    // Check to see if we should handoff to vr flinger.
-    void updateVrFlinger();
+    // Check to see if we should change to or from vr mode, and if so, perform
+    // the handoff.
+    void updateVrMode();
 #endif
 
     /* ------------------------------------------------------------------------
@@ -601,6 +604,7 @@
     DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;
 
     // don't use a lock for these, we don't care
+    int mVrModeSupported;
     int mDebugRegion;
     int mDebugDDMS;
     int mDebugDisableHWC;
@@ -697,8 +701,9 @@
     status_t CheckTransactCodeCredentials(uint32_t code);
 
 #ifdef USE_HWC2
-    std::atomic<bool> mVrFlingerRequestsDisplay;
-    static bool useVrFlinger;
+    sp<VrStateCallbacks> mVrStateCallbacks;
+
+    std::atomic<bool> mEnterVrMode;
 #endif
     };
 }; // namespace android
diff --git a/services/surfaceflinger/VrStateCallbacks.cpp b/services/surfaceflinger/VrStateCallbacks.cpp
new file mode 100644
index 0000000..a924def
--- /dev/null
+++ b/services/surfaceflinger/VrStateCallbacks.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VrStateCallbacks.h"
+#include "SurfaceFlinger.h"
+
+namespace android {
+
+VrStateCallbacks::VrStateCallbacks(SurfaceFlinger& flinger)
+    : mFlinger(flinger) {}
+
+void VrStateCallbacks::onVrStateChanged(bool enabled) {
+    mFlinger.mEnterVrMode = enabled;
+    mFlinger.signalTransaction();
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/VrStateCallbacks.h b/services/surfaceflinger/VrStateCallbacks.h
new file mode 100644
index 0000000..4e655d3
--- /dev/null
+++ b/services/surfaceflinger/VrStateCallbacks.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VR_STATE_CALLBACKS_H
+#define ANDROID_VR_STATE_CALLBACKS_H
+
+#include <vr/vr_manager/vr_manager.h>
+
+namespace android {
+
+class SurfaceFlinger;
+
+class VrStateCallbacks : public BnVrStateCallbacks {
+public:
+    VrStateCallbacks(SurfaceFlinger& flinger);
+    void onVrStateChanged(bool enabled) override;
+
+private:
+    SurfaceFlinger& mFlinger;
+};
+
+} // namespace android
+
+#endif // ANDROID_VR_STATE_CALLBACKS_H