diff --git a/dumpstate.te b/dumpstate.te
index 667c8fc6b56674092a6bf726554d2128deea05a6..28541209987bb64b37bfd601258dbd8c13bfec6d 100644
--- a/dumpstate.te
+++ b/dumpstate.te
@@ -48,9 +48,9 @@ allow dumpstate { appdomain autoplay_app system_server }:process signal;
 
 # Signal native processes to dump their stack.
 # This list comes from native_processes_to_dump in dumpstate/utils.c
-allow dumpstate { audioserver drmserver mediaserver mediaextractor sdcardd surfaceflinger }:process signal;
+allow dumpstate { audioserver drmserver mediaserver mediacodec mediaextractor sdcardd surfaceflinger }:process signal;
 # Ask debuggerd for the backtraces of these processes.
-allow dumpstate { audioserver drmserver mediaserver mediaextractor sdcardd surfaceflinger }:debuggerd dump_backtrace;
+allow dumpstate { audioserver drmserver mediaserver mediacodec mediaextractor sdcardd surfaceflinger }:debuggerd dump_backtrace;
 
 # Execute and transition to the vdc domain
 domain_auto_trans(dumpstate, vdc_exec, vdc)
diff --git a/file_contexts b/file_contexts
index 0a25389ad0b4eee8cd955b7464c7b5b94de01696..8f42ce2bd631ffeae739668536afb33064d82d1f 100644
--- a/file_contexts
+++ b/file_contexts
@@ -167,6 +167,7 @@
 /system/bin/audioserver	u:object_r:audioserver_exec:s0
 /system/bin/mediaserver	u:object_r:mediaserver_exec:s0
 /system/bin/mediaextractor	u:object_r:mediaextractor_exec:s0
+/system/bin/mediacodec	u:object_r:mediacodec_exec:s0
 /system/bin/mdnsd	u:object_r:mdnsd_exec:s0
 /system/bin/installd	u:object_r:installd_exec:s0
 /system/bin/keystore	u:object_r:keystore_exec:s0
diff --git a/mediacodec.te b/mediacodec.te
new file mode 100644
index 0000000000000000000000000000000000000000..7cc7765fb1ab73c63e2463a8fb817d98826b58e1
--- /dev/null
+++ b/mediacodec.te
@@ -0,0 +1,46 @@
+# mediacodec - multimedia daemon
+type mediacodec, domain, domain_deprecated;
+type mediacodec_exec, exec_type, file_type;
+
+typeattribute mediacodec mlstrustedsubject;
+
+init_daemon_domain(mediacodec)
+
+binder_use(mediacodec)
+binder_call(mediacodec, binderservicedomain)
+binder_call(mediacodec, appdomain)
+binder_service(mediacodec)
+
+allow mediacodec kernel:system module_request;
+allow mediacodec gpu_device:chr_file rw_file_perms;
+allow mediacodec video_device:dir r_dir_perms;
+allow mediacodec video_device:chr_file rw_file_perms;
+
+# Needed on some devices for playing DRM protected content,
+# but seems expected and appropriate for all devices.
+unix_socket_connect(mediacodec, drmserver, drmserver)
+
+allow mediacodec drmserver_service:service_manager find;
+allow mediacodec mediacodec_service:service_manager { add find };
+allow mediacodec processinfo_service:service_manager find;
+allow mediacodec surfaceflinger_service:service_manager find;
+
+use_drmservice(mediacodec)
+allow mediacodec drmserver:drmservice {
+    consumeRights
+    setPlaybackStatus
+    openDecryptSession
+    closeDecryptSession
+    initializeDecryptUnit
+    decrypt
+    finalizeDecryptUnit
+    pread
+};
+
+###
+### neverallow rules
+###
+
+# mediacodec should never execute any executable without a
+# domain transition
+neverallow mediacodec { file_type fs_type }:file execute_no_trans;
diff --git a/mediaserver.te b/mediaserver.te
index 8b5b5d5c09f7888744015a451a80c723c060e383..ccd633bc6a9ee8fc16912b10aa8a75fc79f5662e 100644
--- a/mediaserver.te
+++ b/mediaserver.te
@@ -85,6 +85,7 @@ allow mediaserver cameraproxy_service:service_manager find;
 allow mediaserver batterystats_service:service_manager find;
 allow mediaserver drmserver_service:service_manager find;
 allow mediaserver mediaextractor_service:service_manager find;
+allow mediaserver mediacodec_service:service_manager find;
 allow mediaserver mediaserver_service:service_manager { add find };
 allow mediaserver media_session_service:service_manager find;
 allow mediaserver permission_service:service_manager find;
diff --git a/nfc.te b/nfc.te
index e02c119d3734ba944ba8bd049d43724a09b183e2..9cf8c5de60dba1900550b96818586b7ab6725af4 100644
--- a/nfc.te
+++ b/nfc.te
@@ -21,6 +21,7 @@ allow nfc audioserver_service:service_manager find;
 allow nfc drmserver_service:service_manager find;
 allow nfc mediaserver_service:service_manager find;
 allow nfc mediaextractor_service:service_manager find;
+allow nfc mediacodec_service:service_manager find;
 allow nfc nfc_service:service_manager { add find };
 allow nfc radio_service:service_manager find;
 allow nfc surfaceflinger_service:service_manager find;
diff --git a/platform_app.te b/platform_app.te
index e5cd0a66020e742cffc2ec1a9c4cd0ce875a47b0..0c983840f298a58e59d41758bce8a989d9bb19c4 100644
--- a/platform_app.te
+++ b/platform_app.te
@@ -42,6 +42,7 @@ allow platform_app audioserver_service:service_manager find;
 allow platform_app drmserver_service:service_manager find;
 allow platform_app mediaserver_service:service_manager find;
 allow platform_app mediaextractor_service:service_manager find;
+allow platform_app mediacodec_service:service_manager find;
 allow platform_app persistent_data_block_service:service_manager find;
 allow platform_app radio_service:service_manager find;
 allow platform_app surfaceflinger_service:service_manager find;
diff --git a/priv_app.te b/priv_app.te
index d31bf477aed7969a2960bc55dbbbd9d8fa2622a1..818f5cc60e7ed339eb359c6f308b1b6648ba0715 100644
--- a/priv_app.te
+++ b/priv_app.te
@@ -23,6 +23,7 @@ allow priv_app audioserver_service:service_manager find;
 allow priv_app drmserver_service:service_manager find;
 allow priv_app mediaserver_service:service_manager find;
 allow priv_app mediaextractor_service:service_manager find;
+allow priv_app mediacodec_service:service_manager find;
 allow priv_app nfc_service:service_manager find;
 allow priv_app radio_service:service_manager find;
 allow priv_app surfaceflinger_service:service_manager find;
diff --git a/service.te b/service.te
index 6c284e6680169174ef2e3f51f073a5b955acc17e..b9618b6060535e6f54644de53705a68e7014b0d9 100644
--- a/service.te
+++ b/service.te
@@ -9,6 +9,7 @@ type inputflinger_service,      service_manager_type;
 type keystore_service,          service_manager_type;
 type mediaserver_service,       service_manager_type;
 type mediaextractor_service,    service_manager_type;
+type mediacodec_service,        service_manager_type;
 type nfc_service,               service_manager_type;
 type radio_service,             service_manager_type;
 type surfaceflinger_service,    service_manager_type;
diff --git a/service_contexts b/service_contexts
index 58120c0716ce4103754ba595758bf10e9b47630b..d570371544c167514aaebf4f71f3a13de5e9dacf 100644
--- a/service_contexts
+++ b/service_contexts
@@ -68,6 +68,7 @@ media.camera.proxy                        u:object_r:cameraproxy_service:s0
 media.log                                 u:object_r:audioserver_service:s0
 media.player                              u:object_r:mediaserver_service:s0
 media.extractor                           u:object_r:mediaextractor_service:s0
+media.codec                               u:object_r:mediacodec_service:s0
 media.resource_manager                    u:object_r:mediaserver_service:s0
 media.radio                               u:object_r:audioserver_service:s0
 media.sound_trigger_hw                    u:object_r:audioserver_service:s0
diff --git a/system_server.te b/system_server.te
index 55c3fff0a297613f38ca28459fd1c72a674e8192..b198005ba47022f43f572858966d6866767f2d15 100644
--- a/system_server.te
+++ b/system_server.te
@@ -138,12 +138,13 @@ binder_call(system_server, dumpstate)
 binder_service(system_server)
 
 # Ask debuggerd to dump backtraces for native stacks of interest.
-allow system_server { audioserver mediaserver mediaextractor sdcardd surfaceflinger inputflinger }:debuggerd dump_backtrace;
+allow system_server { audioserver mediaserver mediacodec mediaextractor sdcardd surfaceflinger inputflinger }:debuggerd dump_backtrace;
 
 # Read /proc/pid files for dumping stack traces of native processes.
 r_dir_file(system_server, audioserver)
 r_dir_file(system_server, mediaserver)
 r_dir_file(system_server, mediaextractor)
+r_dir_file(system_server, mediacodec)
 r_dir_file(system_server, sdcardd)
 r_dir_file(system_server, surfaceflinger)
 r_dir_file(system_server, inputflinger)
@@ -387,6 +388,7 @@ allow system_server gatekeeper_service:service_manager find;
 allow system_server fingerprintd_service:service_manager find;
 allow system_server mediaserver_service:service_manager find;
 allow system_server mediaextractor_service:service_manager find;
+allow system_server mediacodec_service:service_manager find;
 allow system_server nfc_service:service_manager find;
 allow system_server radio_service:service_manager find;
 allow system_server system_server_service:service_manager { add find };
diff --git a/untrusted_app.te b/untrusted_app.te
index 333f1f4af2539a0c217f131f56800073a81fa36c..459341404fdd0f47909a6b67fcaa7eee26df6e33 100644
--- a/untrusted_app.te
+++ b/untrusted_app.te
@@ -71,6 +71,7 @@ allow untrusted_app drmserver_service:service_manager find;
 allow untrusted_app healthd_service:service_manager find;
 allow untrusted_app mediaserver_service:service_manager find;
 allow untrusted_app mediaextractor_service:service_manager find;
+allow untrusted_app mediacodec_service:service_manager find;
 allow untrusted_app nfc_service:service_manager find;
 allow untrusted_app radio_service:service_manager find;
 allow untrusted_app surfaceflinger_service:service_manager find;