diff --git a/private/file_contexts b/private/file_contexts
index 6687144910a186cc5d98e2e1c7a6d8ad04a5cf37..7a52e5cd27f29f234cb25e329c2596188cb93078 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -256,6 +256,7 @@
 /system/etc/selinux/plat_seapp_contexts  u:object_r:seapp_contexts_file:s0
 /system/etc/selinux/plat_sepolicy.cil       u:object_r:sepolicy_file:s0
 /system/etc/selinux/plat_sepolicy.cil.sha256 u:object_r:sepolicy_file:s0
+/system/bin/vr_hwc               u:object_r:vr_hwc_exec:s0
 
 #############################
 # Vendor files
diff --git a/private/service_contexts b/private/service_contexts
index db2e9f6c2bafaab04d97ac3a77728cda3a7b3f08..a65cb01a23b8823bb1f6483d3248c3a75d89f7d5 100644
--- a/private/service_contexts
+++ b/private/service_contexts
@@ -157,6 +157,7 @@ vibrator                                  u:object_r:vibrator_service:s0
 virtual_touchpad                          u:object_r:virtual_touchpad_service:s0
 voiceinteraction                          u:object_r:voiceinteraction_service:s0
 vr_window_manager                         u:object_r:vr_window_manager_service:s0
+vr_hwc                                    u:object_r:vr_hwc_service:s0
 vrmanager                                 u:object_r:vr_manager_service:s0
 wallpaper                                 u:object_r:wallpaper_service:s0
 webviewupdate                             u:object_r:webviewupdate_service:s0
diff --git a/private/system_app.te b/private/system_app.te
index 1e2245f987fd010f81e834f2fd75b97206f7e6b8..bab49c13d4e4365b4870e1f3817ccb38b8c18b4c 100644
--- a/private/system_app.te
+++ b/private/system_app.te
@@ -57,7 +57,7 @@ binder_call(system_app, incidentd)
 
 allow system_app servicemanager:service_manager list;
 # TODO: scope this down? Too broad?
-allow system_app { service_manager_type -netd_service -dumpstate_service -installd_service -virtual_touchpad_service }:service_manager find;
+allow system_app { service_manager_type -netd_service -dumpstate_service -installd_service -virtual_touchpad_service -vr_hwc_service }:service_manager find;
 
 allow system_app keystore:keystore_key {
     get_state
diff --git a/private/vr_hwc.te b/private/vr_hwc.te
new file mode 100644
index 0000000000000000000000000000000000000000..51d24206197e7a00519da1e6a0c285b6d6e4bc8b
--- /dev/null
+++ b/private/vr_hwc.te
@@ -0,0 +1,4 @@
+typeattribute vr_hwc coredomain;
+
+# Daemon started by init.
+init_daemon_domain(vr_hwc)
diff --git a/public/dumpstate.te b/public/dumpstate.te
index 9b54329773228a4e91250270f64a8c6d8d3f291d..bfbb43bcaf879b206eb9884fcd57cf983454a8cd 100644
--- a/public/dumpstate.te
+++ b/public/dumpstate.te
@@ -170,7 +170,7 @@ userdebug_or_eng(`
   allow dumpstate misc_logd_file:file r_file_perms;
 ')
 
-allow dumpstate { service_manager_type -gatekeeper_service -dumpstate_service -incident_service -virtual_touchpad_service }:service_manager find;
+allow dumpstate { service_manager_type -gatekeeper_service -dumpstate_service -incident_service -virtual_touchpad_service -vr_hwc_service }:service_manager find;
 allow dumpstate servicemanager:service_manager list;
 
 allow dumpstate devpts:chr_file rw_file_perms;
diff --git a/public/service.te b/public/service.te
index 444f82a5796dd6e52b4b0f267920556f0178183b..f8fa174feb4060bc2712816625a2ea7e815d588b 100644
--- a/public/service.te
+++ b/public/service.te
@@ -28,6 +28,7 @@ type system_app_service,        service_manager_type;
 type update_engine_service,     service_manager_type;
 type virtual_touchpad_service,  service_manager_type;
 type vr_window_manager_service, service_manager_type;
+type vr_hwc_service,            service_manager_type;
 
 # system_server_services broken down
 type accessibility_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
diff --git a/public/shell.te b/public/shell.te
index 0e55f84909cf4bef0aa5d221aab1c20afa7411ad..caf93ca63670f4fba77b1b56815109cb9e1f17ad 100644
--- a/public/shell.te
+++ b/public/shell.te
@@ -82,7 +82,7 @@ allow shell servicemanager:service_manager list;
 # don't allow shell to access GateKeeper service
 # TODO: why is this so broad? Tightening candidate? It needs at list:
 # - dumpstate_service (so it can receive dumpstate progress updates)
-allow shell { service_manager_type -gatekeeper_service -incident_service -installd_service -netd_service -virtual_touchpad_service }:service_manager find;
+allow shell { service_manager_type -gatekeeper_service -incident_service -installd_service -netd_service -virtual_touchpad_service -vr_hwc_service }:service_manager find;
 allow shell dumpstate:binder call;
 
 # allow shell to get information from hwservicemanager
diff --git a/public/vr_hwc.te b/public/vr_hwc.te
new file mode 100644
index 0000000000000000000000000000000000000000..b0d3ad927f05b0fe37b6dd18e89e568924f5c06b
--- /dev/null
+++ b/public/vr_hwc.te
@@ -0,0 +1,29 @@
+type vr_hwc, domain;
+type vr_hwc_exec, exec_type, file_type;
+
+# Get buffer metadata.
+hal_client_domain(vr_hwc, hal_graphics_allocator)
+
+binder_use(vr_hwc)
+binder_service(vr_hwc)
+
+binder_call(vr_hwc, surfaceflinger)
+binder_call(vr_hwc, vr_wm)
+
+add_service(vr_hwc, vr_hwc_service)
+
+# Hosts the VR HWC implementation and provides a simple Binder interface for VR
+# Window Manager to receive the layers/buffers.
+hwbinder_use(vr_hwc)
+
+# Load vendor libraries.
+allow vr_hwc system_file:dir r_dir_perms;
+
+allow vr_hwc ion_device:chr_file r_file_perms;
+
+# Allow connection to VR DisplayClient to get the primary display metadata
+# (ie: size).
+use_pdx(vr_hwc, surfaceflinger)
+
+# Limit access so only vr_wm can connect.
+neverallow { domain -vr_hwc -vr_wm } vr_hwc_service:service_manager find;
diff --git a/public/vr_wm.te b/public/vr_wm.te
index deedb0a0041ed351a3a34692e261e68bc690de86..1e486097d364be0fb5a79d3cacbe61d9b2a3c6ac 100644
--- a/public/vr_wm.te
+++ b/public/vr_wm.te
@@ -4,18 +4,15 @@ type vr_wm_exec, exec_type, file_type;
 hal_client_domain(vr_wm, hal_graphics_allocator)
 
 binder_use(vr_wm)
-binder_call(vr_wm, surfaceflinger)
 binder_call(vr_wm, virtual_touchpad)
+binder_call(vr_wm, vr_hwc)
 
 allow vr_wm virtual_touchpad_service:service_manager find;
+allow vr_wm vr_hwc_service:service_manager find;
 
 binder_service(vr_wm)
 add_service(vr_wm, vr_window_manager_service)
 
-# Hosts the VR HWC implementation and provides a simple Binder interface for VR
-# Window Manager to receive the layers/buffers.
-hwbinder_use(vr_wm)
-
 # Load vendor libraries.
 allow vr_wm system_file:dir r_dir_perms;