Second attempt at adding a singleton to region view classes

BUG: 3486191
Change-Id: I418b8536312381072e2303686d76ef1f09c9a874
diff --git a/Android.bp b/Android.bp
index 13d312a..128471a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -90,9 +90,7 @@
     srcs: [
         "common/vsoc/lib/compat.cpp",
         "common/vsoc/lib/audio_data_layout.cpp",
-        "common/vsoc/lib/audio_data_region_view.cpp",
         "common/vsoc/lib/e2e_test_region_layout.cpp",
-        "common/vsoc/lib/e2e_test_region_view.cpp",
         "common/vsoc/lib/fb_bcast_layout.cpp",
         "common/vsoc/lib/fb_bcast_region_view.cpp",
         "common/vsoc/lib/framebuffer_layout.cpp",
diff --git a/common/commands/socket_forward_proxy/main.cpp b/common/commands/socket_forward_proxy/main.cpp
index 0a51ed4..cec1b05 100644
--- a/common/commands/socket_forward_proxy/main.cpp
+++ b/common/commands/socket_forward_proxy/main.cpp
@@ -155,7 +155,7 @@
 }
 #endif
 
-std::shared_ptr<SocketForwardRegionView> GetShm() {
+SocketForwardRegionView* GetShm() {
   auto shm = SocketForwardRegionView::GetInstance(
 #ifdef CUTTLEFISH_HOST
       vsoc::GetDomain().c_str()
@@ -185,8 +185,8 @@
 
 #ifdef CUTTLEFISH_HOST
   CHECK_NE(FLAGS_port, 0u) << "Must specify --port flag";
-  host(shm.get(), FLAGS_port);
+  host(shm, FLAGS_port);
 #else
-  guest(shm.get());
+  guest(shm);
 #endif
 }
diff --git a/common/libs/wifi/packet_switch.h b/common/libs/wifi/packet_switch.h
index a693387..257ccd2 100644
--- a/common/libs/wifi/packet_switch.h
+++ b/common/libs/wifi/packet_switch.h
@@ -46,7 +46,7 @@
 
   std::unique_ptr<std::thread> shm_xchg_;
   std::unique_ptr<vsoc::RegionWorker> worker_;
-  std::shared_ptr<vsoc::wifi::WifiExchangeView> shm_wifi_;
+  vsoc::wifi::WifiExchangeView* shm_wifi_;
 
   PacketSwitch(const PacketSwitch&) = delete;
   PacketSwitch& operator=(const PacketSwitch&) = delete;
diff --git a/common/vsoc/lib/audio_data_region_view.cpp b/common/vsoc/lib/audio_data_region_view.cpp
deleted file mode 100644
index 063f7e5..0000000
--- a/common/vsoc/lib/audio_data_region_view.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2018 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 "common/vsoc/lib/audio_data_region_view.h"
-
-#include "common/vsoc/lib/circqueue_impl.h"
-
-#include <mutex>
-
-using vsoc::layout::audio_data::AudioDataLayout;
-
-namespace vsoc {
-namespace audio_data {
-
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<AudioDataRegionView> AudioDataRegionView::GetInstance(
-    const char* domain) {
-  return RegionView::GetInstanceImpl<AudioDataRegionView>(
-      [](std::shared_ptr<AudioDataRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<AudioDataRegionView> AudioDataRegionView::GetInstance() {
-  return RegionView::GetInstanceImpl<AudioDataRegionView>(
-      std::mem_fn(&AudioDataRegionView::Open));
-}
-#endif
-}  // namespace audio_data
-}  // namespace vsoc
diff --git a/common/vsoc/lib/audio_data_region_view.h b/common/vsoc/lib/audio_data_region_view.h
index 44d8dad..42d05df 100644
--- a/common/vsoc/lib/audio_data_region_view.h
+++ b/common/vsoc/lib/audio_data_region_view.h
@@ -26,17 +26,13 @@
 namespace audio_data {
 
 class AudioDataRegionView
-    : public vsoc::TypedRegionView<vsoc::layout::audio_data::AudioDataLayout> {
+    : public vsoc::TypedRegionView<
+        AudioDataRegionView,
+        vsoc::layout::audio_data::AudioDataLayout> {
 public:
     AudioDataRegionView() = default;
     AudioDataRegionView(const AudioDataRegionView &) = delete;
     AudioDataRegionView &operator=(const AudioDataRegionView &) = delete;
-
-#if defined(CUTTLEFISH_HOST)
-    static std::shared_ptr<AudioDataRegionView> GetInstance(const char *domain);
-#else
-    static std::shared_ptr<AudioDataRegionView> GetInstance();
-#endif
 };
 
 }  // namespace audio_data
diff --git a/common/vsoc/lib/e2e_test_region_view.cpp b/common/vsoc/lib/e2e_test_region_view.cpp
deleted file mode 100644
index 9bcebd9..0000000
--- a/common/vsoc/lib/e2e_test_region_view.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 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 "common/vsoc/lib/e2e_test_region_view.h"
-
-namespace vsoc {
-
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<E2EPrimaryRegionView> E2EPrimaryRegionView::GetInstance(
-    const char* domain) {
-  return vsoc::RegionView::GetInstanceImpl<E2EPrimaryRegionView>(
-      [](std::shared_ptr<E2EPrimaryRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<E2EPrimaryRegionView> E2EPrimaryRegionView::GetInstance() {
-  return vsoc::RegionView::GetInstanceImpl<E2EPrimaryRegionView>(
-      std::mem_fn(&E2EPrimaryRegionView::Open));
-}
-#endif
-
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<E2ESecondaryRegionView> E2ESecondaryRegionView::GetInstance(
-    const char* domain) {
-  return vsoc::RegionView::GetInstanceImpl<E2ESecondaryRegionView>(
-      [](std::shared_ptr<E2ESecondaryRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<E2ESecondaryRegionView> E2ESecondaryRegionView::GetInstance() {
-  return vsoc::RegionView::GetInstanceImpl<E2ESecondaryRegionView>(
-      std::mem_fn(&E2ESecondaryRegionView::Open));
-}
-#endif
-
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<E2EUnfindableRegionView> E2EUnfindableRegionView::GetInstance(
-    const char* domain) {
-  return vsoc::RegionView::GetInstanceImpl<E2EUnfindableRegionView>(
-      [](std::shared_ptr<E2EUnfindableRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<E2EUnfindableRegionView>
-E2EUnfindableRegionView::GetInstance() {
-  return vsoc::RegionView::GetInstanceImpl<E2EUnfindableRegionView>(
-      std::mem_fn(&E2EUnfindableRegionView::Open));
-}
-#endif
-
-}  // namespace vsoc
diff --git a/common/vsoc/lib/e2e_test_region_view.h b/common/vsoc/lib/e2e_test_region_view.h
index 965fce8..1ea6aef 100644
--- a/common/vsoc/lib/e2e_test_region_view.h
+++ b/common/vsoc/lib/e2e_test_region_view.h
@@ -23,7 +23,9 @@
 
 namespace vsoc {
 template <typename Layout>
-class E2ERegionView : public vsoc::TypedRegionView<Layout> {
+class E2ERegionView : public vsoc::TypedRegionView<
+                      E2ERegionView<Layout>,
+                      Layout> {
  public:
   const char* guest_string(size_t index) const {
     return const_cast<const char*>(this->data().data[index].guest_writable);
@@ -58,34 +60,13 @@
   }
 };
 
-class E2EPrimaryRegionView
-    : public vsoc::E2ERegionView<layout::e2e_test::E2EPrimaryTestRegionLayout> {
- public:
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<E2EPrimaryRegionView> GetInstance(const char* domain);
-#else
-  static std::shared_ptr<E2EPrimaryRegionView> GetInstance();
-#endif
-};
-class E2ESecondaryRegionView
-    : public vsoc::E2ERegionView<
-          layout::e2e_test::E2ESecondaryTestRegionLayout> {
- public:
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<E2ESecondaryRegionView> GetInstance(
-      const char* domain);
-#else
-  static std::shared_ptr<E2ESecondaryRegionView> GetInstance();
-#endif
-};
-class E2EUnfindableRegionView
-    : public vsoc::E2ERegionView<layout::e2e_test::E2EUnfindableRegionLayout> {
- public:
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<E2EUnfindableRegionView> GetInstance(
-      const char* domain);
-#else
-  static std::shared_ptr<E2EUnfindableRegionView> GetInstance();
-#endif
-};
-} // namespace vsoc
+using E2EPrimaryRegionView =
+  vsoc::E2ERegionView<layout::e2e_test::E2EPrimaryTestRegionLayout>;
+
+using E2ESecondaryRegionView =
+  vsoc::E2ERegionView<layout::e2e_test::E2ESecondaryTestRegionLayout>;
+
+using E2EUnfindableRegionView =
+  vsoc::E2ERegionView<layout::e2e_test::E2EUnfindableRegionLayout>;
+
+}  // namespace vsoc
diff --git a/common/vsoc/lib/fb_bcast_region_view.cpp b/common/vsoc/lib/fb_bcast_region_view.cpp
index 49f2756..e5e48d9 100644
--- a/common/vsoc/lib/fb_bcast_region_view.cpp
+++ b/common/vsoc/lib/fb_bcast_region_view.cpp
@@ -69,19 +69,3 @@
     return data()->frame_offset;
   }
 }
-
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<FBBroadcastRegionView> FBBroadcastRegionView::GetInstance(
-    const char* domain) {
-  return RegionView::GetInstanceImpl<FBBroadcastRegionView>(
-      [](std::shared_ptr<FBBroadcastRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<FBBroadcastRegionView> FBBroadcastRegionView::GetInstance() {
-  return RegionView::GetInstanceImpl<FBBroadcastRegionView>(
-      std::mem_fn(&FBBroadcastRegionView::Open));
-}
-#endif
diff --git a/common/vsoc/lib/fb_bcast_region_view.h b/common/vsoc/lib/fb_bcast_region_view.h
index b12c67b..3592ebb 100644
--- a/common/vsoc/lib/fb_bcast_region_view.h
+++ b/common/vsoc/lib/fb_bcast_region_view.h
@@ -33,6 +33,7 @@
 // composer.
 class FBBroadcastRegionView
     : public vsoc::TypedRegionView<
+          FBBroadcastRegionView,
           vsoc::layout::framebuffer::FBBroadcastLayout> {
  public:
   static int align(int input, int alignment = kAlignment) {
@@ -81,12 +82,6 @@
       uint32_t* last_seq_num,
       vsoc::layout::framebuffer::CompositionStats* stats = nullptr);
 
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<FBBroadcastRegionView> GetInstance(const char* domain);
-#else
-  static std::shared_ptr<FBBroadcastRegionView> GetInstance();
-#endif
-
   using Pixel = uint32_t;
   static constexpr int kSwiftShaderPadding = 4;
   static constexpr int kRedShift = 0;
diff --git a/common/vsoc/lib/framebuffer_region_view.h b/common/vsoc/lib/framebuffer_region_view.h
index 85267d2..41c46e0 100644
--- a/common/vsoc/lib/framebuffer_region_view.h
+++ b/common/vsoc/lib/framebuffer_region_view.h
@@ -30,25 +30,9 @@
  * gralloc buffers region.*/
 class FrameBufferRegionView
     : public vsoc::TypedRegionView<
+          FrameBufferRegionView,
           vsoc::layout::framebuffer::FrameBufferLayout> {
  public:
-
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<FrameBufferRegionView> GetInstance(
-      const char* domain) {
-    return RegionView::GetInstanceImpl<FrameBufferRegionView>(
-        [](std::shared_ptr<FrameBufferRegionView> region, const char* domain) {
-          return region->Open(domain);
-        },
-        domain);
-  }
-#else
-  static std::shared_ptr<FrameBufferRegionView> GetInstance() {
-    return RegionView::GetInstanceImpl<FrameBufferRegionView>(
-        std::mem_fn(&FrameBufferRegionView::Open));
-  }
-#endif
-
   size_t total_buffer_size() const;
   uint32_t first_buffer_offset() const;
   // Gets a pointer to an offset of the region.
diff --git a/common/vsoc/lib/input_events_region_view.cpp b/common/vsoc/lib/input_events_region_view.cpp
index fb07247..66bc697 100644
--- a/common/vsoc/lib/input_events_region_view.cpp
+++ b/common/vsoc/lib/input_events_region_view.cpp
@@ -96,20 +96,5 @@
   return ret / sizeof(InputEvent);
 }
 
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<InputEventsRegionView> InputEventsRegionView::GetInstance(
-    const char* domain) {
-  return RegionView::GetInstanceImpl<InputEventsRegionView>(
-      [](std::shared_ptr<InputEventsRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<InputEventsRegionView> InputEventsRegionView::GetInstance() {
-  return RegionView::GetInstanceImpl<InputEventsRegionView>(
-      std::mem_fn(&InputEventsRegionView::Open));
-}
-#endif
-}
-}
+}  // namespace input_events
+}  // namespace vsoc
diff --git a/common/vsoc/lib/input_events_region_view.h b/common/vsoc/lib/input_events_region_view.h
index 93a6ccb..3355631 100644
--- a/common/vsoc/lib/input_events_region_view.h
+++ b/common/vsoc/lib/input_events_region_view.h
@@ -32,6 +32,7 @@
 
 class InputEventsRegionView
     : public vsoc::TypedRegionView<
+          InputEventsRegionView,
           vsoc::layout::input_events::InputEventsLayout> {
  public:
   static const int kMaxEventsPerPacket;
@@ -51,11 +52,6 @@
   intptr_t GetKeyboardEventsOrWait(InputEvent* buffer, int max_event_count);
   intptr_t GetPowerButtonEventsOrWait(InputEvent* buffer, int max_event_count);
 
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<InputEventsRegionView> GetInstance(const char* domain);
-#else
-  static std::shared_ptr<InputEventsRegionView> GetInstance();
-#endif
 };
 }  // namespace input_events
 }  // namespace vsoc
diff --git a/common/vsoc/lib/region_view.h b/common/vsoc/lib/region_view.h
index efc1335..2838350 100644
--- a/common/vsoc/lib/region_view.h
+++ b/common/vsoc/lib/region_view.h
@@ -203,49 +203,6 @@
     return rval;
   }
 
-  // Implementation of the region singletons. This method cannot be called
-  // directly, but rather from static function in the concrete region views
-  // classes.
-  template <typename R>
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<R> GetInstanceImpl(
-      std::function<bool(std::shared_ptr<R>, const char*)> initializer,
-      const char* domain) {
-    static std::mutex mtx;
-    static std::map<std::string, std::shared_ptr<R>> instances;
-    if (!domain) {
-      return nullptr;
-    }
-    std::lock_guard<std::mutex> lock(mtx);
-    // Get a reference to the actual shared pointer that's stored in the map, if
-    // there wasn't one it will be default constructed pointing to nullptr.
-    std::shared_ptr<R>& instance = instances[domain];
-    if (!instance) {
-      // Update the referenced pointer with the address of the newly created
-      // region view.
-      instance.reset(new R());
-      if (!initializer(instance, domain)) {
-        instance.reset();
-      }
-    }
-    return instance;
-  }
-#else
-  static std::shared_ptr<R> GetInstanceImpl(
-      std::function<bool(std::shared_ptr<R>)> initializer) {
-    static std::mutex mtx;
-    static std::shared_ptr<R> instance;
-    std::lock_guard<std::mutex> lock(mtx);
-    if (!instance) {
-      instance.reset(new R());
-      if (!initializer(instance)) {
-        instance.reset();
-      }
-    }
-    return instance;
-  }
-#endif
-
   std::shared_ptr<RegionControl> control_;
   void* region_base_{};
 };
diff --git a/common/vsoc/lib/ril_region_view.cpp b/common/vsoc/lib/ril_region_view.cpp
index 366ca6d..ad19ac3 100644
--- a/common/vsoc/lib/ril_region_view.cpp
+++ b/common/vsoc/lib/ril_region_view.cpp
@@ -23,21 +23,6 @@
 namespace vsoc {
 namespace ril {
 
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<RilRegionView> RilRegionView::GetInstance(const char* domain) {
-  return RegionView::GetInstanceImpl<RilRegionView>(
-      [](std::shared_ptr<RilRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<RilRegionView> RilRegionView::GetInstance() {
-  return RegionView::GetInstanceImpl<RilRegionView>(
-      std::mem_fn(&RilRegionView::Open));
-}
-#endif
-
 const char* RilRegionView::address_and_prefix_length() const {
   static char buffer[sizeof(data().ipaddr) + 3]{};  // <ipaddr>/dd
   if (buffer[0] == '\0') {
diff --git a/common/vsoc/lib/ril_region_view.h b/common/vsoc/lib/ril_region_view.h
index dcd9e00..0f7fe84 100644
--- a/common/vsoc/lib/ril_region_view.h
+++ b/common/vsoc/lib/ril_region_view.h
@@ -23,15 +23,10 @@
 namespace vsoc {
 namespace ril {
 class RilRegionView
-    : public vsoc::TypedRegionView<vsoc::layout::ril::RilLayout> {
+    : public vsoc::TypedRegionView<
+        RilRegionView,
+        vsoc::layout::ril::RilLayout> {
  public:
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<RilRegionView> GetInstance(
-      const char* domain = nullptr);
-#else
-  static std::shared_ptr<RilRegionView> GetInstance();
-#endif
-
   // returns a string with '<ip>/<prefix_len>' like this: 192.168.99.2/30
   const char* address_and_prefix_length() const;
 };
diff --git a/common/vsoc/lib/socket_forward_region_view.cpp b/common/vsoc/lib/socket_forward_region_view.cpp
index cf95fa9..b56dde4 100644
--- a/common/vsoc/lib/socket_forward_region_view.cpp
+++ b/common/vsoc/lib/socket_forward_region_view.cpp
@@ -186,23 +186,6 @@
   return {-1, -1};
 }
 
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<SocketForwardRegionView> SocketForwardRegionView::GetInstance(
-    const char* domain) {
-  return RegionView::GetInstanceImpl<SocketForwardRegionView>(
-      [](std::shared_ptr<SocketForwardRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<SocketForwardRegionView> SocketForwardRegionView::GetInstance()
-{
-  return RegionView::GetInstanceImpl<SocketForwardRegionView>(
-      std::mem_fn(&SocketForwardRegionView::Open));
-}
-#endif
-
 #ifdef CUTTLEFISH_HOST
 SocketForwardRegionView::Connection SocketForwardRegionView::OpenConnection(
     int port) {
diff --git a/common/vsoc/lib/socket_forward_region_view.h b/common/vsoc/lib/socket_forward_region_view.h
index 0471a5f..1e4fe0d 100644
--- a/common/vsoc/lib/socket_forward_region_view.h
+++ b/common/vsoc/lib/socket_forward_region_view.h
@@ -30,7 +30,9 @@
 // Data sent will start with a uint32_t indicating the number of bytes being
 // sent, followed be the data itself
 class SocketForwardRegionView
-    : public TypedRegionView<layout::socket_forward::SocketForwardLayout> {
+    : public TypedRegionView<
+        SocketForwardRegionView,
+        layout::socket_forward::SocketForwardLayout> {
  private:
 #ifdef CUTTLEFISH_HOST
   int AcquireConnectionID(int port);
@@ -154,12 +156,6 @@
   SocketForwardRegionView(const SocketForwardRegionView&) = delete;
   SocketForwardRegionView& operator=(const SocketForwardRegionView&) = delete;
 
-  static std::shared_ptr<SocketForwardRegionView> GetInstance(
-#ifdef CUTTLEFISH_HOST
-    const char* domain
-#endif
-  );
-
 #ifdef CUTTLEFISH_HOST
   Connection OpenConnection(int port);
 #else
diff --git a/common/vsoc/lib/typed_region_view.h b/common/vsoc/lib/typed_region_view.h
index 7a599f6..ead7412 100644
--- a/common/vsoc/lib/typed_region_view.h
+++ b/common/vsoc/lib/typed_region_view.h
@@ -34,7 +34,7 @@
  * Layout should be VSoC shared memory compatible, defined in common/vsoc/shm,
  * and should have a constant string region name.
  */
-template <typename LayoutType>
+template <typename ViewType, typename LayoutType>
 class TypedRegionView : public RegionView {
  public:
   using Layout = LayoutType;
@@ -59,6 +59,46 @@
     return RegionView::Open(LayoutType::region_name);
   }
 #endif
+
+ public:
+  // Implementation of the region singletons.
+#if defined(CUTTLEFISH_HOST)
+  static ViewType* GetInstance(const char* domain) {
+    static std::mutex mtx;
+    static std::map<std::string, std::unique_ptr<ViewType>> instances;
+    if (!domain) {
+      return nullptr;
+    }
+    std::lock_guard<std::mutex> lock(mtx);
+    // Get a reference to the actual unique_ptr that's stored in the map, if
+    // there wasn't one it will be default constructed pointing to nullptr.
+    auto& instance = instances[domain];
+    if (!instance) {
+      // Update the referenced pointer with the address of the newly created
+      // region view.
+      instance.reset(new ViewType{});
+      if (!instance->Open(domain)) {
+        instance.reset();
+      }
+    }
+    return instance.get();
+  }
+#else
+  static ViewType* GetInstance() {
+    static std::mutex mtx;
+    static std::unique_ptr<ViewType> instance;
+    std::lock_guard<std::mutex> lock(mtx);
+    if (!instance) {
+      instance.reset(new ViewType{});
+      if (!instance->Open()) {
+        instance.reset();
+      }
+    }
+    return instance.get();
+  }
+#endif
+
+
 };
 
 }  // namespace vsoc
diff --git a/common/vsoc/lib/wifi_exchange_view.cpp b/common/vsoc/lib/wifi_exchange_view.cpp
index 1bbc189..301f35f 100644
--- a/common/vsoc/lib/wifi_exchange_view.cpp
+++ b/common/vsoc/lib/wifi_exchange_view.cpp
@@ -48,21 +48,5 @@
   memcpy(mac_address, data()->mac_address, ETH_ALEN);
 }
 
-#if defined(CUTTLEFISH_HOST)
-std::shared_ptr<WifiExchangeView> WifiExchangeView::GetInstance(
-    const char* domain) {
-  return RegionView::GetInstanceImpl<WifiExchangeView>(
-      [](std::shared_ptr<WifiExchangeView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
-#else
-std::shared_ptr<WifiExchangeView> WifiExchangeView::GetInstance() {
-  return RegionView::GetInstanceImpl<WifiExchangeView>(
-      std::mem_fn(&WifiExchangeView::Open));
-}
-#endif
-
 }  // namespace wifi
 }  // namespace vsoc
diff --git a/common/vsoc/lib/wifi_exchange_view.h b/common/vsoc/lib/wifi_exchange_view.h
index 5d00bd8..ad0d968 100644
--- a/common/vsoc/lib/wifi_exchange_view.h
+++ b/common/vsoc/lib/wifi_exchange_view.h
@@ -25,7 +25,9 @@
 namespace wifi {
 
 class WifiExchangeView
-    : public vsoc::TypedRegionView<vsoc::layout::wifi::WifiExchangeLayout> {
+    : public vsoc::TypedRegionView<
+        WifiExchangeView,
+        vsoc::layout::wifi::WifiExchangeLayout> {
  public:
   // Send netlink packet to peer.
   // returns true, if operation was successful.
@@ -41,12 +43,6 @@
 
   void SetConfigReady();
   void WaitConfigReady();
-
-#if defined(CUTTLEFISH_HOST)
-  static std::shared_ptr<WifiExchangeView> GetInstance(const char* domain);
-#else
-  static std::shared_ptr<WifiExchangeView> GetInstance();
-#endif
 };
 
 }  // namespace wifi
diff --git a/guest/commands/vsoc_input_service/vsoc_input_service.cpp b/guest/commands/vsoc_input_service/vsoc_input_service.cpp
index fd535cb..10fc2e9 100644
--- a/guest/commands/vsoc_input_service/vsoc_input_service.cpp
+++ b/guest/commands/vsoc_input_service/vsoc_input_service.cpp
@@ -64,8 +64,7 @@
     return false;
   }
 
-  std::shared_ptr<FBBroadcastRegionView> fb_broadcast =
-      FBBroadcastRegionView::GetInstance();
+  auto fb_broadcast = FBBroadcastRegionView::GetInstance();
   if (!fb_broadcast) {
     SLOGE("Failed to open framebuffer broadcast region");
     return false;
@@ -81,8 +80,7 @@
 }
 
 bool VSoCInputService::ProcessEvents() {
-  std::shared_ptr<InputEventsRegionView> input_events_rv =
-      InputEventsRegionView::GetInstance();
+  auto input_events_rv = InputEventsRegionView::GetInstance();
   // TODO(jemoreira): Post available devices to region
   input_events_rv->StartWorker();
 
diff --git a/guest/hals/audio/record_audio.cpp b/guest/hals/audio/record_audio.cpp
index 3aa27fd..fb8d25a 100644
--- a/guest/hals/audio/record_audio.cpp
+++ b/guest/hals/audio/record_audio.cpp
@@ -78,9 +78,10 @@
   }
 
   auto audio_data_rv = AudioDataRegionView::GetInstance();
+  CHECK(audio_data_rv != nullptr);
 
   /* std::unique_ptr<vsoc::RegionWorker> audio_worker = */
-    audio_data_rv->StartWorker();
+  audio_data_rv->StartWorker();
 
   std::unique_ptr<WaveWriter> writer;
   int64_t frameCount = 0ll;
@@ -102,7 +103,7 @@
 
   while (!gDone) {
     intptr_t res = audio_data_rv->data()->audio_queue.Read(
-            audio_data_rv.get(),
+            audio_data_rv,
             reinterpret_cast<char *>(buffer),
             sizeof(buffer));
 
diff --git a/guest/hals/audio/vsoc_audio.cpp b/guest/hals/audio/vsoc_audio.cpp
index fe21ffd..28292ff 100644
--- a/guest/hals/audio/vsoc_audio.cpp
+++ b/guest/hals/audio/vsoc_audio.cpp
@@ -215,7 +215,7 @@
 
 ssize_t GceAudio::SendMsg(const msghdr& msg, int /* flags */) {
     intptr_t res = audio_data_rv_->data()->audio_queue.Writev(
-            audio_data_rv_.get(),
+            audio_data_rv_,
             msg.msg_iov,
             msg.msg_iovlen,
             true /* non_blocking */);
diff --git a/guest/hals/audio/vsoc_audio.h b/guest/hals/audio/vsoc_audio.h
index 3d1f917..73d88ba 100644
--- a/guest/hals/audio/vsoc_audio.h
+++ b/guest/hals/audio/vsoc_audio.h
@@ -267,7 +267,7 @@
 #endif
 
   using AudioDataRegionView = vsoc::audio_data::AudioDataRegionView;
-  std::shared_ptr<AudioDataRegionView> audio_data_rv_;
+  AudioDataRegionView* audio_data_rv_{};
   std::unique_ptr<vsoc::RegionWorker> audio_worker_;
 
   // Lock to protect the data below.
diff --git a/guest/vsoc/lib/gralloc_region_view.cpp b/guest/vsoc/lib/gralloc_region_view.cpp
index a3073d6..9ae2c31 100644
--- a/guest/vsoc/lib/gralloc_region_view.cpp
+++ b/guest/vsoc/lib/gralloc_region_view.cpp
@@ -41,7 +41,7 @@
 }  // namespace
 
 bool GrallocRegionView::Open() {
-  if (!vsoc::ManagerRegionView<GrallocManagerLayout>::Open()) {
+  if (!vsoc::ManagerRegionView<GrallocRegionView, GrallocManagerLayout>::Open()) {
     return false;
   }
   std::shared_ptr<vsoc::RegionControl> managed_region =
@@ -140,9 +140,3 @@
     return fd;
   }
 }
-
-
-std::shared_ptr<GrallocRegionView> GrallocRegionView::GetInstance() {
-  return RegionView::GetInstanceImpl<GrallocRegionView>(
-      std::mem_fn(&GrallocRegionView::Open));
-}
diff --git a/guest/vsoc/lib/gralloc_region_view.h b/guest/vsoc/lib/gralloc_region_view.h
index 3857cf0..a32cff7 100644
--- a/guest/vsoc/lib/gralloc_region_view.h
+++ b/guest/vsoc/lib/gralloc_region_view.h
@@ -25,8 +25,11 @@
 namespace gralloc {
 
 class GrallocRegionView : public vsoc::ManagerRegionView<
+                          GrallocRegionView,
                           vsoc::layout::gralloc::GrallocManagerLayout> {
  public:
+  friend TypedRegionView<
+      GrallocRegionView, vsoc::layout::gralloc::GrallocManagerLayout>;
   GrallocRegionView() = default;
   // Allocates a gralloc buffer of (at least) the specified size. Returns a file
   // descriptor that exposes the buffer when mmapped from 0 to (the page
@@ -35,8 +38,6 @@
   // TODO(jemoreira): Include debug info like stride, width, height, etc
   int AllocateBuffer(size_t size, uint32_t* begin_offset = nullptr);
 
-  static std::shared_ptr<GrallocRegionView> GetInstance();
-
  protected:
   GrallocRegionView(const GrallocRegionView&) = delete;
   GrallocRegionView & operator=(const GrallocRegionView&) = delete;
diff --git a/guest/vsoc/lib/guest_region_e2e_test.cpp b/guest/vsoc/lib/guest_region_e2e_test.cpp
index 564a68a..344a743 100644
--- a/guest/vsoc/lib/guest_region_e2e_test.cpp
+++ b/guest/vsoc/lib/guest_region_e2e_test.cpp
@@ -64,7 +64,7 @@
 // 12. Confirm that no interrupt is pending in the second region
 
 template <typename View>
-void SetGuestStrings(std::shared_ptr<View> in) {
+void SetGuestStrings(View* in) {
   size_t num_data = in->string_size();
   EXPECT_LE(2U, num_data);
   for (size_t i = 0; i < num_data; ++i) {
@@ -76,7 +76,7 @@
 }
 
 template <typename View>
-void CheckPeerStrings(std::shared_ptr<View> in) {
+void CheckPeerStrings(View* in) {
   size_t num_data = in->string_size();
   EXPECT_LE(2U, num_data);
   for (size_t i = 0; i < num_data; ++i) {
@@ -85,10 +85,8 @@
 }
 
 TEST(RegionTest, BasicPeerTests) {
-  std::shared_ptr<vsoc::E2EPrimaryRegionView> primary =
-      vsoc::E2EPrimaryRegionView::GetInstance();
-  std::shared_ptr<vsoc::E2ESecondaryRegionView> secondary =
-      vsoc::E2ESecondaryRegionView::GetInstance();
+  auto primary = vsoc::E2EPrimaryRegionView::GetInstance();
+  auto secondary = vsoc::E2ESecondaryRegionView::GetInstance();
   ASSERT_TRUE(!!primary);
   ASSERT_TRUE(!!secondary);
   LOG(INFO) << "Regions are open";
@@ -155,18 +153,20 @@
 
 // Region view classes to allow calling the Open() function from the test.
 class E2EManagedTestRegionView
-    : public vsoc::TypedRegionView<E2EManagedTestRegionLayout> {
+    : public vsoc::TypedRegionView<
+        E2EManagedTestRegionView,
+        E2EManagedTestRegionLayout> {
  public:
-  bool Open() {
-    return vsoc::TypedRegionView<E2EManagedTestRegionLayout>::Open();
-  }
+  using vsoc::TypedRegionView<
+      E2EManagedTestRegionView, E2EManagedTestRegionLayout>::Open;
 };
 class E2EManagerTestRegionView
-    : public vsoc::ManagerRegionView<E2EManagerTestRegionLayout> {
+    : public vsoc::ManagerRegionView<
+        E2EManagerTestRegionView,
+        E2EManagerTestRegionLayout> {
  public:
-  bool Open() {
-    return vsoc::ManagerRegionView<E2EManagerTestRegionLayout>::Open();
-  }
+  using vsoc::ManagerRegionView<
+      E2EManagerTestRegionView, E2EManagerTestRegionLayout>::Open;
 };
 
 class ManagedRegionTest {
@@ -241,8 +241,7 @@
   testing::InitGoogleTest(&argc, argv);
   int rval = RUN_ALL_TESTS();
   if (!rval) {
-    std::shared_ptr<vsoc::E2EPrimaryRegionView> region =
-        vsoc::E2EPrimaryRegionView::GetInstance();
+    auto region = vsoc::E2EPrimaryRegionView::GetInstance();
     region->guest_status(vsoc::layout::e2e_test::E2E_MEMORY_FILLED);
     LOG(INFO) << "stage_1_guest_region_e2e_tests PASSED";
   }
diff --git a/guest/vsoc/lib/manager_region_view.h b/guest/vsoc/lib/manager_region_view.h
index 6c65dec..dc77c06 100644
--- a/guest/vsoc/lib/manager_region_view.h
+++ b/guest/vsoc/lib/manager_region_view.h
@@ -27,8 +27,8 @@
  * The Layout type must (in addition to requirements for TypedRegionView) also
  * provide a nested type for the layout of the managed region.
  */
-template <typename Layout>
-class ManagerRegionView : public TypedRegionView<Layout> {
+template <typename View, typename Layout>
+class ManagerRegionView : public TypedRegionView<View, Layout> {
  public:
   ManagerRegionView() = default;
   /**
diff --git a/host/commands/launch/fb_bcast_region_handler.cc b/host/commands/launch/fb_bcast_region_handler.cc
index 047c621..d58dcc2 100644
--- a/host/commands/launch/fb_bcast_region_handler.cc
+++ b/host/commands/launch/fb_bcast_region_handler.cc
@@ -27,8 +27,7 @@
 DEFINE_int32(refresh_rate_hz, 60, "Screen refresh rate in Hertz");
 
 void InitializeFBBroadcastRegion() {
-  std::shared_ptr<vsoc::framebuffer::FBBroadcastRegionView> region =
-      vsoc::framebuffer::FBBroadcastRegionView::GetInstance(
+  auto region = vsoc::framebuffer::FBBroadcastRegionView::GetInstance(
           vsoc::GetDomain().c_str());
   if (!region) {
     LOG(INFO) << "Framebuffer region was not found";
diff --git a/host/frontend/vnc_server/Android.bp b/host/frontend/vnc_server/Android.bp
index dc65687..cf8a2c4 100644
--- a/host/frontend/vnc_server/Android.bp
+++ b/host/frontend/vnc_server/Android.bp
@@ -24,7 +24,6 @@
         "virtual_inputs.cpp",
         "vnc_client_connection.cpp",
         "vnc_server.cpp",
-        "vnc_utils.cpp",
     ],
     header_libs: [
         "cuttlefish_glog",
diff --git a/host/frontend/vnc_server/virtual_inputs.cpp b/host/frontend/vnc_server/virtual_inputs.cpp
index 6cb06dc..b2f519c 100644
--- a/host/frontend/vnc_server/virtual_inputs.cpp
+++ b/host/frontend/vnc_server/virtual_inputs.cpp
@@ -216,10 +216,10 @@
 }
 }  // namespace
 
-VirtualInputs::VirtualInputs() {
-  input_events_region_view_ =
+VirtualInputs::VirtualInputs()
+  : input_events_region_view_{
       vsoc::input_events::InputEventsRegionView::GetInstance(
-          vsoc::GetDomain().c_str());
+          vsoc::GetDomain().c_str())} {
   if (!input_events_region_view_) {
     LOG(FATAL) << "Failed to open Input events region view";
   }
diff --git a/host/frontend/vnc_server/virtual_inputs.h b/host/frontend/vnc_server/virtual_inputs.h
index 27c8ccf..c937a12 100644
--- a/host/frontend/vnc_server/virtual_inputs.h
+++ b/host/frontend/vnc_server/virtual_inputs.h
@@ -35,8 +35,7 @@
   void HandlePointerEvent(bool touch_down, int x, int y);
 
  private:
-  std::shared_ptr<vsoc::input_events::InputEventsRegionView>
-      input_events_region_view_;
+  vsoc::input_events::InputEventsRegionView* input_events_region_view_{};
   std::map<uint32_t, uint32_t> keymapping_;
 };
 
diff --git a/host/frontend/vnc_server/vnc_utils.cpp b/host/frontend/vnc_server/vnc_utils.cpp
deleted file mode 100644
index d4c6dd6..0000000
--- a/host/frontend/vnc_server/vnc_utils.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 "common/vsoc/lib/fb_bcast_region_view.h"
-#include "host/libs/config/host_config.h"
-
-using vsoc::framebuffer::FBBroadcastRegionView;
-
-namespace cvd {
-namespace vnc {
-
-std::shared_ptr<FBBroadcastRegionView> GetFBBroadcastRegionView() {
-  std::shared_ptr<FBBroadcastRegionView> region =
-      FBBroadcastRegionView::GetInstance(vsoc::GetDomain().c_str());
-  if (!region) {
-    LOG(FATAL) << "Unable to open FBBroadcastRegion";
-  }
-  return region;
-}
-
-}  // namespace vnc
-}  // namespace cvd
diff --git a/host/vsoc/lib/gralloc_buffer_region_view.cpp b/host/vsoc/lib/gralloc_buffer_region_view.cpp
index f171396..ffb130e 100644
--- a/host/vsoc/lib/gralloc_buffer_region_view.cpp
+++ b/host/vsoc/lib/gralloc_buffer_region_view.cpp
@@ -32,12 +32,3 @@
   }
   return region_offset_to_pointer<uint8_t>(offset);
 }
-
-std::shared_ptr<GrallocBufferRegionView> GrallocBufferRegionView::GetInstance(
-    const char* domain) {
-  return RegionView::GetInstanceImpl<GrallocBufferRegionView>(
-      [](std::shared_ptr<GrallocBufferRegionView> region, const char* domain) {
-        return region->Open(domain);
-      },
-      domain);
-}
diff --git a/host/vsoc/lib/gralloc_buffer_region_view.h b/host/vsoc/lib/gralloc_buffer_region_view.h
index 071694c..f76b243 100644
--- a/host/vsoc/lib/gralloc_buffer_region_view.h
+++ b/host/vsoc/lib/gralloc_buffer_region_view.h
@@ -32,16 +32,15 @@
 // VNC server (which uses only the frame buffer and gets the information it
 // needs from the framebuffer region).
 class GrallocBufferRegionView
-    : vsoc::TypedRegionView<vsoc::layout::gralloc::GrallocBufferLayout> {
- public:
+    : vsoc::TypedRegionView<
+        GrallocBufferRegionView,
+        vsoc::layout::gralloc::GrallocBufferLayout> {
+   public:
   GrallocBufferRegionView() = default;
   GrallocBufferRegionView(const GrallocBufferRegionView&) = delete;
   GrallocBufferRegionView& operator=(const GrallocBufferRegionView&) = delete;
 
   uint8_t* OffsetToBufferPtr(vsoc_reg_off_t offset);
-
-  static std::shared_ptr<GrallocBufferRegionView> GetInstance(
-      const char* domain);
 };
 
 }  // namespace gralloc
diff --git a/host/vsoc/lib/host_region_e2e_test.cpp b/host/vsoc/lib/host_region_e2e_test.cpp
index 4502381..13f453b 100644
--- a/host/vsoc/lib/host_region_e2e_test.cpp
+++ b/host/vsoc/lib/host_region_e2e_test.cpp
@@ -38,7 +38,7 @@
 // 12. Confirm that no interrupt is pending in the second region
 
 template <typename View>
-void SetHostStrings(std::shared_ptr<View> in) {
+void SetHostStrings(View* in) {
   size_t num_data = in->string_size();
   EXPECT_LE(static_cast<size_t>(2), num_data);
   for (size_t i = 0; i < num_data; ++i) {
@@ -50,7 +50,7 @@
 }
 
 template <typename View>
-void CheckPeerStrings(std::shared_ptr<View> in) {
+void CheckPeerStrings(View* in) {
   size_t num_data = in->string_size();
   EXPECT_LE(static_cast<size_t>(2), num_data);
   for (size_t i = 0; i < num_data; ++i) {
@@ -59,10 +59,10 @@
 }
 
 TEST(RegionTest, PeerTests) {
-  std::shared_ptr<vsoc::E2EPrimaryRegionView> primary =
+  auto primary =
       vsoc::E2EPrimaryRegionView::GetInstance(vsoc::GetDomain().c_str());
   ASSERT_TRUE(!!primary);
-  std::shared_ptr<vsoc::E2ESecondaryRegionView> secondary =
+  auto secondary =
       vsoc::E2ESecondaryRegionView::GetInstance(vsoc::GetDomain().c_str());
   ASSERT_TRUE(!!secondary);
   LOG(INFO) << "Regions are open";
@@ -122,7 +122,7 @@
   testing::InitGoogleTest(&argc, argv);
   int rval = RUN_ALL_TESTS();
   if (!rval) {
-    std::shared_ptr<vsoc::E2EPrimaryRegionView> region =
+    auto region =
         vsoc::E2EPrimaryRegionView::GetInstance(vsoc::GetDomain().c_str());
     region->host_status(vsoc::layout::e2e_test::E2E_MEMORY_FILLED);
   }