diff --git a/private/compat/26.0/26.0.ignore.cil b/private/compat/26.0/26.0.ignore.cil
index fdc672abc7f412d6ac05978104bca81d61d5692f..edbf97ff526503bd1ad4d7e81588c3b136df9c11 100644
--- a/private/compat/26.0/26.0.ignore.cil
+++ b/private/compat/26.0/26.0.ignore.cil
@@ -42,7 +42,8 @@
     wpantund
     wpantund_exec
     wpantund_service
-    wpantund_tmpfs))
+    wpantund_tmpfs
+    wm_trace_data_file))
 
 ;; private_objects - a collection of types that were labeled differently in
 ;;     older policy, but that should not remain accessible to vendor policy.
diff --git a/private/dumpstate.te b/private/dumpstate.te
index b8f81526cddc1f713b42a4f2e83c97882c1d82dd..24a57de96d0cf29f95f020990d52020327b3d76f 100644
--- a/private/dumpstate.te
+++ b/private/dumpstate.te
@@ -18,6 +18,12 @@ allow dumpstate debugfs_trace_marker:file getattr;
 allow dumpstate atrace_exec:file rx_file_perms;
 allow dumpstate storaged_exec:file rx_file_perms;
 
+# /data/misc/wmtrace for wm traces
+userdebug_or_eng(`
+  allow dumpstate wm_trace_data_file:dir r_dir_perms;
+  allow dumpstate wm_trace_data_file:file r_file_perms;
+')
+
 # Allow dumpstate to make binder calls to storaged service
 binder_call(dumpstate, storaged)
 
diff --git a/private/file.te b/private/file.te
index 6994202ea83a145bb4d7997725196079f7e16efb..5b4dbc804f0d635bdb74b67e4ce5bcf69c6a23b2 100644
--- a/private/file.te
+++ b/private/file.te
@@ -3,3 +3,6 @@ type config_gz, fs_type;
 
 # /data/misc/storaged
 type storaged_data_file, file_type, data_file_type, core_data_file_type;
+
+# /data/misc/wmtrace for wm traces
+type wm_trace_data_file, file_type, data_file_type, core_data_file_type;
diff --git a/private/file_contexts b/private/file_contexts
index 05c36c3d1b6a36ed943e6be388f960093e24e00f..b93168b3e865ccbbe01b5e7c871d0c6a9bc177ef 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -390,6 +390,7 @@
 /data/misc/update_engine_log(/.*)?  u:object_r:update_engine_log_data_file:s0
 /data/system/heapdump(/.*)?     u:object_r:heapdump_data_file:s0
 /data/misc/trace(/.*)?          u:object_r:method_trace_data_file:s0
+/data/misc/wmtrace(/.*)?        u:object_r:wm_trace_data_file:s0
 # TODO(calin) label profile reference differently so that only
 # profman run as a special user can write to them
 /data/misc/profiles/cur(/.*)?       u:object_r:user_profile_data_file:s0
diff --git a/private/surfaceflinger.te b/private/surfaceflinger.te
index ed67597e627a4bd82f3286d5eaad43a78ecfc723..5fbd9ab263cefc5035ce9f0cb33d7922670e2d1e 100644
--- a/private/surfaceflinger.te
+++ b/private/surfaceflinger.te
@@ -52,6 +52,12 @@ set_prop(surfaceflinger, ctl_bootanim_prop)
 allow surfaceflinger appdomain:fd use;
 allow surfaceflinger app_data_file:file { read write };
 
+# Allow writing surface traces to /data/misc/wmtrace.
+userdebug_or_eng(`
+  allow surfaceflinger wm_trace_data_file:dir rw_dir_perms;
+  allow surfaceflinger wm_trace_data_file:file { getattr setattr create w_file_perms };
+')
+
 # Use socket supplied by adbd, for cmd gpu vkjson etc.
 allow surfaceflinger adbd:unix_stream_socket { read write getattr };
 
diff --git a/private/system_server.te b/private/system_server.te
index d2a0c5e28ef774427641d59c487f4e81e17f01d1..e2b57204fb0b7510ad1c06b25aabbf808d1ffe97 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -641,6 +641,10 @@ userdebug_or_eng(`
 
   # Allow system server to read dmesg
   allow system_server kernel:system syslog_read;
+
+  # Allow writing window traces in /data/misc/wmtrace.
+  allow system_server wm_trace_data_file:dir rw_dir_perms;
+  allow system_server wm_trace_data_file:file { getattr setattr create w_file_perms };
 ')
 
 # For AppFuse.