Merge "incidentd: Add missing va_end()"
diff --git a/Android.bp b/Android.bp
index 351704a..67b088c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1445,8 +1445,6 @@
     name: "hiddenapi-mappings",
     defaults: ["metalava-api-stubs-default"],
     srcs: [
-        ":non_openjdk_java_files",
-        ":openjdk_java_files",
         ":opt-telephony-common-srcs",
     ],
 
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 5e5a04b..518a29c 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -583,7 +583,11 @@
                         } catch (IllegalArgumentException e) {
                             installer = "";
                         }
-                        sStatsd.informOnePackage(app, uid, pi.getLongVersionCode(), pi.versionName,
+                        sStatsd.informOnePackage(
+                                app,
+                                uid,
+                                pi.getLongVersionCode(),
+                                pi.versionName == null ? "" : pi.versionName,
                                 installer == null ? "" : installer);
                     }
                 } catch (Exception e) {
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 8fbbcf4..d59ee92 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -145,7 +145,7 @@
         boolean onSingleTapConfirmed(MotionEvent e);
  
         /**
-         * Notified when a double-tap occurs.
+         * Notified when a double-tap occurs. Triggered on the down event of second tap.
          *
          * @param e The down motion event of the first tap of the double-tap.
          * @return true if the event is consumed, else false
@@ -378,7 +378,9 @@
      *
      * @param context the application's context
      * @param listener the listener invoked for all the callbacks, this must
-     * not be null.
+     * not be null. If the listener implements the {@link OnDoubleTapListener} or
+     * {@link OnContextClickListener} then it will also be set as the listener for
+     * these callbacks (for example when using the {@link SimpleOnGestureListener}).
      *
      * @throws NullPointerException if {@code listener} is null.
      */
@@ -393,7 +395,9 @@
      *
      * @param context the application's context
      * @param listener the listener invoked for all the callbacks, this must
-     * not be null.
+     * not be null. If the listener implements the {@link OnDoubleTapListener} or
+     * {@link OnContextClickListener} then it will also be set as the listener for
+     * these callbacks (for example when using the {@link SimpleOnGestureListener}).
      * @param handler the handler to use for running deferred listener events.
      *
      * @throws NullPointerException if {@code listener} is null.
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index b752396..db91dc5 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -863,11 +863,7 @@
                         XmlUtils.skipCurrentTag(parser);
                     } break;
                     case "component-override": {
-                        if (allowAppConfigs) {
-                            readComponentOverrides(parser, permFile);
-                        } else {
-                            logNotAllowedInPartition(name, permFile, parser);
-                        }
+                        readComponentOverrides(parser, permFile);
                         XmlUtils.skipCurrentTag(parser);
                     } break;
                     case "backup-transport-whitelisted-service": {
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4fb03d6..e74cbb1 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -299,13 +299,13 @@
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Μικρόφωνο"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ηχογραφεί"</string>
     <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; η εγγραφή ήχου;"</string>
-    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Σωματική δραστηριότητα"</string>
+    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Σωματική δραστ/τητα"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"πρόσβαση στη σωματική σας δραστηριότητα"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στη σωματική σας δραστηριότητα;"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Κάμερα"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"γίνεται λήψη φωτογραφιών και εγγραφή βίντεο"</string>
     <string name="permgrouprequest_camera" msgid="1299833592069671756">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; η λήψη φωτογραφιών και η εγγραφή βίντεο;"</string>
-    <string name="permgrouplab_calllog" msgid="8798646184930388160">"Αρχεία καταγραφής κλήσεων"</string>
+    <string name="permgrouplab_calllog" msgid="8798646184930388160">"Αρχεία καταγρ. κλήσ."</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"ανάγνωση και εγγραφή αρχείου καταγραφής τηλεφωνικών κλήσεων"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στα αρχεία καταγραφής τηλεφωνικών κλήσεών σας;"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Τηλέφωνο"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 32530d3..02c8043 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -299,7 +299,7 @@
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrer des fichiers audio"</string>
     <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à enregistrer l\'audio?"</string>
-    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"données d\'activité physique"</string>
+    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Activité physique"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"accéder à vos activités physiques"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder à vos activités physiques?"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Appareil photo"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 86e8b36..2888a53 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -304,13 +304,13 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה לתמונות, למדיה ולקבצים במכשיר?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"מיקרופון"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"הקלטת אודיו"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאה להקליט אודיו?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"‏לאשר לאפליקציית &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; להקליט אודיו?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"פעילות גופנית"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"גישה לפעילות הגופנית שלך"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"‏האם לאפשר לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; גישה לפעילות הגופנית שלך?"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"מצלמה"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"צילום תמונות והקלטת וידאו"</string>
-    <string name="permgrouprequest_camera" msgid="1299833592069671756">"‏לאשר לאפליקציה של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; לצלם תמונות וסרטונים?"</string>
+    <string name="permgrouprequest_camera" msgid="1299833592069671756">"‏לאשר לאפליקציית &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; לצלם תמונות וסרטונים?"</string>
     <string name="permgrouplab_calllog" msgid="8798646184930388160">"יומני שיחות"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"קריאה וכתיבה של יומן השיחות של הטלפון"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה ליומני השיחות של הטלפון?"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 904f8b0..3fb6766 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -305,13 +305,13 @@
     <string name="permgrouplab_camera" msgid="4820372495894586615">"ಕ್ಯಾಮರಾ"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"ಚಿತ್ರಗಳನ್ನು ತೆಗೆಯಲು, ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಲು"</string>
     <string name="permgrouprequest_camera" msgid="1299833592069671756">"ಚಿತ್ರಗಳನ್ನು ಸೆರೆಹಿಡಿಯಲು ಮತ್ತು ವೀಡಿಯೊ ರೆಕಾರ್ಡ್‌ ಮಾಡಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
-    <string name="permgrouplab_calllog" msgid="8798646184930388160">"ಕರೆಯ ಲಾಗ್‌ಗಳು"</string>
+    <string name="permgrouplab_calllog" msgid="8798646184930388160">"ಕರೆಯ ಲಾಗ್‌"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"ಪೋನ್‌ ಕರೆಯ ಲಾಗ್‌ ಅನ್ನು ಓದಿ ಮತ್ತು ಬರೆಯಿರಿ"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"ನಿಮ್ಮ ಫೋನ್‌ ಕರೆಯ ಲಾಗ್‌ಗಳಿಗೆ ಪ್ರವೇಶ ಪಡೆಯಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"ಫೋನ್"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"ಫೋನ್ ಕರೆ ಮಾಡಲು ಹಾಗೂ ನಿರ್ವಹಿಸಲು"</string>
     <string name="permgrouprequest_phone" msgid="9166979577750581037">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ನಿರ್ವಹಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
-    <string name="permgrouplab_sensors" msgid="4838614103153567532">"ದೇಹದ ಸೆನ್ಸರ್‌ಗಳು"</string>
+    <string name="permgrouplab_sensors" msgid="4838614103153567532">"ದೇಹದ ಸೆನ್ಸರ್‌"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ನಿಮ್ಮ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಕುರಿತು ಸೆನ್ಸಾರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
     <string name="permgrouprequest_sensors" msgid="6349806962814556786">"ನಿಮ್ಮ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಕುರಿತು ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆಯುತ್ತದೆ"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index dcb766d..db54c42 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -305,7 +305,7 @@
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"сүрөт жана видео тартууга"</string>
     <string name="permgrouprequest_camera" msgid="1299833592069671756">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна сүрөттөр менен видеолорду тартканга уруксат бересизби?"</string>
-    <string name="permgrouplab_calllog" msgid="8798646184930388160">"Чалуулар тизмелери"</string>
+    <string name="permgrouplab_calllog" msgid="8798646184930388160">"Чалуулар тизмеси"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"телефондогу чалуулар тизмесин окуу жана жазуу"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна телефондогу чалуулар тизмесин пайдаланууга уруксат берилсинби?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index f1a6136..82ec2b6 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -301,13 +301,13 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să acceseze fotografiile, conținutul media și fișierele de pe dispozitiv?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistreze sunet"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Pemiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să înregistreze conținut audio?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Pemiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să înregistreze audio?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Activitate fizică"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"accesați activitatea fizică"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Permiteți aplicației &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să vă acceseze activitatea fizică?"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera foto"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografieze și să înregistreze videoclipuri"</string>
-    <string name="permgrouprequest_camera" msgid="1299833592069671756">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să facă fotografii și să înregistreze videoclipuri?"</string>
+    <string name="permgrouprequest_camera" msgid="1299833592069671756">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să fotografieze și să înregistreze video?"</string>
     <string name="permgrouplab_calllog" msgid="8798646184930388160">"Jurnale de apeluri"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"să citească și să scrie jurnalul de apeluri telefonice"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să vă acceseze jurnalele de apeluri?"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 1549f4d..18a8794 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -310,7 +310,7 @@
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prístup k vašej fyzickej aktivite?"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotenie a natáčanie videí"</string>
-    <string name="permgrouprequest_camera" msgid="1299833592069671756">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; snímať fotky a zaznamenávať video?"</string>
+    <string name="permgrouprequest_camera" msgid="1299833592069671756">"Chcete povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; fotiť a nahrávať video?"</string>
     <string name="permgrouplab_calllog" msgid="8798646184930388160">"Zoznam hovorov"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"čítať a zapisovať do zoznamu hovorov"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prístup k zoznamu hovorov?"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 5431796..fd77532 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1234,7 +1234,7 @@
     <string name="volume_unknown" msgid="1400219669770445902">"ระดับเสียง"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ระดับบลูทูธ"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"ระดับเสียงเรียกเข้า"</string>
-    <string name="volume_icon_description_incall" msgid="8890073218154543397">"ปริมาณการโทร"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"ระดับเสียงการโทร"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"ระดับเสียงของสื่อ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"ระดับเสียงของการแจ้งเตือน"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"เสียงเรียกเข้าเริ่มต้น"</string>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index b2859f6..3acbc3a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -92,6 +92,7 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.tv.TvStatusBar;
+import com.android.systemui.theme.ThemeOverlayController;
 import com.android.systemui.util.InjectionInflationController;
 import com.android.systemui.util.leak.GarbageMonitor;
 import com.android.systemui.volume.VolumeUI;
@@ -182,6 +183,18 @@
     public abstract SystemUI bindsSizeCompatModeActivityController(
             SizeCompatModeActivityController sysui);
 
+    /** Inject into SliceBroadcastRelayHandler. */
+    @Binds
+    @IntoMap
+    @ClassKey(SliceBroadcastRelayHandler.class)
+    public abstract SystemUI bindSliceBroadcastRelayHandler(SliceBroadcastRelayHandler sysui);
+
+    /** Inject into ThemeOverlayController. */
+    @Binds
+    @IntoMap
+    @ClassKey(ThemeOverlayController.class)
+    public abstract SystemUI bindThemeOverlayController(ThemeOverlayController sysui);
+
     /** Inject into StatusBar. */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/docs/broadcasts.md b/packages/SystemUI/docs/broadcasts.md
new file mode 100644
index 0000000..56a637f
--- /dev/null
+++ b/packages/SystemUI/docs/broadcasts.md
@@ -0,0 +1,89 @@
+# Using SystemUI's BroadcastDispatcher
+
+## What is this dispatcher?
+
+This is an internal dispatcher class for global broadcasts that SystemUI components want to receive. The dispatcher consolidates most `BroadcastReceiver` that exist in SystemUI by merging the `IntentFilter` and subscribing a single `BroadcastReceiver` per user with the system.
+
+## Why use the dispatcher?
+
+Having a single `BroadcastReceiver` in SystemUI improves the multi dispatch situation that occurs whenever many classes are filtering for the same intent action. In particular:
+* All supported `BroadcastReceiver` will be aggregated into one single receiver per user.
+* Whenever there is a broadcast, the number of IPC calls from `system_server` into SystemUI will be reduced to one per user (plus one for `USER_ALL`). This is meaninful for actions that are filtered by `BroadcastReceiver` in multiple classes.
+*There could be more than one per user in the case of unsupported filters.*
+* The dispatcher immediately moves out of the main thread upon broadcast, giving back control to `system_server`. This improves the total dispatch time for broadcasts and prevents from timing out.
+* The dispatcher significantly reduces time spent in main thread by handling most operations in a background thread and only using the main thread for subscribing/unsubscribind and dispatching where appropriate.
+
+## Should I use the dispatcher?
+
+The dispatcher supports `BroadcastReceiver` dynamic subscriptions in the following cases:
+
+* The `IntentFilter` contains at least one action.
+* The `IntentFilter` may or may not contain categories.
+* The `IntentFilter` **does not** contain data types, data schemes, data authorities or data paths.
+* The broadcast **is not** gated behind a permission.
+
+Additionally, the dispatcher supports the following:
+
+* Subscriptions can be done in any thread.
+* Broadcasts will be dispatched on the main thread (same as `system_server`) by default but a `Handler` can be specified for dispatching
+* A `UserHandle` can be provided to filter the broadcasts by user.
+
+If introducing a new `BroadcastReceiver` (not declared in `AndroidManifest`) that satisfies the constraints above, use the dispatcher to reduce the load on `system_server`.
+
+Do not use the dispatcher to obtain the last broadcast (by passing a null `BroadcastReceiver`). `BroadcastDispatcher#registerReceiver` **does not** return the last sticky Intent.
+
+Additionally, if listening to some broadcast is latency critical (beyond 100ms of latency), consider registering with Context instead.
+
+## How do I use the dispatcher?
+
+Acquire the dispatcher by using `@Inject` to obtain a `BroadcastDispatcher`. Then, use the following methods in that instance. 
+
+### Subscribe
+
+```kotlin
+/**
+    * Register a receiver for broadcast with the dispatcher
+    *
+    * @param receiver A receiver to dispatch the [Intent]
+    * @param filter A filter to determine what broadcasts should be dispatched to this receiver.
+    *               It will only take into account actions and categories for filtering. It must
+    *               have at least one action.
+    * @param handler A handler to dispatch [BroadcastReceiver.onReceive]. By default, it is the
+    *                main handler. Pass `null` to use the default.
+    * @param user A user handle to determine which broadcast should be dispatched to this receiver.
+    *             By default, it is the current user.
+    * @throws IllegalArgumentException if the filter has other constraints that are not actions or
+    *                                  categories or the filter has no actions.
+    */
+@JvmOverloads
+fun registerReceiver(BroadcastReceiver, IntentFilter, Handler? = mainHandler, UserHandle = context.user)
+```
+
+All subscriptions are done with the same overloaded method. As specified in the doc, in order to pass a `UserHandle` with the default `Handler`, pass `null` for the `Handler`.
+
+In the same way as with `Context`, subscribing the same `BroadcastReceiver` for the same user using different filters will result on two subscriptions, not in replacing the filter.
+
+### Unsubscribe
+
+There are two methods to unsubscribe a given `BroadcastReceiver`. One that will remove it for all users and another where the user can be specified. This allows using separate subscriptions of the same receiver for different users and manipulating them separately.
+
+```kotlin
+/**
+    * Unregister receiver for all users.
+    * <br>
+    * This will remove every registration of [receiver], not those done just with [UserHandle.ALL].
+    *
+    * @param receiver The receiver to unregister. It will be unregistered for all users.
+    */
+fun unregisterReceiver(BroadcastReceiver)
+
+/**
+    * Unregister receiver for a particular user.
+    *
+    * @param receiver The receiver to unregister. It will be unregistered for all users.
+    * @param user The user associated to the registered [receiver]. It can be [UserHandle.ALL].
+    */
+fun unregisterReceiverForUser(BroadcastReceiver, UserHandle)
+```
+
+Unregistering can be done even if the `BroadcastReceiver` has never been registered with `BroadcastDispatcher`. In that case, it is a No-Op.
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 6186589..5f92b28 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -89,6 +89,14 @@
         onTaskMovedToFront(taskInfo.taskId);
     }
 
+    /**
+     * Called when a task’s description is changed due to an activity calling
+     * ActivityManagerService.setTaskDescription
+     *
+     * @param taskInfo info about the task which changed, with {@link TaskInfo#taskDescription}
+     */
+    public void onTaskDescriptionChanged(RunningTaskInfo taskInfo) { }
+
     public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { }
     public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) { }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index 8d823ca..074ef53 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -230,6 +230,11 @@
                 .sendToTarget();
     }
 
+    @Override
+    public void onTaskDescriptionChanged(RunningTaskInfo taskInfo) {
+        mHandler.obtainMessage(H.ON_TASK_DESCRIPTION_CHANGED, taskInfo).sendToTarget();
+    }
+
     private final class H extends Handler {
         private static final int ON_TASK_STACK_CHANGED = 1;
         private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -254,6 +259,7 @@
         private static final int ON_TASK_LIST_UPDATED = 21;
         private static final int ON_SINGLE_TASK_DISPLAY_EMPTY = 22;
         private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 23;
+        private static final int ON_TASK_DESCRIPTION_CHANGED = 24;
 
 
         public H(Looper looper) {
@@ -421,6 +427,13 @@
                         }
                         break;
                     }
+                    case ON_TASK_DESCRIPTION_CHANGED: {
+                        final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskDescriptionChanged(info);
+                        }
+                        break;
+                    }
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index 1c30762..ecd8c8d 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -50,14 +50,6 @@
  * allows the user to return to the call.
  */
 public class EmergencyButton extends Button {
-    private static final Intent INTENT_EMERGENCY_DIAL = new Intent()
-            .setAction(EmergencyDialerConstants.ACTION_DIAL)
-            .setPackage("com.android.phone")
-            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                    | Intent.FLAG_ACTIVITY_CLEAR_TOP)
-            .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
-                    EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
 
     private static final String LOG_TAG = "EmergencyButton";
     private final EmergencyAffordanceManager mEmergencyAffordanceManager;
@@ -189,7 +181,15 @@
         } else {
             Dependency.get(KeyguardUpdateMonitor.class).reportEmergencyCallAction(
                     true /* bypassHandler */);
-            getContext().startActivityAsUser(INTENT_EMERGENCY_DIAL,
+            Intent emergencyDialIntent =
+                    getTelecommManager().createLaunchEmergencyDialerIntent(null /* number*/)
+                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                                    | Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                            .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+                                    EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
+
+            getContext().startActivityAsUser(emergencyDialIntent,
                     ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
                     new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 8373fb2..6685db1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -102,6 +102,7 @@
 import com.android.systemui.DumpController;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.MainLooper;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -1502,6 +1503,7 @@
     @VisibleForTesting
     @Inject
     protected KeyguardUpdateMonitor(Context context, @MainLooper Looper mainLooper,
+            BroadcastDispatcher broadcastDispatcher,
             DumpController dumpController) {
         mContext = context;
         mSubscriptionManager = SubscriptionManager.from(context);
@@ -1645,12 +1647,12 @@
         filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
+        broadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, mHandler);
 
         final IntentFilter bootCompleteFilter = new IntentFilter();
         bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
-        context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
+        broadcastDispatcher.registerReceiver(mBroadcastReceiver, bootCompleteFilter, mHandler);
 
         final IntentFilter allUserFilter = new IntentFilter();
         allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
@@ -1661,8 +1663,8 @@
         allUserFilter.addAction(ACTION_USER_UNLOCKED);
         allUserFilter.addAction(ACTION_USER_STOPPED);
         allUserFilter.addAction(ACTION_USER_REMOVED);
-        context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
-                null, mHandler);
+        broadcastDispatcher.registerReceiver(mBroadcastAllReceiver, allUserFilter, mHandler,
+                UserHandle.ALL);
 
         mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
         try {
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 9e2464e..dfabe69 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -32,6 +32,7 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.lifecycle.Observer;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManager.DockEventListener;
@@ -125,9 +126,9 @@
     @Inject
     public ClockManager(Context context, InjectionInflationController injectionInflater,
             PluginManager pluginManager, SysuiColorExtractor colorExtractor,
-            @Nullable DockManager dockManager) {
+            @Nullable DockManager dockManager, BroadcastDispatcher broadcastDispatcher) {
         this(context, injectionInflater, pluginManager, colorExtractor,
-                context.getContentResolver(), new CurrentUserObservable(context),
+                context.getContentResolver(), new CurrentUserObservable(broadcastDispatcher),
                 new SettingsWrapper(context.getContentResolver()), dockManager);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index fef9198..2afcb12 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -51,6 +51,7 @@
 
 import com.android.settingslib.Utils;
 import com.android.settingslib.graph.ThemedBatteryDrawable;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.settings.CurrentUserTracker;
@@ -112,16 +113,13 @@
     private int mNonAdaptedForegroundColor;
     private int mNonAdaptedBackgroundColor;
 
-    public BatteryMeterView(Context context) {
-        this(context, null, 0);
-    }
-
     public BatteryMeterView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
     public BatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        BroadcastDispatcher broadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
 
         setOrientation(LinearLayout.HORIZONTAL);
         setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
@@ -161,7 +159,7 @@
         // Init to not dark at all.
         onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
 
-        mUserTracker = new CurrentUserTracker(mContext) {
+        mUserTracker = new CurrentUserTracker(broadcastDispatcher) {
             @Override
             public void onUserSwitched(int newUserId) {
                 mUser = newUserId;
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 3a8536b..4afa969 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 import android.view.WindowManagerGlobal;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 /**
@@ -45,10 +46,14 @@
 
     private Dialog mNewSessionDialog;
 
-    public void register(Context context) {
+    /**
+     * Register this receiver with the {@link BroadcastDispatcher}
+     *
+     * @param broadcastDispatcher to register the receiver.
+     */
+    public void register(BroadcastDispatcher broadcastDispatcher) {
         IntentFilter f = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        context.registerReceiverAsUser(this, UserHandle.SYSTEM,
-                f, null /* permission */, null /* scheduler */);
+        broadcastDispatcher.registerReceiver(this, f, null /* handler */, UserHandle.SYSTEM);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/LatencyTester.java b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
index 30a60ab..1a47dac 100644
--- a/packages/SystemUI/src/com/android/systemui/LatencyTester.java
+++ b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
@@ -29,6 +29,7 @@
 
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 
 import javax.inject.Inject;
@@ -49,13 +50,16 @@
             "com.android.systemui.latency.ACTION_TURN_ON_SCREEN";
     private final BiometricUnlockController mBiometricUnlockController;
     private final PowerManager mPowerManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     @Inject
     public LatencyTester(Context context, BiometricUnlockController biometricUnlockController,
-            PowerManager powerManager) {
+            PowerManager powerManager, BroadcastDispatcher broadcastDispatcher) {
         super(context);
+
         mBiometricUnlockController = biometricUnlockController;
         mPowerManager = powerManager;
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     @Override
@@ -67,7 +71,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(ACTION_FINGERPRINT_WAKE);
         filter.addAction(ACTION_TURN_ON_SCREEN);
-        mContext.registerReceiver(new BroadcastReceiver() {
+        mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 String action = intent.getAction();
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 8a99e45..ab7eec5 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -67,6 +67,8 @@
 
 import com.android.internal.util.Preconditions;
 import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
@@ -103,6 +105,9 @@
     private final Lazy<StatusBar> mStatusBarLazy;
 
     private DisplayManager mDisplayManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final Handler mMainHandler;
+    private final TunerService mTunerService;
     private DisplayManager.DisplayListener mDisplayListener;
 
     @VisibleForTesting
@@ -140,9 +145,16 @@
     }
 
     @Inject
-    public ScreenDecorations(Context context, Lazy<StatusBar> statusBarLazy) {
+    public ScreenDecorations(Context context,
+            Lazy<StatusBar> statusBarLazy,
+            @MainHandler Handler handler,
+            BroadcastDispatcher broadcastDispatcher,
+            TunerService tunerService) {
         super(context);
         mStatusBarLazy = statusBarLazy;
+        mMainHandler = handler;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mTunerService = tunerService;
     }
 
     @Override
@@ -239,8 +251,7 @@
         mWindowManager.getDefaultDisplay().getMetrics(metrics);
         mDensity = metrics.density;
 
-        Dependency.get(Dependency.MAIN_HANDLER).post(
-                () -> Dependency.get(TunerService.class).addTunable(this, SIZE));
+        mMainHandler.post(() -> mTunerService.addTunable(this, SIZE));
 
         // Watch color inversion and invert the overlay as needed.
         mColorInversionSetting = new SecureSetting(mContext, mHandler,
@@ -255,7 +266,7 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
-        mContext.registerReceiver(mIntentReceiver, filter, null /* permission */, mHandler);
+        mBroadcastDispatcher.registerReceiver(mIntentReceiver, filter, mHandler);
 
         mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java b/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java
index 92fbd25..7a4ef2b 100644
--- a/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java
@@ -28,19 +28,27 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.SliceBroadcastRelay;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
 
 /**
  * Allows settings to register certain broadcasts to launch the settings app for pinned slices.
  * @see SliceBroadcastRelay
  */
+@Singleton
 public class SliceBroadcastRelayHandler extends SystemUI {
     private static final String TAG = "SliceBroadcastRelay";
     private static final boolean DEBUG = false;
 
     private final ArrayMap<Uri, BroadcastRelay> mRelays = new ArrayMap<>();
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
-    public SliceBroadcastRelayHandler(Context context) {
+    @Inject
+    public SliceBroadcastRelayHandler(Context context, BroadcastDispatcher broadcastDispatcher) {
         super(context);
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     @Override
@@ -48,9 +56,10 @@
         if (DEBUG) Log.d(TAG, "Start");
         IntentFilter filter = new IntentFilter(SliceBroadcastRelay.ACTION_REGISTER);
         filter.addAction(SliceBroadcastRelay.ACTION_UNREGISTER);
-        mContext.registerReceiver(mReceiver, filter);
+        mBroadcastDispatcher.registerReceiver(mReceiver, filter);
     }
 
+    // This does not use BroadcastDispatcher as the filter may have schemas or mime types.
     @VisibleForTesting
     void handleIntent(Intent intent) {
         if (SliceBroadcastRelay.ACTION_REGISTER.equals(intent.getAction())) {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index 3ff1b97..9a277e8 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -34,6 +34,7 @@
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -161,6 +162,7 @@
     private final Lazy<SysUiState> mSysUiFlagContainer;
     private final Lazy<WakefulnessLifecycle> mWakefulnessLifecycle;
     private final Lazy<PackageManagerWrapper> mPackageManagerWrapper;
+    private final Lazy<BroadcastDispatcher> mBroadcastDispatcher;
 
     private boolean mOnLockscreen;
     private boolean mIsDozing;
@@ -193,7 +195,8 @@
             Lazy<OverviewProxyService> overviewProxyService,
             Lazy<SysUiState> sysUiFlagContainer,
             Lazy<WakefulnessLifecycle> wakefulnessLifecycle,
-            Lazy<PackageManagerWrapper> packageManagerWrapper) {
+            Lazy<PackageManagerWrapper> packageManagerWrapper,
+            Lazy<BroadcastDispatcher> broadcastDispatcher) {
         mClock = clock;
         mHandler = handler;
         mPhenotypeHelper = phenotypeHelper;
@@ -207,6 +210,7 @@
         for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
             mDefaultHomeIntentFilter.addAction(action);
         }
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     @Override
@@ -215,7 +219,8 @@
         mAssistHandleCallbacks = callbacks;
         mConsecutiveTaskSwitches = 0;
         mDefaultHome = getCurrentDefaultHome();
-        context.registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
+        mBroadcastDispatcher.get()
+                .registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
         mOnLockscreen = onLockscreen(mStatusBarStateController.get().getState());
         mIsDozing = mStatusBarStateController.get().isDozing();
         mStatusBarStateController.get().addCallback(mStatusBarStateListener);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index b7a6167..398826c 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -45,6 +45,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.assist.ui.DefaultUiController;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -161,14 +162,15 @@
             Context context,
             AssistUtils assistUtils,
             AssistHandleBehaviorController handleController,
-            CommandQueue commandQueue) {
+            CommandQueue commandQueue,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mDeviceProvisionedController = controller;
         mCommandQueue = commandQueue;
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         mAssistUtils = assistUtils;
         mAssistDisclosure = new AssistDisclosure(context, new Handler());
-        mPhoneStateMonitor = new PhoneStateMonitor(context);
+        mPhoneStateMonitor = new PhoneStateMonitor(context, broadcastDispatcher);
         mHandleController = handleController;
 
         registerVoiceInteractionSessionListener();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index e73dc4a..95d611a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -29,6 +29,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.PackageManagerWrapper;
@@ -67,7 +68,7 @@
     private boolean mLauncherShowing;
     @Nullable private ComponentName mDefaultHome;
 
-    PhoneStateMonitor(Context context) {
+    PhoneStateMonitor(Context context, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
 
@@ -77,7 +78,7 @@
         for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
             intentFilter.addAction(action);
         }
-        mContext.registerReceiver(new BroadcastReceiver() {
+        broadcastDispatcher.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 mDefaultHome = getCurrentDefaultHome();
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index ddda95a..24357a7 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -31,6 +31,7 @@
 import java.io.FileDescriptor
 import java.io.PrintWriter
 import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicInteger
 
 private const val MSG_REGISTER_RECEIVER = 0
 private const val MSG_UNREGISTER_RECEIVER = 1
@@ -50,6 +51,13 @@
     private val bgLooper: Looper
 ) : BroadcastReceiver(), Dumpable {
 
+    companion object {
+        // Used only for debugging. If not debugging, this variable will not be accessed and all
+        // received broadcasts will be tagged with 0. However, as DEBUG is false, nothing will be
+        // logged
+        val index = AtomicInteger(0)
+    }
+
     private val bgHandler = object : Handler(bgLooper) {
         override fun handleMessage(msg: Message) {
             when (msg.what) {
@@ -97,7 +105,10 @@
     private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
 
     override fun onReceive(context: Context, intent: Intent) {
-        bgHandler.post(HandleBroadcastRunnable(actionsToReceivers, context, intent, pendingResult))
+        val id = if (DEBUG) index.getAndIncrement() else 0
+        if (DEBUG) Log.w(TAG, "[$id] Received $intent")
+        bgHandler.post(
+                HandleBroadcastRunnable(actionsToReceivers, context, intent, pendingResult, id))
     }
 
     /**
@@ -161,17 +172,19 @@
         val actionsToReceivers: Map<String, Set<ReceiverData>>,
         val context: Context,
         val intent: Intent,
-        val pendingResult: PendingResult
+        val pendingResult: PendingResult,
+        val index: Int
     ) : Runnable {
         override fun run() {
-            if (DEBUG) Log.w(TAG, "Dispatching $intent")
+            if (DEBUG) Log.w(TAG, "[$index] Dispatching $intent")
             actionsToReceivers.get(intent.action)
                     ?.filter {
                         it.filter.hasAction(intent.action) &&
                             it.filter.matchCategories(intent.categories) == null }
                     ?.forEach {
                         it.handler.post {
-                            if (DEBUG) Log.w(TAG, "Dispatching to ${it.receiver}")
+                            if (DEBUG) Log.w(TAG,
+                                    "[$index] Dispatching ${intent.action} to ${it.receiver}")
                             it.receiver.pendingResult = pendingResult
                             it.receiver.onReceive(context, intent)
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index 61ded13..4593164 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -19,7 +19,11 @@
 import android.app.Activity;
 
 import com.android.systemui.ForegroundServicesDialog;
+import com.android.systemui.keyguard.WorkLockActivity;
+import com.android.systemui.settings.BrightnessDialog;
 import com.android.systemui.tuner.TunerActivity;
+import com.android.systemui.usb.UsbDebuggingActivity;
+import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity;
 
 import dagger.Binds;
 import dagger.Module;
@@ -42,4 +46,29 @@
     @IntoMap
     @ClassKey(ForegroundServicesDialog.class)
     public abstract Activity bindForegroundServicesDialog(ForegroundServicesDialog activity);
+
+    /** Inject into WorkLockActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(WorkLockActivity.class)
+    public abstract Activity bindWorkLockActivity(WorkLockActivity activity);
+
+    /** Inject into BrightnessDialog. */
+    @Binds
+    @IntoMap
+    @ClassKey(BrightnessDialog.class)
+    public abstract Activity bindBrightnessDialog(BrightnessDialog activity);
+
+    /** Inject into UsbDebuggingActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(UsbDebuggingActivity.class)
+    public abstract Activity bindUsbDebuggingActivity(UsbDebuggingActivity activity);
+
+    /** Inject into UsbDebuggingSecondaryUserActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(UsbDebuggingSecondaryUserActivity.class)
+    public abstract Activity bindUsbDebuggingSecondaryUserActivity(
+            UsbDebuggingSecondaryUserActivity activity);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 248bf622..6d61b2f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -35,6 +35,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgHandler;
 import com.android.systemui.dagger.qualifiers.BgLooper;
 import com.android.systemui.dagger.qualifiers.MainHandler;
@@ -226,8 +227,8 @@
     @Singleton
     @Provides
     public DeviceProvisionedController provideDeviceProvisionedController(Context context,
-            @MainHandler Handler mainHandler) {
-        return new DeviceProvisionedControllerImpl(context, mainHandler);
+            @MainHandler Handler mainHandler, BroadcastDispatcher broadcastDispatcher) {
+        return new DeviceProvisionedControllerImpl(context, mainHandler, broadcastDispatcher);
     }
 
     /** */
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 88ec76c..4f429d3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -30,6 +30,7 @@
 import com.android.systemui.LatencyTester;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.SizeCompatModeActivityController;
+import com.android.systemui.SliceBroadcastRelayHandler;
 import com.android.systemui.SystemUI;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.appops.AppOpsController;
@@ -98,6 +99,7 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.tv.TvStatusBar;
+import com.android.systemui.theme.ThemeOverlayController;
 import com.android.systemui.util.InjectionInflationController;
 import com.android.systemui.util.leak.GarbageMonitor;
 import com.android.systemui.volume.VolumeUI;
@@ -184,12 +186,24 @@
     public abstract SystemUI bindsSizeCompatModeActivityController(
             SizeCompatModeActivityController sysui);
 
+    /** Inject into SliceBroadcastRelayHandler. */
+    @Binds
+    @IntoMap
+    @ClassKey(SliceBroadcastRelayHandler.class)
+    public abstract SystemUI bindSliceBroadcastRelayHandler(SliceBroadcastRelayHandler sysui);
+
     /** Inject into StatusBar. */
     @Binds
     @IntoMap
     @ClassKey(StatusBar.class)
     public abstract SystemUI bindsStatusBar(StatusBar sysui);
 
+    /** Inject into ThemeOverlayController. */
+    @Binds
+    @IntoMap
+    @ClassKey(ThemeOverlayController.class)
+    public abstract SystemUI bindThemeOverlayController(ThemeOverlayController sysui);
+
     /** Inject into TvStatusBar. */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 33f68cf..eaa72dc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -29,6 +29,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.FalsingManager;
@@ -58,6 +59,7 @@
     private final DelayedWakeLock.Builder mDelayedWakeLockBuilder;
     private final Handler mHandler;
     private final BiometricUnlockController mBiometricUnlockController;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     @Inject
     public DozeFactory(FalsingManager falsingManager, DozeLog dozeLog,
@@ -67,7 +69,8 @@
             DockManager dockManager, @Nullable IWallpaperManager wallpaperManager,
             ProximitySensor proximitySensor,
             DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
-            BiometricUnlockController biometricUnlockController) {
+            BiometricUnlockController biometricUnlockController,
+            BroadcastDispatcher broadcastDispatcher) {
         mFalsingManager = falsingManager;
         mDozeLog = dozeLog;
         mDozeParameters = dozeParameters;
@@ -82,6 +85,7 @@
         mDelayedWakeLockBuilder = delayedWakeLockBuilder;
         mHandler = handler;
         mBiometricUnlockController = biometricUnlockController;
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
@@ -123,8 +127,8 @@
             DozeParameters params, Handler handler) {
         Sensor sensor = DozeSensors.findSensorWithType(sensorManager,
                 context.getString(R.string.doze_brightness_sensor_type));
-        return new DozeScreenBrightness(context, service, sensorManager, sensor, host, handler,
-                params.getPolicy());
+        return new DozeScreenBrightness(context, service, sensorManager, sensor,
+                mBroadcastDispatcher, host, handler, params.getPolicy());
     }
 
     private DozeTriggers createDozeTriggers(Context context, AsyncSensorManager sensorManager,
@@ -134,7 +138,7 @@
         boolean allowPulseTriggers = true;
         return new DozeTriggers(context, machine, host, alarmManager, config, params,
                 sensorManager, handler, wakeLock, allowPulseTriggers, dockManager,
-                mProximitySensor, dozeLog);
+                mProximitySensor, dozeLog, mBroadcastDispatcher);
 
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index bd6882c..39a2562 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -31,6 +31,7 @@
 import android.provider.Settings;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 /**
  * Controls the screen brightness when dozing.
@@ -49,6 +50,7 @@
     private final Handler mHandler;
     private final SensorManager mSensorManager;
     private final Sensor mLightSensor;
+    private final BroadcastDispatcher mBroadcastDispatcher;
     private final int[] mSensorToBrightness;
     private final int[] mSensorToScrimOpacity;
     private final boolean mDebuggable;
@@ -69,13 +71,15 @@
 
     @VisibleForTesting
     public DozeScreenBrightness(Context context, DozeMachine.Service service,
-            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
+            SensorManager sensorManager, Sensor lightSensor,
+            BroadcastDispatcher broadcastDispatcher, DozeHost host,
             Handler handler, int defaultDozeBrightness, int[] sensorToBrightness,
             int[] sensorToScrimOpacity, boolean debuggable) {
         mContext = context;
         mDozeService = service;
         mSensorManager = sensorManager;
         mLightSensor = lightSensor;
+        mBroadcastDispatcher = broadcastDispatcher;
         mDozeHost = host;
         mHandler = handler;
         mDebuggable = debuggable;
@@ -87,14 +91,15 @@
         if (mDebuggable) {
             IntentFilter filter = new IntentFilter();
             filter.addAction(ACTION_AOD_BRIGHTNESS);
-            mContext.registerReceiverAsUser(this, UserHandle.ALL, filter, null, handler);
+            mBroadcastDispatcher.registerReceiver(this, filter, handler, UserHandle.ALL);
         }
     }
 
     public DozeScreenBrightness(Context context, DozeMachine.Service service,
-            SensorManager sensorManager, Sensor lightSensor, DozeHost host,
-            Handler handler, AlwaysOnDisplayPolicy policy) {
-        this(context, service, sensorManager, lightSensor, host, handler,
+            SensorManager sensorManager, Sensor lightSensor,
+            BroadcastDispatcher broadcastDispatcher, DozeHost host, Handler handler,
+            AlwaysOnDisplayPolicy policy) {
+        this(context, service, sensorManager, lightSensor, broadcastDispatcher, host, handler,
                 context.getResources().getInteger(
                         com.android.internal.R.integer.config_screenBrightnessDoze),
                 policy.screenBrightnessArray, policy.dimmingScrimArray, DEBUG_AOD_BRIGHTNESS);
@@ -127,7 +132,7 @@
     private void onDestroy() {
         setLightSensorEnabled(false);
         if (mDebuggable) {
-            mContext.unregisterReceiver(this);
+            mBroadcastDispatcher.unregisterReceiver(this);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index b212884..1134268 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -36,6 +36,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.Assert;
@@ -80,6 +81,7 @@
     private final DockEventListener mDockEventListener = new DockEventListener();
     private final DockManager mDockManager;
     private final ProximitySensor.ProximityCheck mProxCheck;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private long mNotificationPulseTime;
     private boolean mPulsePending;
@@ -91,7 +93,7 @@
             DozeParameters dozeParameters, AsyncSensorManager sensorManager, Handler handler,
             WakeLock wakeLock, boolean allowPulseTriggers, DockManager dockManager,
             ProximitySensor proximitySensor,
-            DozeLog dozeLog) {
+            DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mMachine = machine;
         mDozeHost = dozeHost;
@@ -107,6 +109,7 @@
         mDockManager = dockManager;
         mProxCheck = new ProximitySensor.ProximityCheck(proximitySensor, handler);
         mDozeLog = dozeLog;
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     private void onNotification(Runnable onPulseSuppressedListener) {
@@ -299,7 +302,7 @@
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
             case INITIALIZED:
-                mBroadcastReceiver.register(mContext);
+                mBroadcastReceiver.register(mBroadcastDispatcher);
                 mDozeHost.addCallback(mHostCallback);
                 if (mDockManager != null) {
                     mDockManager.addListener(mDockEventListener);
@@ -334,7 +337,7 @@
                 mDozeSensors.updateListening();
                 break;
             case FINISH:
-                mBroadcastReceiver.unregister(mContext);
+                mBroadcastReceiver.unregister(mBroadcastDispatcher);
                 mDozeHost.removeCallback(mHostCallback);
                 if (mDockManager != null) {
                     mDockManager.removeListener(mDockEventListener);
@@ -437,22 +440,22 @@
             }
         }
 
-        public void register(Context context) {
+        public void register(BroadcastDispatcher broadcastDispatcher) {
             if (mRegistered) {
                 return;
             }
             IntentFilter filter = new IntentFilter(PULSE_ACTION);
             filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
             filter.addAction(Intent.ACTION_USER_SWITCHED);
-            context.registerReceiver(this, filter);
+            broadcastDispatcher.registerReceiver(this, filter);
             mRegistered = true;
         }
 
-        public void unregister(Context context) {
+        public void unregister(BroadcastDispatcher broadcastDispatcher) {
             if (!mRegistered) {
                 return;
             }
-            context.unregisterReceiver(this);
+            broadcastDispatcher.unregisterReceiver(this);
             mRegistered = false;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 22846bc..bb2d142 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -52,6 +52,7 @@
 import android.provider.Settings;
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
+import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -145,6 +146,7 @@
     private final DevicePolicyManager mDevicePolicyManager;
     private final LockPatternUtils mLockPatternUtils;
     private final KeyguardManager mKeyguardManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private ArrayList<Action> mItems;
     private ActionsDialog mDialog;
@@ -182,13 +184,14 @@
                 Context.DEVICE_POLICY_SERVICE);
         mLockPatternUtils = new LockPatternUtils(mContext);
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
 
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
-        Dependency.get(BroadcastDispatcher.class).registerReceiver(mBroadcastReceiver, filter);
+        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
 
         ConnectivityManager cm = (ConnectivityManager)
                 context.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -563,7 +566,8 @@
         @Override
         public void onPress() {
             MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_DIALER_FROM_POWER_MENU);
-            Intent intent = new Intent(EmergencyDialerConstants.ACTION_DIAL);
+            Intent intent = mContext.getSystemService(TelecomManager.class)
+                    .createLaunchEmergencyDialerIntent(null /* number */);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -899,7 +903,7 @@
         mAdapter.notifyDataSetChanged();
         if (mShowSilentToggle) {
             IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
-            mContext.registerReceiver(mRingerModeReceiver, filter);
+            mBroadcastDispatcher.registerReceiver(mRingerModeReceiver, filter);
         }
     }
 
@@ -917,7 +921,7 @@
         mWindowManagerFuncs.onGlobalActionsHidden();
         if (mShowSilentToggle) {
             try {
-                mContext.unregisterReceiver(mRingerModeReceiver);
+                mBroadcastDispatcher.unregisterReceiver(mRingerModeReceiver);
             } catch (IllegalArgumentException ie) {
                 // ignore this
                 Log.w(TAG, ie);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 411bf9a..3b1edcc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -87,6 +87,7 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -319,6 +320,7 @@
      */
     private boolean mWaitingUntilKeyguardVisible = false;
     private final LockPatternUtils mLockPatternUtils;
+    private final BroadcastDispatcher mBroadcastDispatcher;
     private boolean mKeyguardDonePending = false;
     private boolean mHideAnimationRun = false;
     private boolean mHideAnimationRunning = false;
@@ -685,8 +687,10 @@
     public KeyguardViewMediator(
             Context context,
             FalsingManager falsingManager,
-            LockPatternUtils lockPatternUtils) {
-        this(context, falsingManager, lockPatternUtils, SystemUIFactory.getInstance());
+            LockPatternUtils lockPatternUtils,
+            BroadcastDispatcher broadcastDispatcher) {
+        this(context, falsingManager, lockPatternUtils, broadcastDispatcher,
+                SystemUIFactory.getInstance());
     }
 
     @VisibleForTesting
@@ -694,10 +698,12 @@
             Context context,
             FalsingManager falsingManager,
             LockPatternUtils lockPatternUtils,
+            BroadcastDispatcher broadcastDispatcher,
             SystemUIFactory systemUIFactory) {
         super(context);
         mFalsingManager = falsingManager;
         mLockPatternUtils = lockPatternUtils;
+        mBroadcastDispatcher = broadcastDispatcher;
         mStatusBarKeyguardViewManager = systemUIFactory.createStatusBarKeyguardViewManager(
                 mContext,
                 mViewMediatorCallback,
@@ -722,7 +728,7 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SHUTDOWN);
-        mContext.registerReceiver(mBroadcastReceiver, filter);
+        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
 
         final IntentFilter delayedActionFilter = new IntentFilter();
         delayedActionFilter.addAction(DELAYED_KEYGUARD_ACTION);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index 4d061e1..86c532c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -36,6 +36,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
+import javax.inject.Inject;
 
 /**
  * Bouncer between work activities and the activity used to confirm credentials before unlocking
@@ -67,14 +70,21 @@
      * @see KeyguardManager
      */
     private KeyguardManager mKgm;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+
+    @Inject
+    public WorkLockActivity(BroadcastDispatcher broadcastDispatcher) {
+        super();
+        mBroadcastDispatcher = broadcastDispatcher;
+    }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        registerReceiverAsUser(mLockEventReceiver, UserHandle.ALL,
-                new IntentFilter(Intent.ACTION_DEVICE_LOCKED_CHANGED), /* permission */ null,
-                /* scheduler */ null);
+        mBroadcastDispatcher.registerReceiver(mLockEventReceiver,
+                new IntentFilter(Intent.ACTION_DEVICE_LOCKED_CHANGED), null /* handler */,
+                UserHandle.ALL);
 
         // Once the receiver is registered, check whether anything happened between now and the time
         // when this activity was launched. If it did and the user is unlocked now, just quit.
diff --git a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
index 05be425..75e260e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
@@ -19,10 +19,12 @@
 import android.content.Context;
 import android.content.res.Configuration;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
 import java.io.PrintWriter;
 
 public interface BasePipManager {
-    void initialize(Context context);
+    void initialize(Context context, BroadcastDispatcher broadcastDispatcher);
     void showPictureInPictureMenu();
     default void expandPip() {}
     default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
index feb5d19..583ce67 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -26,6 +26,7 @@
 import android.os.UserManager;
 
 import com.android.systemui.SystemUI;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.CommandQueue;
 
 import java.io.FileDescriptor;
@@ -42,12 +43,15 @@
 
     private final CommandQueue mCommandQueue;
     private BasePipManager mPipManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private boolean mSupportsPip;
 
     @Inject
-    public PipUI(Context context, CommandQueue commandQueue) {
+    public PipUI(Context context, CommandQueue commandQueue,
+            BroadcastDispatcher broadcastDispatcher) {
         super(context);
+        mBroadcastDispatcher = broadcastDispatcher;
         mCommandQueue = commandQueue;
     }
 
@@ -68,7 +72,7 @@
         mPipManager = pm.hasSystemFeature(FEATURE_LEANBACK_ONLY)
                 ? com.android.systemui.pip.tv.PipManager.getInstance()
                 : com.android.systemui.pip.phone.PipManager.getInstance();
-        mPipManager.initialize(mContext);
+        mPipManager.initialize(mContext, mBroadcastDispatcher);
 
         mCommandQueue.addCallback(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 369073c..c33b8d9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -37,6 +37,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.UiOffloadThread;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.pip.BasePipManager;
 import com.android.systemui.pip.PipBoundsHandler;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -200,7 +201,7 @@
     /**
      * Initializes {@link PipManager}.
      */
-    public void initialize(Context context) {
+    public void initialize(Context context, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mActivityManager = ActivityManager.getService();
         mActivityTaskManager = ActivityTaskManager.getService();
@@ -214,7 +215,7 @@
 
         mPipBoundsHandler = new PipBoundsHandler(context);
         mInputConsumerController = InputConsumerController.getPipInputConsumer();
-        mMediaController = new PipMediaController(context, mActivityManager);
+        mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
         mMenuController = new PipMenuActivityController(context, mActivityManager, mMediaController,
                 mInputConsumerController);
         mTouchHandler = new PipTouchHandler(context, mActivityManager, mActivityTaskManager,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
index 174a7ef..e57b416 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
@@ -37,6 +37,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.policy.UserInfoController;
 
 import java.util.ArrayList;
@@ -109,7 +110,8 @@
 
     private ArrayList<ActionListener> mListeners = new ArrayList<>();
 
-    public PipMediaController(Context context, IActivityManager activityManager) {
+    public PipMediaController(Context context, IActivityManager activityManager,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mActivityManager = activityManager;
         IntentFilter mediaControlFilter = new IntentFilter();
@@ -117,7 +119,7 @@
         mediaControlFilter.addAction(ACTION_PAUSE);
         mediaControlFilter.addAction(ACTION_NEXT);
         mediaControlFilter.addAction(ACTION_PREV);
-        mContext.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter);
+        broadcastDispatcher.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter);
 
         createMediaActions();
         mMediaSessionManager =
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 81d6973..195fca8 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -48,6 +48,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.pip.BasePipManager;
 import com.android.systemui.pip.PipBoundsHandler;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -227,7 +228,7 @@
     /**
      * Initializes {@link PipManager}.
      */
-    public void initialize(Context context) {
+    public void initialize(Context context, BroadcastDispatcher broadcastDispatcher) {
         if (mInitialized) {
             return;
         }
@@ -238,8 +239,8 @@
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
-        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, intentFilter,
-                null, null);
+        broadcastDispatcher.registerReceiver(mBroadcastReceiver, intentFilter,
+                null /* handler */, UserHandle.ALL);
 
         if (sSettingsPackageAndClassNamePairList == null) {
             String[] settings = mContext.getResources().getStringArray(
@@ -286,7 +287,7 @@
             Log.e(TAG, "Failed to register pinned stack listener", e);
         }
 
-        mPipNotification = new PipNotification(context);
+        mPipNotification = new PipNotification(context, broadcastDispatcher);
     }
 
     private void loadConfigurationsAndApply(Configuration newConfig) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
index d50f294e4..ca15131 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
@@ -34,6 +34,7 @@
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.util.NotificationChannels;
 
 /**
@@ -143,7 +144,7 @@
         }
     };
 
-    public PipNotification(Context context) {
+    public PipNotification(Context context, BroadcastDispatcher broadcastDispatcher) {
         mNotificationManager = (NotificationManager) context.getSystemService(
                 Context.NOTIFICATION_SERVICE);
 
@@ -161,7 +162,7 @@
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ACTION_MENU);
         intentFilter.addAction(ACTION_CLOSE);
-        context.registerReceiver(mEventReceiver, intentFilter);
+        broadcastDispatcher.registerReceiver(mEventReceiver, intentFilter);
 
         onConfigurationChanged(context);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index ca16e84..d592492 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.R
 import com.android.systemui.appops.AppOpItem
 import com.android.systemui.appops.AppOpsController
+import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.qualifiers.BgHandler
 import com.android.systemui.dagger.qualifiers.MainHandler
 import java.io.FileDescriptor
@@ -47,10 +48,11 @@
 
 @Singleton
 class PrivacyItemController @Inject constructor(
-    val context: Context,
+    private val context: Context,
     private val appOpsController: AppOpsController,
     @MainHandler private val uiHandler: Handler,
-    @BgHandler private val bgHandler: Handler
+    @BgHandler private val bgHandler: Handler,
+    private val broadcastDispatcher: BroadcastDispatcher
 ) : Dumpable {
 
     @VisibleForTesting
@@ -138,15 +140,15 @@
     }
 
     private fun unregisterReceiver() {
-        context.unregisterReceiver(userSwitcherReceiver)
+        broadcastDispatcher.unregisterReceiver(userSwitcherReceiver)
     }
 
     private fun registerReceiver() {
-        context.registerReceiverAsUser(userSwitcherReceiver, UserHandle.ALL, IntentFilter().apply {
+        broadcastDispatcher.registerReceiver(userSwitcherReceiver, IntentFilter().apply {
             intents.forEach {
                 addAction(it)
             }
-        }, null, null)
+        }, null /* handler */, UserHandle.ALL)
     }
 
     private fun update(updateUsers: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 39f0865..cac9025 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -50,6 +50,7 @@
 import com.android.systemui.DumpController;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTileView;
@@ -125,12 +126,13 @@
     }
 
     public QSPanel(Context context, AttributeSet attrs, DumpController dumpController) {
-        this(context, attrs, dumpController, null);
+        this(context, attrs, dumpController, null, Dependency.get(BroadcastDispatcher.class));
     }
 
     @Inject
     public QSPanel(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
-            DumpController dumpController, PluginManager pluginManager) {
+            DumpController dumpController, PluginManager pluginManager,
+            BroadcastDispatcher broadcastDispatcher) {
         super(context, attrs);
         mContext = context;
 
@@ -177,7 +179,7 @@
         updateResources();
 
         mBrightnessController = new BrightnessController(getContext(),
-                findViewById(R.id.brightness_slider));
+                findViewById(R.id.brightness_slider), broadcastDispatcher);
         mDumpController = dumpController;
         mPluginManager = pluginManager;
         if (mPluginManager != null && Settings.System.getInt(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index b395c3c..6d434b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -34,6 +34,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgLooper;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.plugins.PluginListener;
@@ -80,6 +81,7 @@
     private final TunerService mTunerService;
     private final PluginManager mPluginManager;
     private final DumpController mDumpController;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private final List<Callback> mCallbacks = new ArrayList<>();
     private AutoTileManager mAutoTiles;
@@ -99,14 +101,16 @@
             PluginManager pluginManager,
             TunerService tunerService,
             Provider<AutoTileManager> autoTiles,
-            DumpController dumpController) {
+            DumpController dumpController,
+            BroadcastDispatcher broadcastDispatcher) {
         mIconController = iconController;
         mContext = context;
         mTunerService = tunerService;
         mPluginManager = pluginManager;
         mDumpController = dumpController;
+        mBroadcastDispatcher = broadcastDispatcher;
 
-        mServices = new TileServices(this, bgLooper);
+        mServices = new TileServices(this, bgLooper, mBroadcastDispatcher);
 
         defaultFactory.setHost(this);
         mQsFactories.add(defaultFactory);
@@ -334,7 +338,8 @@
                 Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
                         mContext, mServices, new Tile(), intent,
-                        new UserHandle(ActivityManager.getCurrentUser()));
+                        new UserHandle(ActivityManager.getCurrentUser()),
+                        mBroadcastDispatcher);
                 lifecycleManager.onStopListening();
                 lifecycleManager.onTileRemoved();
                 TileLifecycleManager.setTileAdded(mContext, component, false);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 24ac27e..19af235 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -61,6 +61,7 @@
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.DualToneHandler;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
@@ -150,6 +151,7 @@
     private boolean mPermissionsHubEnabled;
 
     private PrivacyItemController mPrivacyItemController;
+    private BroadcastDispatcher mBroadcastDispatcher;
 
     private final BroadcastReceiver mRingerReceiver = new BroadcastReceiver() {
         @Override
@@ -189,7 +191,7 @@
             NextAlarmController nextAlarmController, ZenModeController zenModeController,
             StatusBarIconController statusBarIconController,
             ActivityStarter activityStarter, PrivacyItemController privacyItemController,
-            CommandQueue commandQueue) {
+            CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher) {
         super(context, attrs);
         mAlarmController = nextAlarmController;
         mZenController = zenModeController;
@@ -198,6 +200,7 @@
         mPrivacyItemController = privacyItemController;
         mDualToneHandler = new DualToneHandler(
                 new ContextThemeWrapper(context, R.style.QSHeaderTheme));
+        mBroadcastDispatcher = broadcastDispatcher;
         mCommandQueue = commandQueue;
     }
 
@@ -551,14 +554,14 @@
         if (listening) {
             mZenController.addCallback(this);
             mAlarmController.addCallback(this);
-            mContext.registerReceiver(mRingerReceiver,
+            mBroadcastDispatcher.registerReceiver(mRingerReceiver,
                     new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
             mPrivacyItemController.addCallback(mPICCallback);
         } else {
             mZenController.removeCallback(this);
             mAlarmController.removeCallback(this);
             mPrivacyItemController.removeCallback(mPICCallback);
-            mContext.unregisterReceiver(mRingerReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mRingerReceiver);
             mPrivacyChipLogged = false;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index f59e0c2..9261412 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -38,6 +38,8 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
 import java.util.Objects;
 import java.util.Set;
 
@@ -72,6 +74,7 @@
     private final UserHandle mUser;
     private final IBinder mToken = new Binder();
     private final PackageManagerAdapter mPackageManagerAdapter;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private Set<Integer> mQueuedMessages = new ArraySet<>();
     private QSTileServiceWrapper mWrapper;
@@ -88,13 +91,15 @@
     private boolean mIsBound;
 
     public TileLifecycleManager(Handler handler, Context context, IQSService service, Tile tile,
-            Intent intent, UserHandle user) {
-        this(handler, context, service, tile, intent, user, new PackageManagerAdapter(context));
+            Intent intent, UserHandle user, BroadcastDispatcher broadcastDispatcher) {
+        this(handler, context, service, tile, intent, user, new PackageManagerAdapter(context),
+                broadcastDispatcher);
     }
 
     @VisibleForTesting
     TileLifecycleManager(Handler handler, Context context, IQSService service, Tile tile,
-            Intent intent, UserHandle user, PackageManagerAdapter packageManagerAdapter) {
+            Intent intent, UserHandle user, PackageManagerAdapter packageManagerAdapter,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mHandler = handler;
         mIntent = intent;
@@ -102,6 +107,7 @@
         mIntent.putExtra(TileService.EXTRA_TOKEN, mToken);
         mUser = user;
         mPackageManagerAdapter = packageManagerAdapter;
+        mBroadcastDispatcher = broadcastDispatcher;
         if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
     }
 
@@ -306,13 +312,14 @@
         filter.addDataScheme("package");
         mContext.registerReceiverAsUser(this, mUser, filter, null, mHandler);
         filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiverAsUser(this, mUser, filter, null, mHandler);
+        mBroadcastDispatcher.registerReceiver(this, filter, mHandler, mUser);
         mReceiverRegistered = true;
     }
 
     private void stopPackageListening() {
         if (DEBUG) Log.d(TAG, "stopPackageListening");
         mContext.unregisterReceiver(this);
+        mBroadcastDispatcher.unregisterReceiver(this);
         mReceiverRegistered = false;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index 0b4e648..1902d65 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -34,6 +34,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
 
 import java.util.List;
@@ -72,10 +73,10 @@
     private boolean mStarted = false;
 
     TileServiceManager(TileServices tileServices, Handler handler, ComponentName component,
-            Tile tile) {
+            Tile tile, BroadcastDispatcher broadcastDispatcher) {
         this(tileServices, handler, new TileLifecycleManager(handler,
                 tileServices.getContext(), tileServices, tile, new Intent().setComponent(component),
-                new UserHandle(ActivityManager.getCurrentUser())));
+                new UserHandle(ActivityManager.getCurrentUser()), broadcastDispatcher));
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 13cfa78..db7c6ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -37,6 +37,7 @@
 
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.Dependency;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -60,13 +61,15 @@
     private final Handler mHandler;
     private final Handler mMainHandler;
     private final QSTileHost mHost;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private int mMaxBound = DEFAULT_MAX_BOUND;
 
-    public TileServices(QSTileHost host, Looper looper) {
+    public TileServices(QSTileHost host, Looper looper, BroadcastDispatcher broadcastDispatcher) {
         mHost = host;
         mContext = mHost.getContext();
-        mContext.registerReceiver(mRequestListeningReceiver,
+        mBroadcastDispatcher = broadcastDispatcher;
+        mBroadcastDispatcher.registerReceiver(mRequestListeningReceiver,
                 new IntentFilter(TileService.ACTION_REQUEST_LISTENING));
         mHandler = new Handler(looper);
         mMainHandler = new Handler(Looper.getMainLooper());
@@ -82,7 +85,8 @@
 
     public TileServiceManager getTileWrapper(CustomTile tile) {
         ComponentName component = tile.getComponent();
-        TileServiceManager service = onCreateTileService(component, tile.getQsTile());
+        TileServiceManager service = onCreateTileService(component, tile.getQsTile(),
+                mBroadcastDispatcher);
         synchronized (mServices) {
             mServices.put(tile, service);
             mTiles.put(component, tile);
@@ -93,8 +97,10 @@
         return service;
     }
 
-    protected TileServiceManager onCreateTileService(ComponentName component, Tile tile) {
-        return new TileServiceManager(this, mHandler, component, tile);
+    protected TileServiceManager onCreateTileService(ComponentName component, Tile tile,
+            BroadcastDispatcher broadcastDispatcher) {
+        return new TileServiceManager(this, mHandler, component, tile,
+                broadcastDispatcher);
     }
 
     public void freeService(CustomTile tile, TileServiceManager service) {
@@ -323,7 +329,7 @@
     public void destroy() {
         synchronized (mServices) {
             mServices.values().forEach(service -> service.handleDestroy());
-            mContext.unregisterReceiver(mRequestListeningReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mRequestListeningReceiver);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 19e20a9..da74663 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -33,6 +33,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.GlobalSetting;
@@ -46,13 +47,16 @@
     private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane);
     private final GlobalSetting mSetting;
     private final ActivityStarter mActivityStarter;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private boolean mListening;
 
     @Inject
-    public AirplaneModeTile(QSHost host, ActivityStarter activityStarter) {
+    public AirplaneModeTile(QSHost host, ActivityStarter activityStarter,
+            BroadcastDispatcher broadcastDispatcher) {
         super(host);
         mActivityStarter = activityStarter;
+        mBroadcastDispatcher = broadcastDispatcher;
 
         mSetting = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) {
             @Override
@@ -133,9 +137,9 @@
         if (listening) {
             final IntentFilter filter = new IntentFilter();
             filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-            mContext.registerReceiver(mReceiver, filter);
+            mBroadcastDispatcher.registerReceiver(mReceiver, filter);
         } else {
-            mContext.unregisterReceiver(mReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mReceiver);
         }
         mSetting.setListening(listening);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 869fa6b..52d1a5b3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -52,6 +52,7 @@
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SysUIToast;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -78,6 +79,7 @@
     private final ZenModeController mController;
     private final DndDetailAdapter mDetailAdapter;
     private final ActivityStarter mActivityStarter;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private boolean mListening;
     private boolean mShowingDetail;
@@ -85,12 +87,13 @@
 
     @Inject
     public DndTile(QSHost host, ZenModeController zenModeController,
-            ActivityStarter activityStarter) {
+            ActivityStarter activityStarter, BroadcastDispatcher broadcastDispatcher) {
         super(host);
         mController = zenModeController;
         mActivityStarter = activityStarter;
         mDetailAdapter = new DndDetailAdapter();
-        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE));
+        mBroadcastDispatcher = broadcastDispatcher;
+        broadcastDispatcher.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE));
         mReceiverRegistered = true;
         mController.observe(getLifecycle(), mZenCallback);
     }
@@ -99,7 +102,7 @@
     protected void handleDestroy() {
         super.handleDestroy();
         if (mReceiverRegistered) {
-            mContext.unregisterReceiver(mReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mReceiver);
             mReceiverRegistered = false;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 476a239..8bbfd24 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -29,6 +29,7 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -39,12 +40,14 @@
 public class NfcTile extends QSTileImpl<BooleanState> {
 
     private NfcAdapter mAdapter;
+    private BroadcastDispatcher mBroadcastDispatcher;
 
     private boolean mListening;
 
     @Inject
-    public NfcTile(QSHost host) {
+    public NfcTile(QSHost host, BroadcastDispatcher broadcastDispatcher) {
         super(host);
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     @Override
@@ -56,10 +59,10 @@
     public void handleSetListening(boolean listening) {
         mListening = listening;
         if (mListening) {
-            mContext.registerReceiver(mNfcReceiver,
+            mBroadcastDispatcher.registerReceiver(mNfcReceiver,
                     new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED));
         } else {
-            mContext.unregisterReceiver(mNfcReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mNfcReceiver);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 176676f..b1f1f38 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -44,6 +44,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.systemui.Dependency;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import java.util.ArrayList;
 
@@ -281,12 +282,13 @@
         }
     };
 
-    public BrightnessController(Context context, ToggleSlider control) {
+    public BrightnessController(Context context, ToggleSlider control,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mControl = control;
         mControl.setMax(GAMMA_SPACE_MAX);
         mBackgroundHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
-        mUserTracker = new CurrentUserTracker(mContext) {
+        mUserTracker = new CurrentUserTracker(broadcastDispatcher) {
             @Override
             public void onUserSwitched(int newUserId) {
                 mBackgroundHandler.post(mUpdateModeRunnable);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index d8b4df5..70c2531 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -28,11 +28,21 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
+import javax.inject.Inject;
 
 /** A dialog that provides controls for adjusting the screen brightness. */
 public class BrightnessDialog extends Activity {
 
     private BrightnessController mBrightnessController;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+
+    @Inject
+    public BrightnessDialog(BroadcastDispatcher broadcastDispatcher) {
+        mBroadcastDispatcher = broadcastDispatcher;
+    }
+
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -49,7 +59,7 @@
         setContentView(v);
 
         final ToggleSliderView slider = findViewById(R.id.brightness_slider);
-        mBrightnessController = new BrightnessController(this, slider);
+        mBrightnessController = new BrightnessController(this, slider, mBroadcastDispatcher);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserObservable.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserObservable.java
index 3cf08b4..3cdc01d 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserObservable.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserObservable.java
@@ -16,11 +16,11 @@
 
 package com.android.systemui.settings;
 
-import android.content.Context;
-
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
 /**
  * A class that has an observable for the current user.
  */
@@ -42,8 +42,8 @@
         }
     };
 
-    public CurrentUserObservable(Context context) {
-        mTracker = new CurrentUserTracker(context) {
+    public CurrentUserObservable(BroadcastDispatcher broadcastDispatcher) {
+        mTracker = new CurrentUserTracker(broadcastDispatcher) {
             @Override
             public void onUserSwitched(int newUserId) {
                 mCurrentUser.setValue(newUserId);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index 0b89dc1..9f79785 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -23,6 +23,7 @@
 import android.content.IntentFilter;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -33,8 +34,8 @@
 
     private Consumer<Integer> mCallback = this::onUserSwitched;
 
-    public CurrentUserTracker(Context context) {
-        this(UserReceiver.getInstance(context));
+    public CurrentUserTracker(BroadcastDispatcher broadcastDispatcher) {
+        this(UserReceiver.getInstance(broadcastDispatcher));
     }
 
     @VisibleForTesting
@@ -60,20 +61,20 @@
     static class UserReceiver extends BroadcastReceiver {
         private static UserReceiver sInstance;
 
-        private Context mAppContext;
         private boolean mReceiverRegistered;
         private int mCurrentUserId;
+        private final BroadcastDispatcher mBroadcastDispatcher;
 
         private List<Consumer<Integer>> mCallbacks = new ArrayList<>();
 
         @VisibleForTesting
-        UserReceiver(Context context) {
-            mAppContext = context.getApplicationContext();
+        UserReceiver(BroadcastDispatcher broadcastDispatcher) {
+            mBroadcastDispatcher = broadcastDispatcher;
         }
 
-        static UserReceiver getInstance(Context context) {
+        static UserReceiver getInstance(BroadcastDispatcher broadcastDispatcher) {
             if (sInstance == null) {
-                sInstance = new UserReceiver(context);
+                sInstance = new UserReceiver(broadcastDispatcher);
             }
             return sInstance;
         }
@@ -96,7 +97,7 @@
             if (!mReceiverRegistered) {
                 mCurrentUserId = ActivityManager.getCurrentUser();
                 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-                mAppContext.registerReceiver(this, filter);
+                mBroadcastDispatcher.registerReceiver(this, filter);
                 mReceiverRegistered = true;
             }
         }
@@ -105,7 +106,7 @@
             if (mCallbacks.contains(callback)) {
                 mCallbacks.remove(callback);
                 if (mCallbacks.size() == 0 && mReceiverRegistered) {
-                    mAppContext.unregisterReceiver(this);
+                    mBroadcastDispatcher.unregisterReceiver(this);
                     mReceiverRegistered = false;
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 7adf7af..571d3d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -46,6 +46,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.recents.OverviewProxyService;
@@ -90,6 +91,7 @@
     private final UserManager mUserManager;
     private final IStatusBarService mBarService;
     private final List<UserChangedListener> mListeners = new ArrayList<>();
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private boolean mShowLockscreenNotifications;
     private boolean mAllowLockscreenRemoteInput;
@@ -180,7 +182,8 @@
     }
 
     @Inject
-    public NotificationLockscreenUserManagerImpl(Context context) {
+    public NotificationLockscreenUserManagerImpl(Context context,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
@@ -191,6 +194,7 @@
         Dependency.get(StatusBarStateController.class).addCallback(this);
         mLockPatternUtils = new LockPatternUtils(context);
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter) {
@@ -244,15 +248,15 @@
                     UserHandle.USER_ALL);
         }
 
-        mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL,
+        mBroadcastDispatcher.registerReceiver(mAllUsersReceiver,
                 new IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
-                null, null);
+                null /* handler */, UserHandle.ALL);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_USER_ADDED);
         filter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiver(mBaseBroadcastReceiver, filter);
+        mBroadcastDispatcher.registerReceiver(mBaseBroadcastReceiver, filter);
 
         IntentFilter internalFilter = new IntentFilter();
         internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
index fbd8d8a..07e9f94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
@@ -24,6 +24,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -40,6 +42,7 @@
 
     private final Context mContext;
     private final UserManager mUserManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
     private final LinkedList<UserInfo> mProfiles;
     private boolean mListening;
     private int mCurrentUser;
@@ -47,9 +50,10 @@
     /**
      */
     @Inject
-    public ManagedProfileControllerImpl(Context context) {
+    public ManagedProfileControllerImpl(Context context, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mUserManager = UserManager.get(mContext);
+        mBroadcastDispatcher = broadcastDispatcher;
         mProfiles = new LinkedList<UserInfo>();
     }
 
@@ -129,9 +133,10 @@
             filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
             filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
             filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
-            mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
+            mBroadcastDispatcher.registerReceiver(
+                    mReceiver, filter, null /* handler */, UserHandle.ALL);
         } else {
-            mContext.unregisterReceiver(mReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mReceiver);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 0645423..01cd2b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -41,6 +41,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.privacy.PrivacyItem;
 import com.android.systemui.privacy.PrivacyItemController;
 import com.android.systemui.privacy.PrivacyItemControllerKt;
@@ -138,7 +139,7 @@
     private AlarmManager.AlarmClockInfo mNextAlarm;
 
     public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController,
-            CommandQueue commandQueue) {
+            CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mIconController = iconController;
         mCast = Dependency.get(CastController.class);
@@ -184,7 +185,7 @@
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
-        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+        broadcastDispatcher.registerReceiver(mIntentReceiver, filter, mHandler);
 
         // listen for user / profile change.
         try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 2125d12..8f13741 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -847,8 +847,8 @@
         if (mWallpaperSupported) {
             // Make sure we always have the most current wallpaper info.
             IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
-            mContext.registerReceiverAsUser(mWallpaperChangedReceiver, UserHandle.ALL,
-                    wallpaperChangedFilter, null /* broadcastPermission */, null /* scheduler */);
+            mBroadcastDispatcher.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter,
+                    null /* handler */, UserHandle.ALL);
             mWallpaperChangedReceiver.onReceive(mContext, null);
         } else if (DEBUG) {
             Log.v(TAG, "start(): no wallpaper service ");
@@ -912,7 +912,8 @@
         // end old BaseStatusBar.start().
 
         // Lastly, call to the icon policy to install/update all the icons.
-        mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCommandQueue);
+        mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCommandQueue,
+                mBroadcastDispatcher);
         mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController);
 
         mKeyguardStateController.addCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 3fc9b44..f0f9420 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -34,6 +34,7 @@
 import com.android.settingslib.fuelgauge.Estimate;
 import com.android.settingslib.utils.PowerUtil;
 import com.android.systemui.Dependency;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.power.EnhancedEstimates;
 
 import java.io.FileDescriptor;
@@ -58,6 +59,7 @@
     private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60;
 
     private final EnhancedEstimates mEstimates;
+    private final BroadcastDispatcher mBroadcastDispatcher;
     private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
     private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>();
     private final PowerManager mPowerManager;
@@ -76,17 +78,20 @@
     private boolean mFetchingEstimate = false;
 
     @Inject
-    public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates) {
-        this(context, enhancedEstimates, context.getSystemService(PowerManager.class));
+    public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates,
+            BroadcastDispatcher broadcastDispatcher) {
+        this(context, enhancedEstimates, context.getSystemService(PowerManager.class),
+                broadcastDispatcher);
     }
 
     @VisibleForTesting
     BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates,
-            PowerManager powerManager) {
+            PowerManager powerManager, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mHandler = new Handler();
         mPowerManager = powerManager;
         mEstimates = enhancedEstimates;
+        mBroadcastDispatcher = broadcastDispatcher;
 
         registerReceiver();
         updatePowerSave();
@@ -99,7 +104,7 @@
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
         filter.addAction(ACTION_LEVEL_TEST);
-        mContext.registerReceiver(this, filter);
+        mBroadcastDispatcher.registerReceiver(this, filter);
     }
 
     @Override
@@ -306,7 +311,7 @@
     public void dispatchDemoCommand(String command, Bundle args) {
         if (!mDemoMode && command.equals(COMMAND_ENTER)) {
             mDemoMode = true;
-            mContext.unregisterReceiver(this);
+            mBroadcastDispatcher.unregisterReceiver(this);
         } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
             mDemoMode = false;
             registerReceiver();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 568f590..dba3b92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.policy;
 
-import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
-
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -62,9 +60,6 @@
 import java.util.Locale;
 import java.util.TimeZone;
 
-import javax.inject.Inject;
-import javax.inject.Named;
-
 /**
  * Digital clock for the status bar.
  */
@@ -116,19 +111,12 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
 
     public Clock(Context context, AttributeSet attrs) {
-        this(context, attrs, null, Dependency.get(CommandQueue.class));
+        this(context, attrs, 0);
     }
 
-    @Inject
-    public Clock(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
-            BroadcastDispatcher broadcastDispatcher, CommandQueue commandQueue) {
-        this(context, attrs, 0, broadcastDispatcher, commandQueue);
-    }
-
-    public Clock(Context context, AttributeSet attrs, int defStyle,
-            BroadcastDispatcher broadcastDispatcher, CommandQueue commandQueue) {
+    public Clock(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mCommandQueue = commandQueue;
+        mCommandQueue = Dependency.get(CommandQueue.class);
         TypedArray a = context.getTheme().obtainStyledAttributes(
                 attrs,
                 R.styleable.Clock,
@@ -140,13 +128,13 @@
         } finally {
             a.recycle();
         }
-        mCurrentUserTracker = new CurrentUserTracker(context) {
+        mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
+        mCurrentUserTracker = new CurrentUserTracker(mBroadcastDispatcher) {
             @Override
             public void onUserSwitched(int newUserId) {
                 mCurrentUserId = newUserId;
             }
         };
-        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     @Override
@@ -197,8 +185,8 @@
             filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
             filter.addAction(Intent.ACTION_USER_SWITCHED);
 
-            getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
-                    null, Dependency.get(Dependency.TIME_TICK_HANDLER));
+            mBroadcastDispatcher.registerReceiver(mIntentReceiver, filter,
+                    Dependency.get(Dependency.TIME_TICK_HANDLER), UserHandle.ALL);
             Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
                     StatusBarIconController.ICON_BLACKLIST);
             mCommandQueue.addCallback(this);
@@ -225,7 +213,7 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         if (mAttached) {
-            getContext().unregisterReceiver(mIntentReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mIntentReceiver);
             mAttached = false;
             Dependency.get(TunerService.class).removeTunable(this);
             mCommandQueue.removeCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index 74a30fa..d488767 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -29,6 +29,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import java.util.Date;
 import java.util.Locale;
@@ -41,6 +42,7 @@
     private DateFormat mDateFormat;
     private String mLastText;
     private String mDatePattern;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
@@ -75,6 +77,7 @@
         if (mDatePattern == null) {
             mDatePattern = getContext().getString(R.string.system_ui_date_pattern);
         }
+        mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
     }
 
     @Override
@@ -86,7 +89,7 @@
         filter.addAction(Intent.ACTION_TIME_CHANGED);
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
         filter.addAction(Intent.ACTION_LOCALE_CHANGED);
-        getContext().registerReceiver(mIntentReceiver, filter, null,
+        mBroadcastDispatcher.registerReceiver(mIntentReceiver, filter,
                 Dependency.get(Dependency.TIME_TICK_HANDLER));
 
         updateClock();
@@ -97,7 +100,7 @@
         super.onDetachedFromWindow();
 
         mDateFormat = null; // reload the locale next time
-        getContext().unregisterReceiver(mIntentReceiver);
+        mBroadcastDispatcher.unregisterReceiver(mIntentReceiver);
     }
 
     protected void updateClock() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index 0a40b3c..b6ffd58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -24,6 +24,7 @@
 import android.provider.Settings.Secure;
 import android.util.Log;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.settings.CurrentUserTracker;
 
@@ -49,8 +50,9 @@
     /**
      */
     @Inject
-    public DeviceProvisionedControllerImpl(Context context, @MainHandler Handler mainHandler) {
-        super(context);
+    public DeviceProvisionedControllerImpl(Context context, @MainHandler Handler mainHandler,
+            BroadcastDispatcher broadcastDispatcher) {
+        super(broadcastDispatcher);
         mContext = context;
         mContentResolver = context.getContentResolver();
         mDeviceProvisionedUri = Global.getUriFor(Global.DEVICE_PROVISIONED);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 5a97eed..3d51be7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -35,6 +35,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgLooper;
 import com.android.systemui.util.Utils;
 
@@ -57,6 +58,7 @@
 
     private AppOpsManager mAppOpsManager;
     private StatusBarManager mStatusBarManager;
+    private BroadcastDispatcher mBroadcastDispatcher;
 
     private boolean mAreActiveLocationRequests;
 
@@ -65,14 +67,16 @@
     private final H mHandler = new H();
 
     @Inject
-    public LocationControllerImpl(Context context, @BgLooper Looper bgLooper) {
+    public LocationControllerImpl(Context context, @BgLooper Looper bgLooper,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
+        mBroadcastDispatcher = broadcastDispatcher;
 
         // Register to listen for changes in location settings.
         IntentFilter filter = new IntentFilter();
         filter.addAction(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
         filter.addAction(LocationManager.MODE_CHANGED_ACTION);
-        context.registerReceiverAsUser(this, UserHandle.ALL, filter, null, new Handler(bgLooper));
+        mBroadcastDispatcher.registerReceiver(this, filter, new Handler(bgLooper), UserHandle.ALL);
 
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
         mStatusBarManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 60784c9..e5898ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -64,6 +64,7 @@
 import com.android.systemui.DemoMode;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgLooper;
 import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -109,6 +110,7 @@
     private final SubscriptionDefaults mSubDefaults;
     private final DataSaverController mDataSaverController;
     private final CurrentUserTracker mUserTracker;
+    private final BroadcastDispatcher mBroadcastDispatcher;
     private final Object mLock = new Object();
     private Config mConfig;
 
@@ -170,7 +172,8 @@
      */
     @Inject
     public NetworkControllerImpl(Context context, @BgLooper Looper bgLooper,
-            DeviceProvisionedController deviceProvisionedController) {
+            DeviceProvisionedController deviceProvisionedController,
+            BroadcastDispatcher broadcastDispatcher) {
         this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
                 (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
@@ -179,7 +182,8 @@
                 new AccessPointControllerImpl(context),
                 new DataUsageController(context),
                 new SubscriptionDefaults(),
-                deviceProvisionedController);
+                deviceProvisionedController,
+                broadcastDispatcher);
         mReceiverHandler.post(mRegisterListeners);
     }
 
@@ -191,12 +195,14 @@
             AccessPointControllerImpl accessPointController,
             DataUsageController dataUsageController,
             SubscriptionDefaults defaultsHandler,
-            DeviceProvisionedController deviceProvisionedController) {
+            DeviceProvisionedController deviceProvisionedController,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mConfig = config;
         mReceiverHandler = new Handler(bgLooper);
         mCallbackHandler = callbackHandler;
         mDataSaverController = new DataSaverControllerImpl(context);
+        mBroadcastDispatcher = broadcastDispatcher;
 
         mSubscriptionManager = subManager;
         mSubDefaults = defaultsHandler;
@@ -229,7 +235,7 @@
 
         // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
         updateAirplaneMode(true /* force callback */);
-        mUserTracker = new CurrentUserTracker(mContext) {
+        mUserTracker = new CurrentUserTracker(broadcastDispatcher) {
             @Override
             public void onUserSwitched(int newUserId) {
                 NetworkControllerImpl.this.onUserSwitched(newUserId);
@@ -315,7 +321,7 @@
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         filter.addAction(Intent.ACTION_BOOT_COMPLETED);
         filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mContext.registerReceiver(this, filter, null, mReceiverHandler);
+        mBroadcastDispatcher.registerReceiver(this, filter, mReceiverHandler);
         mListening = true;
 
         updateMobileControllers();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 0c68383..c161458 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -48,6 +48,7 @@
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgHandler;
 import com.android.systemui.settings.CurrentUserTracker;
 
@@ -100,13 +101,14 @@
     /**
      */
     @Inject
-    public SecurityControllerImpl(Context context, @BgHandler Handler bgHandler) {
-        this(context, bgHandler, null);
+    public SecurityControllerImpl(Context context, @BgHandler Handler bgHandler,
+            BroadcastDispatcher broadcastDispatcher) {
+        this(context, bgHandler, broadcastDispatcher, null);
     }
 
     public SecurityControllerImpl(Context context, Handler bgHandler,
-            SecurityControllerCallback callback) {
-        super(context);
+            BroadcastDispatcher broadcastDispatcher, SecurityControllerCallback callback) {
+        super(broadcastDispatcher);
         mContext = context;
         mBgHandler = bgHandler;
         mDevicePolicyManager = (DevicePolicyManager)
@@ -124,8 +126,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
         filter.addAction(Intent.ACTION_USER_UNLOCKED);
-        context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null,
-                bgHandler);
+        broadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, bgHandler, UserHandle.ALL);
 
         // TODO: re-register network callback on user change.
         mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 2c99668..075c6d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -59,6 +59,7 @@
 import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.SystemUISecondaryUserService;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
@@ -96,6 +97,7 @@
     private final KeyguardStateController mKeyguardStateController;
     protected final Handler mHandler;
     private final ActivityStarter mActivityStarter;
+    private final BroadcastDispatcher mBroadcastDispatcher;
 
     private ArrayList<UserRecord> mUsers = new ArrayList<>();
     private Dialog mExitGuestDialog;
@@ -111,10 +113,12 @@
 
     @Inject
     public UserSwitcherController(Context context, KeyguardStateController keyguardStateController,
-            @MainHandler Handler handler, ActivityStarter activityStarter) {
+            @MainHandler Handler handler, ActivityStarter activityStarter,
+            BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
+        mBroadcastDispatcher = broadcastDispatcher;
         if (!UserManager.isGuestUserEphemeral()) {
-            mGuestResumeSessionReceiver.register(context);
+            mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
         }
         mKeyguardStateController = keyguardStateController;
         mHandler = handler;
@@ -127,8 +131,8 @@
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_USER_STOPPED);
         filter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
-                null /* permission */, null /* scheduler */);
+        mBroadcastDispatcher.registerReceiver(
+                mReceiver, filter, null /* handler */, UserHandle.SYSTEM);
 
         mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 1c7a195..a2028e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -39,6 +39,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dumpable;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.qs.GlobalSetting;
 import com.android.systemui.settings.CurrentUserTracker;
@@ -77,8 +78,9 @@
     private NotificationManager.Policy mConsolidatedNotificationPolicy;
 
     @Inject
-    public ZenModeControllerImpl(Context context, @MainHandler Handler handler) {
-        super(context);
+    public ZenModeControllerImpl(Context context, @MainHandler Handler handler,
+            BroadcastDispatcher broadcastDispatcher) {
+        super(broadcastDispatcher);
         mContext = context;
         mModeSetting = new GlobalSetting(mContext, handler, Global.ZEN_MODE) {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 9a58a35..128bb21 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -36,6 +36,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import com.google.android.collect.Sets;
 
@@ -45,6 +46,9 @@
 import java.util.Map;
 import java.util.Set;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Controls the application of theme overlays across the system for all users.
  * This service is responsible for:
@@ -54,15 +58,19 @@
  * - Observing work profile changes and applying overlays from the primary user to their
  * associated work profiles
  */
+@Singleton
 public class ThemeOverlayController extends SystemUI {
     private static final String TAG = "ThemeOverlayController";
     private static final boolean DEBUG = false;
 
     private ThemeOverlayManager mThemeManager;
     private UserManager mUserManager;
+    private BroadcastDispatcher mBroadcastDispatcher;
 
-    public ThemeOverlayController(Context context) {
+    @Inject
+    public ThemeOverlayController(Context context, BroadcastDispatcher broadcastDispatcher) {
         super(context);
+        mBroadcastDispatcher = broadcastDispatcher;
     }
 
     @Override
@@ -78,13 +86,13 @@
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
-        mContext.registerReceiverAsUser(new BroadcastReceiver() {
+        mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
                 updateThemeOverlays();
             }
-        }, UserHandle.ALL, filter, null, bgHandler);
+        }, filter, bgHandler, UserHandle.ALL);
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
                 false,
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 2d6027c..ce0032e 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -34,6 +34,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.DemoMode;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.settings.CurrentUserTracker;
@@ -82,7 +83,7 @@
      */
     @Inject
     public TunerServiceImpl(Context context, @MainHandler Handler mainHandler,
-            LeakDetector leakDetector) {
+            LeakDetector leakDetector, BroadcastDispatcher broadcastDispatcher) {
         mContext = context;
         mContentResolver = mContext.getContentResolver();
         mLeakDetector = leakDetector;
@@ -95,7 +96,7 @@
         }
 
         mCurrentUser = ActivityManager.getCurrentUser();
-        mUserTracker = new CurrentUserTracker(mContext) {
+        mUserTracker = new CurrentUserTracker(broadcastDispatcher) {
             @Override
             public void onUserSwitched(int newUserId) {
                 mCurrentUser = newUserId;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index 4d12cc9..2f13f39 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -42,6 +42,9 @@
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
+import javax.inject.Inject;
 
 public class UsbDebuggingActivity extends AlertActivity
                                   implements DialogInterface.OnClickListener {
@@ -49,12 +52,20 @@
 
     private CheckBox mAlwaysAllow;
     private UsbDisconnectedReceiver mDisconnectedReceiver;
+    private final BroadcastDispatcher mBroadcastDispatcher;
     private String mKey;
 
+    @Inject
+    public UsbDebuggingActivity(BroadcastDispatcher broadcastDispatcher) {
+        super();
+        mBroadcastDispatcher = broadcastDispatcher;
+    }
+
     @Override
     public void onCreate(Bundle icicle) {
         Window window = getWindow();
-        window.addSystemFlags(WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        window.addSystemFlags(
+                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
 
         super.onCreate(icicle);
@@ -138,13 +149,13 @@
     public void onStart() {
         super.onStart();
         IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);
-        registerReceiver(mDisconnectedReceiver, filter);
+        mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter);
     }
 
     @Override
     protected void onStop() {
         if (mDisconnectedReceiver != null) {
-            unregisterReceiver(mDisconnectedReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver);
         }
         super.onStop();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java
index bafd1f1..032b72e 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java
@@ -29,10 +29,19 @@
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
 import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+
+import javax.inject.Inject;
 
 public class UsbDebuggingSecondaryUserActivity extends AlertActivity
         implements DialogInterface.OnClickListener {
     private UsbDisconnectedReceiver mDisconnectedReceiver;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+
+    @Inject
+    public UsbDebuggingSecondaryUserActivity(BroadcastDispatcher broadcastDispatcher) {
+        mBroadcastDispatcher = broadcastDispatcher;
+    }
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -74,13 +83,13 @@
         super.onStart();
 
         IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);
-        registerReceiver(mDisconnectedReceiver, filter);
+        mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter);
     }
 
     @Override
     protected void onStop() {
         if (mDisconnectedReceiver != null) {
-            unregisterReceiver(mDisconnectedReceiver);
+            mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver);
         }
         super.onStop();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java b/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java
index d101ccb..e93e241 100644
--- a/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java
@@ -21,11 +21,10 @@
  * Please keep these constants being consistent with those in com.android.phone.EmergencyDialer.
  */
 public class EmergencyDialerConstants {
-    // Intent action for emergency dialer activity.
-    public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
 
     /**
-     * Extra included in {@link #ACTION_DIAL} to indicate the entry type that user starts
+     * Extra included in {@link android.telecom.TelecomManager#createLaunchEmergencyDialerIntent}
+     * to indicate the entry type that user starts
      * the emergency dialer.
      */
     public static final String EXTRA_ENTRY_TYPE =
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index 5ed027d..60d7678 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -37,7 +37,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.policy.Clock;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -179,11 +178,6 @@
          * Creates the QSCustomizer.
          */
         QSCustomizer createQSCustomizer();
-
-        /**
-         * Creates a Clock.
-         */
-        Clock createClock();
     }
 
     /**
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 7d28392..c1da53b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
@@ -37,6 +38,7 @@
 import android.app.trust.TrustManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
@@ -44,6 +46,8 @@
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -58,6 +62,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.systemui.DumpController;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 
 import org.junit.Assert;
@@ -109,6 +114,8 @@
     private KeyguardBypassController mKeyguardBypassController;
     @Mock
     private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
     private TestableLooper mTestableLooper;
     private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
@@ -143,6 +150,16 @@
     }
 
     @Test
+    public void testReceiversRegistered() {
+        verify(mBroadcastDispatcher, atLeastOnce()).registerReceiver(
+                eq(mKeyguardUpdateMonitor.mBroadcastReceiver),
+                any(IntentFilter.class), any(Handler.class));
+        verify(mBroadcastDispatcher, atLeastOnce()).registerReceiver(
+                eq(mKeyguardUpdateMonitor.mBroadcastAllReceiver),
+                any(IntentFilter.class), any(Handler.class), eq(UserHandle.ALL));
+    }
+
+    @Test
     public void testIgnoresSimStateCallback_rebroadcast() {
         Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
 
@@ -518,10 +535,9 @@
         AtomicBoolean mSimStateChanged = new AtomicBoolean(false);
 
         protected TestableKeyguardUpdateMonitor(Context context) {
-            super(context, TestableLooper.get(KeyguardUpdateMonitorTest.this)
-                    .getLooper(), mDumpController);
-            context.unregisterReceiver(mBroadcastReceiver);
-            context.unregisterReceiver(mBroadcastAllReceiver);
+            super(context,
+                    TestableLooper.get(KeyguardUpdateMonitorTest.this).getLooper(),
+                    mBroadcastDispatcher, mDumpController);
             mStrongAuthTracker = KeyguardUpdateMonitorTest.this.mStrongAuthTracker;
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 7359fdce..1e9000b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -50,6 +50,7 @@
 
 import com.android.systemui.R.dimen;
 import com.android.systemui.ScreenDecorations.TunablePaddingTagListener;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -79,9 +80,13 @@
     private WindowManager mWindowManager;
     private FragmentService mFragmentService;
     private FragmentHostManager mFragmentHostManager;
-    private TunerService mTunerService;
     private StatusBarWindowView mView;
     private TunablePaddingService mTunablePaddingService;
+    private Handler mMainHandler;
+    @Mock
+    private TunerService mTunerService;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private Lazy<StatusBar> mStatusBarLazy;
 
     @Before
@@ -89,10 +94,8 @@
         MockitoAnnotations.initMocks(this);
 
         mTestableLooper = TestableLooper.get(this);
-        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
-                new Handler(mTestableLooper.getLooper()));
+        mMainHandler = new Handler(mTestableLooper.getLooper());
         mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
-        mTunerService = mDependency.injectMockDependency(TunerService.class);
         mFragmentService = mDependency.injectMockDependency(FragmentService.class);
 
         mWindowManager = mock(WindowManager.class);
@@ -108,7 +111,8 @@
         when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
 
 
-        mScreenDecorations = new ScreenDecorations(mContext, mStatusBarLazy) {
+        mScreenDecorations = new ScreenDecorations(mContext, mStatusBarLazy, mMainHandler,
+                mBroadcastDispatcher, mTunerService) {
             @Override
             public void start() {
                 super.start();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java
index a766885..7d55623 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java
@@ -17,6 +17,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
@@ -34,11 +35,14 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.settingslib.SliceBroadcastRelay;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
@@ -47,11 +51,15 @@
     private static final String TEST_ACTION = "com.android.systemui.action.TEST_ACTION";
     private SliceBroadcastRelayHandler mRelayHandler;
     private Context mSpyContext;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
+
     @Before
     public void setup() {
+        MockitoAnnotations.initMocks(this);
         mSpyContext = spy(mContext);
 
-        mRelayHandler = new SliceBroadcastRelayHandler(mSpyContext);
+        mRelayHandler = new SliceBroadcastRelayHandler(mSpyContext, mBroadcastDispatcher);
     }
 
     @Test
@@ -136,6 +144,16 @@
         verify(Receiver.sReceiver, timeout(2000)).onReceive(any(), any());
     }
 
+    @Test
+    public void testRegisteredWithDispatcher() {
+        mRelayHandler.start();
+
+        verify(mBroadcastDispatcher)
+                .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+        verify(mSpyContext, never())
+                .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+    }
+
     public static class Receiver extends BroadcastReceiver {
         private static BroadcastReceiver sReceiver;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 316b891..2ed0b4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -45,6 +45,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.util.sensors.FakeSensorManager;
 
 import org.junit.Before;
@@ -66,6 +67,8 @@
     FakeSensorManager mSensorManager;
     @Mock
     DozeHost mDozeHost;
+    @Mock
+    BroadcastDispatcher mBroadcastDispatcher;
     DozeScreenBrightness mScreen;
 
     @Before
@@ -82,7 +85,7 @@
         mSensorManager = new FakeSensorManager(mContext);
         mSensor = mSensorManager.getFakeLightSensor();
         mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
-                mSensor.getSensor(), mDozeHost, null /* handler */,
+                mSensor.getSensor(), mBroadcastDispatcher, mDozeHost, null /* handler */,
                 DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY,
                 true /* debuggable */);
     }
@@ -185,7 +188,7 @@
     @Test
     public void testNullSensor() throws Exception {
         mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager,
-                null /* sensor */, mDozeHost, null /* handler */,
+                null /* sensor */, mBroadcastDispatcher, mDozeHost, null /* handler */,
                 DEFAULT_BRIGHTNESS, SENSOR_TO_BRIGHTNESS, SENSOR_TO_OPACITY,
                 true /* debuggable */);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 756227e..226bf6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -39,6 +39,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.sensors.AsyncSensorManager;
@@ -66,6 +67,8 @@
     private DozeHost mHost;
     @Mock
     private AlarmManager mAlarmManager;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
     private DozeTriggers mTriggers;
     private FakeSensorManager mSensors;
     private Sensor mTapSensor;
@@ -87,7 +90,7 @@
 
         mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, config, parameters,
                 asyncSensorManager, Handler.createAsync(Looper.myLooper()), wakeLock, true,
-                mDockManagerFake, mProximitySensor, mock(DozeLog.class));
+                mDockManagerFake, mProximitySensor, mock(DozeLog.class), mBroadcastDispatcher);
         waitForSensorManager();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 9312ed2..c815279 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -37,6 +37,7 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -60,6 +61,7 @@
     private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private @Mock StatusBarWindowController mStatusBarWindowController;
     private @Mock SystemUIFactory mSystemUIFactory;
+    private @Mock BroadcastDispatcher mBroadcastDispatcher;
 
     private FalsingManagerFake mFalsingManager;
 
@@ -81,7 +83,8 @@
 
         TestableLooper.get(this).runWithLooper(() -> {
             mViewMediator = new KeyguardViewMediator(
-                    mContext, mFalsingManager, mLockPatternUtils, mSystemUIFactory);
+                    mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher,
+                    mSystemUIFactory);
         });
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityTest.java
index 6e726cf..187c72a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityTest.java
@@ -35,6 +35,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.keyguard.WorkLockActivity;
 
 import org.junit.Before;
@@ -55,12 +56,13 @@
     private @Mock DevicePolicyManager mDevicePolicyManager;
     private @Mock KeyguardManager mKeyguardManager;
     private @Mock Context mContext;
+    private @Mock BroadcastDispatcher mBroadcastDispatcher;
 
     private WorkLockActivity mActivity;
 
     private static class WorkLockActivityTestable extends WorkLockActivity {
-        WorkLockActivityTestable(Context baseContext) {
-            super();
+        WorkLockActivityTestable(Context baseContext, BroadcastDispatcher broadcastDispatcher) {
+            super(broadcastDispatcher);
             attachBaseContext(baseContext);
         }
     }
@@ -77,7 +79,7 @@
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
-        mActivity = new WorkLockActivityTestable(mContext);
+        mActivity = new WorkLockActivityTestable(mContext, mBroadcastDispatcher);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
index 462c82e..098521f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.appops.AppOpItem
 import com.android.systemui.appops.AppOpsController
+import com.android.systemui.broadcast.BroadcastDispatcher
 import org.hamcrest.Matchers.hasItem
 import org.hamcrest.Matchers.not
 import org.hamcrest.Matchers.nullValue
@@ -62,7 +63,6 @@
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
-import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
@@ -89,6 +89,8 @@
     private lateinit var callback: PrivacyItemController.Callback
     @Mock
     private lateinit var userManager: UserManager
+    @Mock
+    private lateinit var broadcastDispatcher: BroadcastDispatcher
     @Captor
     private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>>
     @Captor
@@ -99,7 +101,7 @@
     private lateinit var handler: Handler
 
     fun PrivacyItemController(context: Context) =
-            PrivacyItemController(context, appOpsController, handler, handler)
+            PrivacyItemController(context, appOpsController, handler, handler, broadcastDispatcher)
 
     @Before
     fun setup() {
@@ -180,14 +182,12 @@
 
     @Test
     fun testRegisterReceiver_allUsers() {
-        val spiedContext = spy(mContext)
-        val itemController = PrivacyItemController(spiedContext)
-        itemController.addCallback(callback)
+        privacyItemController.addCallback(callback)
         testableLooper.processAllMessages()
-        verify(spiedContext, atLeastOnce()).registerReceiverAsUser(
-                eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null),
-                eq(null))
-        verify(spiedContext, never()).unregisterReceiver(eq(itemController.userSwitcherReceiver))
+        verify(broadcastDispatcher, atLeastOnce()).registerReceiver(
+                eq(privacyItemController.userSwitcherReceiver), any(), eq(null), eq(UserHandle.ALL))
+        verify(broadcastDispatcher, never())
+                .unregisterReceiver(eq(privacyItemController.userSwitcherReceiver))
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index ca30bed..a31fc3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -39,6 +39,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.tileimpl.QSFactoryImpl;
 import com.android.systemui.shared.plugins.PluginManager;
@@ -98,7 +99,8 @@
         QSTileHost host = new QSTileHost(mContext, mock(StatusBarIconController.class),
                 mock(QSFactoryImpl.class), new Handler(), Looper.myLooper(),
                 mock(PluginManager.class), mock(TunerService.class),
-                () -> mock(AutoTileManager.class), mock(DumpController.class));
+                () -> mock(AutoTileManager.class), mock(DumpController.class),
+                mock(BroadcastDispatcher.class));
         qs.setHost(host);
 
         qs.setListening(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 7752014..0247c2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -41,6 +41,7 @@
 import com.android.systemui.DumpController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.tileimpl.QSFactoryImpl;
@@ -84,6 +85,8 @@
     @Mock
     private DumpController mDumpController;
     @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
     private QSTile.State mMockState;
     private Handler mHandler;
     private TestableLooper mLooper;
@@ -96,7 +99,7 @@
         mHandler = new Handler(mLooper.getLooper());
         mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
                 mLooper.getLooper(),
-                mPluginManager, mTunerService, mAutoTiles, mDumpController);
+                mPluginManager, mTunerService, mAutoTiles, mDumpController, mBroadcastDispatcher);
         setUpTileFactory();
         Settings.Secure.putStringForUser(mContext.getContentResolver(), QSTileHost.TILES_SETTING,
                 "", ActivityManager.getCurrentUser());
@@ -168,9 +171,10 @@
         TestQSTileHost(Context context, StatusBarIconController iconController,
                 QSFactoryImpl defaultFactory, Handler mainHandler, Looper bgLooper,
                 PluginManager pluginManager, TunerService tunerService,
-                Provider<AutoTileManager> autoTiles, DumpController dumpController) {
+                Provider<AutoTileManager> autoTiles, DumpController dumpController,
+                BroadcastDispatcher broadcastDispatcher) {
             super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
-                    tunerService, autoTiles, dumpController);
+                    tunerService, autoTiles, dumpController, broadcastDispatcher);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
index 11b0c69..9e5e582 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
@@ -45,6 +45,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import org.junit.After;
 import org.junit.Before;
@@ -59,6 +60,8 @@
 
     private final PackageManagerAdapter mMockPackageManagerAdapter =
             Mockito.mock(PackageManagerAdapter.class);
+    private final BroadcastDispatcher mMockBroadcastDispatcher =
+            Mockito.mock(BroadcastDispatcher.class);
     private final IQSTileService.Stub mMockTileService = Mockito.mock(IQSTileService.Stub.class);
     private ComponentName mTileServiceComponentName;
     private Intent mTileServiceIntent;
@@ -87,7 +90,8 @@
                 Mockito.mock(IQSService.class), new Tile(),
                 mTileServiceIntent,
                 mUser,
-                mMockPackageManagerAdapter);
+                mMockPackageManagerAdapter,
+                mMockBroadcastDispatcher);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index d18cebb..824c50d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -32,6 +32,7 @@
 
 import com.android.systemui.DumpController;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.tileimpl.QSFactoryImpl;
 import com.android.systemui.shared.plugins.PluginManager;
@@ -45,7 +46,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 
@@ -57,21 +60,37 @@
 
     private TileServices mTileService;
     private ArrayList<TileServiceManager> mManagers;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
+    private StatusBarIconController mStatusBarIconController;
+    @Mock
+    private QSFactoryImpl mQSFactory;
+    @Mock
+    private PluginManager mPluginManager;
+    @Mock
+    private  TunerService mTunerService;
+    @Mock
+    private AutoTileManager mAutoTileManager;
+    @Mock
+    private DumpController mDumpController;
 
     @Before
     public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
         mDependency.injectMockDependency(BluetoothController.class);
         mManagers = new ArrayList<>();
         QSTileHost host = new QSTileHost(mContext,
-                mock(StatusBarIconController.class),
-                mock(QSFactoryImpl.class),
+                mStatusBarIconController,
+                mQSFactory,
                 new Handler(),
                 Looper.myLooper(),
-                mock(PluginManager.class),
-                mock(TunerService.class),
-                () -> mock(AutoTileManager.class),
-                mock(DumpController.class));
-        mTileService = new TestTileServices(host, Looper.getMainLooper());
+                mPluginManager,
+                mTunerService,
+                () -> mAutoTileManager,
+                mDumpController,
+                mBroadcastDispatcher);
+        mTileService = new TestTileServices(host, Looper.getMainLooper(), mBroadcastDispatcher);
     }
 
     @After
@@ -138,12 +157,14 @@
     }
 
     private class TestTileServices extends TileServices {
-        public TestTileServices(QSTileHost host, Looper looper) {
-            super(host, looper);
+        TestTileServices(QSTileHost host, Looper looper,
+                BroadcastDispatcher broadcastDispatcher) {
+            super(host, looper, broadcastDispatcher);
         }
 
         @Override
-        protected TileServiceManager onCreateTileService(ComponentName component, Tile qsTile) {
+        protected TileServiceManager onCreateTileService(ComponentName component, Tile qsTile,
+                BroadcastDispatcher broadcastDispatcher) {
             TileServiceManager manager = mock(TileServiceManager.class);
             mManagers.add(manager);
             when(manager.isLifecycleStarted()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/CurrentUserTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/settings/CurrentUserTrackerTest.java
index 4162bc1..1b515c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/CurrentUserTrackerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/CurrentUserTrackerTest.java
@@ -21,9 +21,12 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Testing functionality of the current user tracker
@@ -33,10 +36,13 @@
 
     private CurrentUserTracker mTracker;
     private CurrentUserTracker.UserReceiver mReceiver;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
 
     @Before
     public void setUp() {
-        mReceiver = new CurrentUserTracker.UserReceiver(getContext());
+        MockitoAnnotations.initMocks(this);
+        mReceiver = new CurrentUserTracker.UserReceiver(mBroadcastDispatcher);
         mTracker = new CurrentUserTracker(mReceiver) {
             @Override
             public void onUserSwitched(int newUserId) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 85a0fbd..548f7a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -47,6 +47,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -74,6 +75,7 @@
     @Mock private NotificationData mNotificationData;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
     @Mock private StatusBarKeyguardViewManager mKeyguardViewManager;
+    @Mock private BroadcastDispatcher mBroadcastDispatcher;
 
     private int mCurrentUserId;
     private TestNotificationLockscreenUserManager mLockscreenUserManager;
@@ -194,7 +196,7 @@
     private class TestNotificationLockscreenUserManager
             extends NotificationLockscreenUserManagerImpl {
         public TestNotificationLockscreenUserManager(Context context) {
-            super(context);
+            super(context, mBroadcastDispatcher);
         }
 
         public BroadcastReceiver getBaseBroadcastReceiverForTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index e626d08..48ed4ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -27,6 +27,7 @@
 import android.testing.TestableLooper;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.power.EnhancedEstimates;
 
 import org.junit.Assert;
@@ -44,13 +45,15 @@
 
     @Mock
     private PowerManager mPowerManager;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
     private BatteryControllerImpl mBatteryController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mBatteryController = new BatteryControllerImpl(getContext(), mock(EnhancedEstimates.class),
-                mPowerManager);
+                mPowerManager, mBroadcastDispatcher);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
index 3dcb34a..5f772b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -27,6 +27,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
 
 import org.junit.Before;
@@ -44,7 +45,8 @@
     @Before
     public void setup() {
         mLocationController = spy(new LocationControllerImpl(mContext,
-                TestableLooper.get(this).getLooper()));
+                TestableLooper.get(this).getLooper(),
+                mock(BroadcastDispatcher.class)));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index c03f07e..4d86613 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -56,6 +56,7 @@
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -93,6 +94,7 @@
     protected WifiManager mMockWm;
     protected SubscriptionManager mMockSm;
     protected TelephonyManager mMockTm;
+    protected BroadcastDispatcher mMockBd;
     protected Config mConfig;
     protected CallbackHandler mCallbackHandler;
     protected SubscriptionDefaults mMockSubDefaults;
@@ -130,6 +132,7 @@
         mMockTm = mock(TelephonyManager.class);
         mMockSm = mock(SubscriptionManager.class);
         mMockCm = mock(ConnectivityManager.class);
+        mMockBd = mock(BroadcastDispatcher.class);
         mMockSubDefaults = mock(SubscriptionDefaults.class);
         mNetCapabilities = new NetworkCapabilities();
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
@@ -157,7 +160,7 @@
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
-                mMockSubDefaults, mMockProvisionController);
+                mMockSubDefaults, mMockProvisionController, mMockBd);
         setupNetworkController();
 
         // Trigger blank callbacks to always get the current state (some tests don't trigger
@@ -208,7 +211,7 @@
                         mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
                         mock(DataUsageController.class), mMockSubDefaults,
-                        mock(DeviceProvisionedController.class));
+                        mock(DeviceProvisionedController.class), mMockBd);
 
       setupNetworkController();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index aa4723a..ab74caa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -108,7 +108,7 @@
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class),
                 mock(DataUsageController.class), mMockSubDefaults,
-                mock(DeviceProvisionedController.class));
+                mock(DeviceProvisionedController.class), mMockBd);
         setupNetworkController();
 
         setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 0b53c48..57dcbf2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -61,7 +61,7 @@
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
-                mMockSubDefaults, mock(DeviceProvisionedController.class));
+                mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd);
         setupNetworkController();
 
         verifyLastMobileDataIndicators(false, -1, 0);
@@ -123,7 +123,7 @@
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
-                mMockSubDefaults, mock(DeviceProvisionedController.class));
+                mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd);
         setupNetworkController();
 
         // No Subscriptions.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index 97542a9..0c9130d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -45,6 +45,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.policy.SecurityController.SecurityControllerCallback;
 
 import org.junit.After;
@@ -99,7 +100,7 @@
         // TODO: Migrate this test to TestableLooper and use a handler attached
         // to that.
         mSecurityController = new SecurityControllerImpl(mContext,
-                new Handler(Looper.getMainLooper()), this);
+                new Handler(Looper.getMainLooper()), mock(BroadcastDispatcher.class), this);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
index 47e4492..dcf0ef7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
@@ -33,6 +33,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.statusbar.policy.ZenModeController.Callback;
 
 import org.junit.Before;
@@ -51,6 +52,8 @@
     NotificationManager mNm;
     @Mock
     ZenModeConfig mConfig;
+    @Mock
+    BroadcastDispatcher mBroadcastDispatcher;
 
     private ZenModeControllerImpl mController;
 
@@ -60,7 +63,8 @@
         mContext.addMockSystemService(NotificationManager.class, mNm);
         when(mNm.getZenModeConfig()).thenReturn(mConfig);
 
-        mController = new ZenModeControllerImpl(mContext, Handler.createAsync(Looper.myLooper()));
+        mController = new ZenModeControllerImpl(mContext, Handler.createAsync(Looper.myLooper()),
+                mBroadcastDispatcher);
     }
 
     @Test