Refactor the static checks of layout structures.

Uses templates instead of macros.
Eliminates versioning of layout structures (not needed since host and
guest versions are compiled together).
Eliminates checks for constant values.
Will ease the burden on the programmer to assert shm compatibility for
every new region layout. Once the vsoc_mem.json file is substituded
the layout will be automatically validated when added to the vsoc
device.

Bug: 79602833
Test: build and run locally
Change-Id: Ia176d7678bff96e509da182def51d3a74b598cd3
diff --git a/Android.bp b/Android.bp
index 1b3a986..7945e35 100644
--- a/Android.bp
+++ b/Android.bp
@@ -104,6 +104,7 @@
         "common/vsoc/lib/screen_region_view.cpp",
         "common/vsoc/lib/socket_forward_layout.cpp",
         "common/vsoc/lib/socket_forward_region_view.cpp",
+        "common/vsoc/lib/vsoc_memory.cpp",
         "common/vsoc/lib/wifi_exchange_layout.cpp",
         "common/vsoc/lib/wifi_exchange_view.cpp",
     ],
diff --git a/common/vsoc/lib/vsoc_memory.cpp b/common/vsoc/lib/vsoc_memory.cpp
new file mode 100644
index 0000000..f05b0b8
--- /dev/null
+++ b/common/vsoc/lib/vsoc_memory.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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/vsoc_memory.h"
+
+#include <string>
+#include <type_traits>
+
+#include "common/vsoc/shm/audio_data_layout.h"
+#include "common/vsoc/shm/e2e_test_region_layout.h"
+#include "common/vsoc/shm/gralloc_layout.h"
+#include "common/vsoc/shm/input_events_layout.h"
+#include "common/vsoc/shm/ril_layout.h"
+#include "common/vsoc/shm/screen_layout.h"
+#include "common/vsoc/shm/socket_forward_layout.h"
+#include "common/vsoc/shm/version.h"
+#include "common/vsoc/shm/wifi_exchange_layout.h"
+
+namespace vsoc {
+
+// ShmTypeValidator provides meaningful information about the type size
+// mismatch in compilation error messages, eg.
+//
+// error:
+//    static_assert failed "Class size changed, update version.h"
+//    static_assert(Current == Expected,
+// note: in instantiation of template class
+//    'ShmTypeValidator<vsoc::layout::myclass::ClassName, 1232, 1240>'
+//    requested here ASSERT_SHM_COMPATIBLE(ClassName, myclass);
+//
+template <typename Type, size_t Current, size_t Expected>
+struct ShmTypeValidator {
+  static_assert(Current == Expected, "Class size changed, update version.h");
+  static_assert(std::is_trivial<Type>(), "Class uses features that are unsafe");
+  static constexpr bool valid =
+      (Current == Expected) && std::is_trivial<Type>();
+};
+
+namespace {
+template <class R>
+RegionMemoryLayout ValidateAndBuildLayout(int region_size,
+                                          int g_to_h_signal_table_log_size,
+                                          int h_to_g_signal_table_log_size,
+                                          const char* managed_by = nullptr) {
+  static_assert(
+      ShmTypeValidator<R, sizeof(R), vsoc::layout::VersionInfo<R>::size>::valid,
+      "Compilation error. Please fix above errors and retry.");
+  return RegionMemoryLayout(R::region_name, region_size,
+                            g_to_h_signal_table_log_size,
+                            h_to_g_signal_table_log_size, managed_by);
+}
+
+}  // namespace
+
+const std::vector<RegionMemoryLayout>& GetVsocMemoryLayout() {
+  static const std::vector<RegionMemoryLayout> layout = {
+      ValidateAndBuildLayout<layout::input_events::InputEventsLayout>(
+          /*size*/ 4096, /*g->h*/ 2, /*h->g*/ 2),
+      ValidateAndBuildLayout<layout::screen::ScreenLayout>(
+          /*size*/ 12292096, /*g->h*/ 2, /*h->g*/ 2),
+      ValidateAndBuildLayout<layout::gralloc::GrallocManagerLayout>(
+          /*size*/ 40960, /*g->h*/ 2, /*h->g*/ 2),
+      ValidateAndBuildLayout<layout::gralloc::GrallocBufferLayout>(
+          /*size*/ 407142400, /*g->h*/ 0, /*h->g*/ 0,
+          /* managed_by */ layout::gralloc::GrallocManagerLayout::region_name),
+      ValidateAndBuildLayout<layout::socket_forward::SocketForwardLayout>(
+          /*size*/ 2105344, /*g->h*/ 7, /*h->g*/ 7),
+      ValidateAndBuildLayout<layout::wifi::WifiExchangeLayout>(
+          /*size*/ 139264, /*g->h*/ 2, /*h->g*/ 2),
+      ValidateAndBuildLayout<layout::ril::RilLayout>(
+          /*size*/ 4096, /*g->h*/ 2, /*h->g*/ 2),
+      ValidateAndBuildLayout<layout::e2e_test::E2EPrimaryTestRegionLayout>(
+          /*size*/ 16384, /*g->h*/ 1, /*h->g*/ 1),
+      ValidateAndBuildLayout<layout::e2e_test::E2ESecondaryTestRegionLayout>(
+          /*size*/ 16384, /*g->h*/ 1, /*h->g*/ 1),
+      ValidateAndBuildLayout<layout::e2e_test::E2EManagerTestRegionLayout>(
+          /*size*/ 4096, /*g->h*/ 1, /*h->g*/ 1),
+      ValidateAndBuildLayout<layout::e2e_test::E2EManagedTestRegionLayout>(
+          /*size*/ 16384, /*g->h*/ 1, /*h->g*/ 1),
+      ValidateAndBuildLayout<layout::audio_data::AudioDataLayout>(
+          /*size*/ 20480, /*g->h*/ 2, /*h->g*/ 2)};
+
+  return layout;
+}
+
+}  // namespace vsoc
diff --git a/common/vsoc/lib/vsoc_memory.h b/common/vsoc/lib/vsoc_memory.h
new file mode 100644
index 0000000..b6844b8
--- /dev/null
+++ b/common/vsoc/lib/vsoc_memory.h
@@ -0,0 +1,58 @@
+#pragma once
+/*
+ * 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 <vector>
+
+namespace vsoc {
+
+class RegionMemoryLayout {
+ public:
+  RegionMemoryLayout(const char* region_name, size_t region_size,
+                     int guest_to_host_signal_table_log_size,
+                     int host_to_guest_signal_table_log_size,
+                     const char* managed_by)
+      : region_name_(region_name),
+        region_size_(region_size),
+        guest_to_host_signal_table_log_size_(
+            guest_to_host_signal_table_log_size),
+        host_to_guest_signal_table_log_size_(
+            host_to_guest_signal_table_log_size),
+        managed_by_(managed_by) {}
+
+  const char* region_name() const { return region_name_; }
+  size_t region_size() const { return region_size_; }
+  int guest_to_host_signal_table_log_size() const {
+    return guest_to_host_signal_table_log_size_;
+  }
+  int host_to_guest_signal_table_log_size() const {
+    return host_to_guest_signal_table_log_size_;
+  }
+  const char * managed_by() const {
+    return managed_by_;
+  }
+
+ private:
+  const char* region_name_{};
+  size_t region_size_{};
+  int guest_to_host_signal_table_log_size_{};
+  int host_to_guest_signal_table_log_size_{};
+  const char* managed_by_{};
+};
+
+const std::vector<RegionMemoryLayout>& GetVsocMemoryLayout();
+
+}  // namespace vsoc
diff --git a/common/vsoc/shm/audio_data_layout.h b/common/vsoc/shm/audio_data_layout.h
index d344a8e..30df4f8 100644
--- a/common/vsoc/shm/audio_data_layout.h
+++ b/common/vsoc/shm/audio_data_layout.h
@@ -17,7 +17,6 @@
 
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/circqueue.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for region carrying audio data from audio HAL to client.
 
@@ -31,9 +30,7 @@
     // size = 2^14 = 16384, packets are up to 4KB bytes each.
     CircularPacketQueue<14, 4096> audio_queue;
 };
-ASSERT_SHM_COMPATIBLE(AudioDataLayout, audio_data);
 
 }  // namespace audio_data
 }  // namespace layout
 }  // namespace vsoc
-
diff --git a/common/vsoc/shm/base.h b/common/vsoc/shm/base.h
index 2525696..7bbaeb9 100644
--- a/common/vsoc/shm/base.h
+++ b/common/vsoc/shm/base.h
@@ -15,39 +15,10 @@
  * limitations under the License.
  */
 
+#include <stdint.h>
+
 // Base macros for all layout structures.
 
-#include <type_traits>
-#include "common/vsoc/shm/version.h"
-
-// ShmTypeValidator provides meaningful information about the type size
-// mismatch in compilation error messages, eg.
-//
-// error:
-//    static_assert failed "Class size changed, update the version"
-//    static_assert(Current == Expected,
-// note: in instantiation of template class
-//    'ShmTypeValidator<vsoc::layout::myclass::ClassName, 1232, 1240>'
-//    requested here ASSERT_SHM_COMPATIBLE(ClassName, myclass);
-//
-template<typename Type, size_t Current, size_t Expected>
-struct ShmTypeValidator {
-    static_assert(Current == Expected,
-                  "Class size changed, update the version");
-    static_assert(std::is_trivial<Type>(),
-                  "Class uses features that are unsafe");
-    static constexpr bool valid = (Current == Expected);
-};
-
-#define ASSERT_SHM_COMPATIBLE(T, R)                                   \
-  static_assert(                                                      \
-      ShmTypeValidator<T, sizeof(T), vsoc::layout::version_info::R::T##_size> \
-      ::valid, "Compilation error. Please fix above errors and retry.")
-
-#define ASSERT_SHM_CONSTANT_VALUE(T, R)                                 \
-  static_assert(T == vsoc::layout::version_info::R::constant_values::T, \
-                "Constant value changed")
-
 namespace vsoc {
 namespace layout {
 
@@ -71,14 +42,12 @@
   Peer = Host
 #endif
 };
-ASSERT_SHM_COMPATIBLE(Sides, multi_region);
 
 /**
  * Base class for all region layout structures.
  */
 class RegionLayout {
 };
-ASSERT_SHM_COMPATIBLE(RegionLayout, multi_region);
 
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/circqueue.h b/common/vsoc/shm/circqueue.h
index 2f26fa3..aacdd2b 100644
--- a/common/vsoc/shm/circqueue.h
+++ b/common/vsoc/shm/circqueue.h
@@ -101,7 +101,6 @@
   char buffer_[BufferSize];
 };
 using CircularQueueBase64k = CircularQueueBase<16>;
-ASSERT_SHM_COMPATIBLE(CircularQueueBase64k, multi_region);
 
 /**
  * Byte oriented circular queue. Reads will always return some data, but
@@ -135,7 +134,6 @@
   using Range = typename CircularQueueBase<SizeLog2>::Range;
 };
 using CircularByteQueue64k = CircularByteQueue<16>;
-ASSERT_SHM_COMPATIBLE(CircularByteQueue64k, multi_region);
 
 /**
  * Packet oriented circular queue. Reads will either return data or an error.
@@ -188,7 +186,6 @@
   intptr_t CalculateBufferedSize(size_t payload);
 };
 using CircularPacketQueue64k = CircularPacketQueue<16, 1024>;
-ASSERT_SHM_COMPATIBLE(CircularPacketQueue64k, multi_region);
 
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/e2e_test_region_layout.h b/common/vsoc/shm/e2e_test_region_layout.h
index 3c5950e..8853211 100644
--- a/common/vsoc/shm/e2e_test_region_layout.h
+++ b/common/vsoc/shm/e2e_test_region_layout.h
@@ -18,7 +18,6 @@
 #include <atomic>
 #include <cstdint>
 #include "common/vsoc/shm/base.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for a region that supports end-to-end (E2E) testing of
 // shared memory regions. This verifies that all sorts of things work along the
@@ -66,7 +65,6 @@
   char host_writable[kOwnedFieldSize];
   char guest_writable[kOwnedFieldSize];
 };
-ASSERT_SHM_COMPATIBLE(E2EMemoryFill, e2e_test);
 
 /**
  * Structure that grants permission to write in the region to either the guest
@@ -87,7 +85,6 @@
   // doing memory mapped I/O.
   uint32_t value_;
 };
-ASSERT_SHM_COMPATIBLE(E2ETestStageRegister, e2e_test);
 
 /**
  * Describes the layout of the regions used for the end-to-end test. There
@@ -126,21 +123,18 @@
   // until we examine the region.
   E2EMemoryFill data[1];
 };
-ASSERT_SHM_COMPATIBLE(E2ETestRegionLayout, e2e_test);
 
 struct E2EPrimaryTestRegionLayout : public E2ETestRegionLayout {
   static const char* region_name;
   static const char guest_pattern[E2EMemoryFill::kOwnedFieldSize];
   static const char host_pattern[E2EMemoryFill::kOwnedFieldSize];
 };
-ASSERT_SHM_COMPATIBLE(E2EPrimaryTestRegionLayout, e2e_test);
 
 struct E2ESecondaryTestRegionLayout : public E2ETestRegionLayout {
   static const char* region_name;
   static const char guest_pattern[E2EMemoryFill::kOwnedFieldSize];
   static const char host_pattern[E2EMemoryFill::kOwnedFieldSize];
 };
-ASSERT_SHM_COMPATIBLE(E2ESecondaryTestRegionLayout, e2e_test);
 
 /**
  * Defines an end-to-end region with a name that should never be configured.
@@ -148,20 +142,17 @@
 struct E2EUnfindableRegionLayout : public E2ETestRegionLayout {
   static const char* region_name;
 };
-ASSERT_SHM_COMPATIBLE(E2EUnfindableRegionLayout, e2e_test);
 
 struct E2EManagedTestRegionLayout : public RegionLayout {
   static const char* region_name;
   uint32_t val;  // Not needed, here only to avoid an empty struct.
 };
-ASSERT_SHM_COMPATIBLE(E2EManagedTestRegionLayout, e2e_test);
 
 struct E2EManagerTestRegionLayout : public RegionLayout {
   static const char* region_name;
   typedef E2EManagedTestRegionLayout ManagedRegion;
   uint32_t data[4];  // We don't need more than 4 for the tests
 };
-ASSERT_SHM_COMPATIBLE(E2EManagerTestRegionLayout, e2e_test);
 
 }  // namespace e2e_test
 }  // namespace layout
diff --git a/common/vsoc/shm/gralloc_layout.h b/common/vsoc/shm/gralloc_layout.h
index 54f5589..3e0c883 100644
--- a/common/vsoc/shm/gralloc_layout.h
+++ b/common/vsoc/shm/gralloc_layout.h
@@ -18,7 +18,6 @@
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/graphics.h"
 #include "common/vsoc/shm/lock.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for the gralloc manager region.
 
@@ -45,12 +44,10 @@
     return buffer_end - buffer_begin;
   }
 };
-ASSERT_SHM_COMPATIBLE(BufferEntry, gralloc);
 
 struct GrallocBufferLayout : public RegionLayout {
   static const char* region_name;
 };
-ASSERT_SHM_COMPATIBLE(GrallocBufferLayout, gralloc);
 
 struct GrallocManagerLayout : public RegionLayout {
   static const char* region_name;
@@ -63,7 +60,6 @@
   // Needs to be last field
   BufferEntry buffers_table[1];
 };
-ASSERT_SHM_COMPATIBLE(GrallocManagerLayout, gralloc);
 
 } // namespace gralloc
 } // namespace layout
diff --git a/common/vsoc/shm/graphics.h b/common/vsoc/shm/graphics.h
index 22fe047..f29e0cf 100644
--- a/common/vsoc/shm/graphics.h
+++ b/common/vsoc/shm/graphics.h
@@ -25,7 +25,6 @@
 #include <cstdint>
 
 #include "common/vsoc/shm/base.h"
-#include "common/vsoc/shm/version.h"
 
 namespace vsoc {
 
@@ -130,16 +129,6 @@
   //   VSOC_PIXEL_FORMAT_sRGB_X_8888
   //   VSOC_PIXEL_FORMAT_sRGB_A_8888
 };
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_UNINITIALIZED, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_BLOB, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_RGB_565, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_YV12, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_YCbCr_420_888, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_RGB_888, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_RGBA_8888, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_RGBX_8888, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_BGRA_8888, multi_region);
-ASSERT_SHM_CONSTANT_VALUE(VSOC_PIXEL_FORMAT_RGBA_FP16, multi_region);
 
 namespace layout {
 
@@ -148,7 +137,6 @@
 struct PixelFormatRegister {
   volatile PixelFormat value_;
 };
-ASSERT_SHM_COMPATIBLE(PixelFormatRegister, multi_region);
 
 // Register layout for a mask giving different PixelFormats. Reserve enough
 // space to allow for future expansion. For example, we may well end with
@@ -160,7 +148,6 @@
     return !!(value_ & (uint64_t(1) << in));
   }
 };
-ASSERT_SHM_COMPATIBLE(PixelFormatMaskRegister, multi_region);
 
 // Ensure that the mask is large enough to hold the highest encodable
 // pixel format.
diff --git a/common/vsoc/shm/input_events_layout.h b/common/vsoc/shm/input_events_layout.h
index 83ad70b..7cb4654 100644
--- a/common/vsoc/shm/input_events_layout.h
+++ b/common/vsoc/shm/input_events_layout.h
@@ -17,7 +17,6 @@
 
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/circqueue.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for region carrying input events from host to guest
 
@@ -36,7 +35,6 @@
   CircularPacketQueue<10, 16> keyboard_queue;
   CircularPacketQueue<10, 16> power_button_queue;
 };
-ASSERT_SHM_COMPATIBLE(InputEventsLayout, input_events);
 
 }  // namespace input_events
 }  // namespace layout
diff --git a/common/vsoc/shm/lock.h b/common/vsoc/shm/lock.h
index f3b8da8..6ebdaa2 100644
--- a/common/vsoc/shm/lock.h
+++ b/common/vsoc/shm/lock.h
@@ -29,7 +29,6 @@
 #include <cstdint>
 
 #include "common/vsoc/shm/base.h"
-#include "common/vsoc/shm/version.h"
 
 // Host userspace, guest userspace, and the guest kernel must all agree on
 // the relationship between std::atomic and atomic_t. That's hard to do without
@@ -88,7 +87,6 @@
  protected:
   std::atomic<uint32_t> lock_;
 };
-ASSERT_SHM_COMPATIBLE(SpinLock, multi_region);
 
 /**
  * This is a generic synchronization primitive that provides space for the
@@ -139,7 +137,6 @@
   int64_t owner_scratch_[2];
 #pragma clang diagnostic pop
 };
-ASSERT_SHM_COMPATIBLE(WaitingLockBase, multi_region);
 
 /**
  * GuestLocks can be acquired and released only on the guest. They reside
@@ -164,7 +161,6 @@
   bool Recover();
 #endif
 };
-ASSERT_SHM_COMPATIBLE(GuestLock, multi_region);
 
 /**
  * HostLocks can be acquired and released only on the host. They reside
@@ -190,7 +186,6 @@
   bool Recover();
 #endif
 };
-ASSERT_SHM_COMPATIBLE(HostLock, multi_region);
 
 /**
  * GuestAndHostLocks can be acquired and released on either side of the
@@ -230,7 +225,6 @@
    */
   bool Recover(RegionView*);
 };
-ASSERT_SHM_COMPATIBLE(GuestAndHostLock, multi_region);
 
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/ril_layout.h b/common/vsoc/shm/ril_layout.h
index b2749dd..8910bde 100644
--- a/common/vsoc/shm/ril_layout.h
+++ b/common/vsoc/shm/ril_layout.h
@@ -16,7 +16,6 @@
  */
 
 #include "common/vsoc/shm/base.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for the ril hal region
 
@@ -33,7 +32,6 @@
   char broadcast[16];
   uint32_t prefixlen;
 };
-ASSERT_SHM_COMPATIBLE(RilLayout, ril);
 }  // namespace ril
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/screen_layout.h b/common/vsoc/shm/screen_layout.h
index 5975247..3e54c6c 100644
--- a/common/vsoc/shm/screen_layout.h
+++ b/common/vsoc/shm/screen_layout.h
@@ -15,9 +15,10 @@
  * limitations under the License.
  */
 
+#include <vector>
+
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/lock.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for screen region
 
@@ -61,7 +62,6 @@
   CompositionStats stats;
   uint8_t buffer[0];
 };
-ASSERT_SHM_COMPATIBLE(ScreenLayout, screen);
 
 }  // namespace screen
 
diff --git a/common/vsoc/shm/socket_forward_layout.h b/common/vsoc/shm/socket_forward_layout.h
index 40075c1..69d4ae2 100644
--- a/common/vsoc/shm/socket_forward_layout.h
+++ b/common/vsoc/shm/socket_forward_layout.h
@@ -18,7 +18,6 @@
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/circqueue.h"
 #include "common/vsoc/shm/lock.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for wifi packet exchange region.
 namespace vsoc {
@@ -26,6 +25,7 @@
 namespace socket_forward {
 
 constexpr std::size_t kMaxPacketSize = 8192;
+constexpr std::size_t kNumQueues = 16;
 
 enum class QueueState : std::uint32_t {
   INACTIVE = 0,
@@ -79,14 +79,12 @@
     return recovered;
   }
 
-  QueuePair queues_[version_info::socket_forward::kNumQueues];
+  QueuePair queues_[kNumQueues];
   std::atomic_uint32_t seq_num; // incremented for every new connection
   std::atomic_uint32_t generation_num; // incremented for every new socket forward process
   static const char* region_name;
 };
 
-ASSERT_SHM_COMPATIBLE(SocketForwardLayout, socket_forward);
-
 }  // namespace socket_forward
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/version.h b/common/vsoc/shm/version.h
index 895b87b..cc2e6b6 100644
--- a/common/vsoc/shm/version.h
+++ b/common/vsoc/shm/version.h
@@ -49,141 +49,127 @@
 
 #include <cstdint>
 
+#include "common/vsoc/shm/audio_data_layout.h"
+#include "common/vsoc/shm/e2e_test_region_layout.h"
+#include "common/vsoc/shm/gralloc_layout.h"
+#include "common/vsoc/shm/input_events_layout.h"
+#include "common/vsoc/shm/ril_layout.h"
+#include "common/vsoc/shm/screen_layout.h"
+#include "common/vsoc/shm/socket_forward_layout.h"
+#include "common/vsoc/shm/wifi_exchange_layout.h"
+
 namespace vsoc {
 namespace layout {
-namespace version_info {
-namespace multi_region {
 
-namespace {
-// Increment this for any change in size in the fundamental structures listed
-// below.  If the size of any of these structures changes we must examine all
-// of the regions bumping the version number if they used the fields in their
-// definition.
-const uint32_t version = 0;
-}  // namespace
-
-static const std::size_t Base_size = 1;
-static const std::size_t CircularQueueBase64k_size = 65548;
-static const std::size_t CircularByteQueue64k_size = 65548;
-static const std::size_t CircularPacketQueue64k_size = 65548;
-static const std::size_t GuestLock_size = 40;
-static const std::size_t GuestAndHostLock_size = 40;
-static const std::size_t HostLock_size = 40;
-static const std::size_t PixelFormatRegister_size = 4;
-static const std::size_t PixelFormatMaskRegister_size = 8;
-static const std::size_t RegionLayout_size = 1;
-static const std::size_t Sides_size = 4;
-static const std::size_t SpinLock_size = 4;
-static const std::size_t WaitingLockBase_size = 40;
-
-namespace constant_values {
-static const uint32_t VSOC_PIXEL_FORMAT_UNINITIALIZED = 0;
-static const uint32_t VSOC_PIXEL_FORMAT_BLOB = 1;
-
-static const uint32_t VSOC_PIXEL_FORMAT_RGB_565 = 8;
-static const uint32_t VSOC_PIXEL_FORMAT_YV12 = 9;
-static const uint32_t VSOC_PIXEL_FORMAT_YCbCr_420_888 = 10;
-
-static const uint32_t VSOC_PIXEL_FORMAT_RGB_888 = 16;
-
-static const uint32_t VSOC_PIXEL_FORMAT_RGBA_8888 = 24;
-static const uint32_t VSOC_PIXEL_FORMAT_RGBX_8888 = 25;
-static const uint32_t VSOC_PIXEL_FORMAT_BGRA_8888 = 26;
-static const uint32_t VSOC_PIXEL_FORMAT_RGBA_FP16 = 56;
-}  // namespace constant_values
-}  // namespace multi_region
-
-// Versioning information for gralloc_layout.h
-// Changes to these structures will affect only the gralloc region
-namespace gralloc {
-namespace {
-const uint32_t version = 0;
-}
-static const std::size_t BufferEntry_size = 32;
-static const std::size_t GrallocManagerLayout_size = 80;
-static const std::size_t GrallocBufferLayout_size = 1;
-}  // namespace gralloc
-
-// Versioning information for input_events_layout.h
-// Changes to these structures will affect only the input_events region
-namespace input_events {
-namespace {
-const uint32_t version = 0;
-}
-// Three circular queues, each with a 1024 bytes buffer, a 32 bits spinlock and
-// two 32 bits integers.
-static const std::size_t InputEventsLayout_size = 3 * (1024 + 3 * 4);
-}  // namespace input_events
-
-// Versioning information for screen_layout.h
-// Changes to these structures will affect only the screen region.
-namespace screen {
-namespace {
-const uint32_t version = 0;
-}
-static const std::size_t ScreenLayout_size = 112;
-}  // namespace screen
-
-// Versioning information for wifi_layout.h
-namespace wifi {
-namespace {
-constexpr uint32_t version = 1;
-}  // namespace
-constexpr size_t WifiExchangeLayout_size =
-    65548 + // sizeof(CircularPacketQueue<16, 8192>) - forward
-    65548 + // sizeof(CircularPacketQueue<16, 8192>) - reverse
-    6 +     // uint8_t[6] MAC address.
-    6;     // uint8_t[6] MAC address.
-}  // namespace wifi
-
-// Versioning information for ril_layout.h
-namespace ril {
-namespace {
-const uint32_t version = 1;
-}
-static const std::size_t RilLayout_size = 68;
-}  // namespace ril
-
-// Versioning Information for socket_forward_layout.h
-namespace socket_forward {
-constexpr uint32_t version = 0;
-constexpr std::size_t kNumQueues = 16;
-constexpr std::size_t SocketForwardLayout_size =
-    ((((65548  + 4) // queue + state
-       * 2) // host_to_guest and guest_to_host
-      + 4 + 4) // port and state_lock
-     * kNumQueues)
-    + 4 // seq_num
-    + 4; // generation number
-}  // namespace socket_forward
-
-// Versioning information for e2e_test_region.h
-// Changes to these structures will affect only the e2e_test_region
-namespace e2e_test {
-namespace {
-const uint32_t version = 2;
-}
-static const std::size_t E2EManagerTestRegionLayout_size = 16;
-static const std::size_t E2EMemoryFill_size = 64;
-static const std::size_t E2EPrimaryTestRegionLayout_size = 84;
-static const std::size_t E2ESecondaryTestRegionLayout_size = 84;
-static const std::size_t E2ETestRegionLayout_size = 84;
-static const std::size_t E2ETestStageRegister_size = 4;
-static const std::size_t E2EUnfindableRegionLayout_size = 84;
-static const std::size_t E2EManagedTestRegionLayout_size = 4;
-}  // namespace e2e_test
+template <typename T>
+class VersionInfo {
+ public:
+  constexpr static size_t size = -1;
+};
 
 // Versioning information for audio_data_layout.h
 // Changes to these structures will affect only the audio_data region
-namespace audio_data {
-namespace {
-const uint32_t version = 0;
-}
-// One circular queue of with a 16KB buffer, a 32 bits spinlock and
-// two 32 bits integers.
-static const std::size_t AudioDataLayout_size = 16384 + 3 * 4;
-}  // namespace audio_data
+template <>
+class VersionInfo<audio_data::AudioDataLayout> {
+ public:
+  // One circular queue of with a 16KB buffer, a 32 bits spinlock and
+  // two 32 bits integers.
+  constexpr static size_t size = 16384 + 3 * 4;
+};
 
-}  // namespace version_info
+// Versioning information for e2e_test_region.h
+// Changes to these structures will affect only the e2e_test_region
+template <>
+class VersionInfo<e2e_test::E2EManagerTestRegionLayout> {
+ public:
+  constexpr static size_t size = 16;
+};
+template <>
+class VersionInfo<e2e_test::E2EPrimaryTestRegionLayout> {
+ public:
+  constexpr static size_t size = 84;
+};
+template <>
+class VersionInfo<e2e_test::E2ESecondaryTestRegionLayout> {
+ public:
+  constexpr static size_t size = 84;
+};
+template <>
+class VersionInfo<e2e_test::E2ETestRegionLayout> {
+ public:
+  constexpr static size_t size = 84;
+};
+template <>
+class VersionInfo<e2e_test::E2EUnfindableRegionLayout> {
+ public:
+  constexpr static size_t size = 84;
+};
+template <>
+class VersionInfo<e2e_test::E2EManagedTestRegionLayout> {
+ public:
+  constexpr static size_t size = 4;
+};
+
+// Versioning information for gralloc_layout.h
+// Changes to these structures will affect only the gralloc region
+template <>
+class VersionInfo<gralloc::GrallocManagerLayout> {
+ public:
+  constexpr static size_t size = 80;
+};
+template <>
+class VersionInfo<gralloc::GrallocBufferLayout> {
+ public:
+  constexpr static size_t size = 1;
+};
+
+// Versioning information for input_events_layout.h
+// Changes to these structures will affect only the input_events region
+template <>
+class VersionInfo<input_events::InputEventsLayout> {
+ public:
+  // Three circular queues, each with a 1024 bytes buffer, a 32 bits spinlock
+  // and two 32 bits integers.
+  constexpr static size_t size = 3 * (1024 + 3 * 4);
+};
+
+// Versioning information for ril_layout.h
+template <>
+class VersionInfo<ril::RilLayout> {
+ public:
+  constexpr static size_t size = 68;
+};
+
+// Versioning information for screen_layout.h
+// Changes to these structures will affect only the screen region.
+template <>
+class VersionInfo<screen::ScreenLayout> {
+ public:
+  constexpr static size_t size = 112;
+};
+
+// Versioning Information for socket_forward_layout.h
+template <>
+class VersionInfo<socket_forward::SocketForwardLayout> {
+ public:
+  constexpr static size_t size = ((((65548 + 4)  // queue + state
+                                    * 2)     // host_to_guest and guest_to_host
+                                   + 4 + 4)  // port and state_lock
+                                  * socket_forward::kNumQueues) +
+                                 4     // seq_num
+                                 + 4;  // generation number
+};
+
+// Versioning information for wifi_layout.h
+template <>
+class VersionInfo<wifi::WifiExchangeLayout> {
+ public:
+  constexpr static size_t size =
+      65548 +  // sizeof(CircularPacketQueue<16, 8192>) - forward
+      65548 +  // sizeof(CircularPacketQueue<16, 8192>) - reverse
+      6 +      // uint8_t[6] MAC address.
+      6;       // uint8_t[6] MAC address.
+};
+
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/wifi_exchange_layout.h b/common/vsoc/shm/wifi_exchange_layout.h
index 93f1a9e..3eaa1b6 100644
--- a/common/vsoc/shm/wifi_exchange_layout.h
+++ b/common/vsoc/shm/wifi_exchange_layout.h
@@ -18,7 +18,6 @@
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/circqueue.h"
 #include "common/vsoc/shm/lock.h"
-#include "common/vsoc/shm/version.h"
 
 // Memory layout for wifi packet exchange region.
 namespace vsoc {
@@ -39,8 +38,6 @@
   static const char* region_name;
 };
 
-ASSERT_SHM_COMPATIBLE(WifiExchangeLayout, wifi);
-
 }  // namespace wifi
 }  // namespace layout
 }  // namespace vsoc