Converted ThemeUtil into a DaggerModule.

This enables us to have Google-Sans font in GoogleDialer and Roboto in AOSP.

Bug: 79883035
Test: tap
PiperOrigin-RevId: 197774497
Change-Id: I1d490ab196a444c62e439444627d659fc42973ea
diff --git a/java/com/android/contacts/common/list/ViewPagerTabStrip.java b/java/com/android/contacts/common/list/ViewPagerTabStrip.java
index fa345e4..88c0369 100644
--- a/java/com/android/contacts/common/list/ViewPagerTabStrip.java
+++ b/java/com/android/contacts/common/list/ViewPagerTabStrip.java
@@ -24,7 +24,7 @@
 import android.view.View;
 import android.widget.LinearLayout;
 import com.android.contacts.common.R;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 
 public class ViewPagerTabStrip extends LinearLayout {
 
@@ -43,8 +43,8 @@
     final Resources res = context.getResources();
 
     mSelectedUnderlineThickness = res.getDimensionPixelSize(R.dimen.tab_selected_underline_height);
-    int underlineColor = ThemeUtil.getColorAccent();
-    int backgroundColor = ThemeUtil.getColorPrimary();
+    int underlineColor = ThemeComponent.get(context).theme().getColorAccent();
+    int backgroundColor = ThemeComponent.get(context).theme().getColorPrimary();
 
     mSelectedUnderlinePaint = new Paint();
     mSelectedUnderlinePaint.setColor(underlineColor);
diff --git a/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java b/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java
index f142399..ccf12ae 100644
--- a/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java
+++ b/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java
@@ -37,6 +37,7 @@
 import com.android.dialer.notification.NotificationChannelManager;
 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
 import com.android.dialer.telecom.TelecomUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 
 /** Shows a notification in the status bar for legacy vociemail. */
 @TargetApi(VERSION_CODES.O)
@@ -115,7 +116,7 @@
     Notification.Builder builder =
         new Notification.Builder(context)
             .setSmallIcon(android.R.drawable.stat_notify_voicemail)
-            .setColor(context.getColor(R.color.dialer_theme_color))
+            .setColor(ThemeComponent.get(context).theme().getColorPrimary())
             .setWhen(System.currentTimeMillis())
             .setContentTitle(notificationTitle)
             .setContentText(contentText)
diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
index f671fb7..4b5bfba 100644
--- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java
+++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java
@@ -62,6 +62,7 @@
 import com.android.dialer.phonenumbercache.ContactInfo;
 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
 import com.android.dialer.precall.PreCall;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.IntentUtil;
 import java.util.Iterator;
@@ -396,7 +397,7 @@
     return new Notification.Builder(context)
         .setGroup(MissedCallConstants.GROUP_KEY)
         .setSmallIcon(android.R.drawable.stat_notify_missed_call)
-        .setColor(context.getResources().getColor(R.color.dialer_theme_color, null))
+        .setColor(ThemeComponent.get(context).theme().getColorPrimary())
         .setAutoCancel(true)
         .setOnlyAlertOnce(true)
         .setShowWhen(true)
diff --git a/java/com/android/dialer/app/calllog/PhoneCallDetailsHelper.java b/java/com/android/dialer/app/calllog/PhoneCallDetailsHelper.java
index 108a11b..2632fb3 100644
--- a/java/com/android/dialer/app/calllog/PhoneCallDetailsHelper.java
+++ b/java/com/android/dialer/app/calllog/PhoneCallDetailsHelper.java
@@ -51,7 +51,7 @@
 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
 import com.android.dialer.spannable.ContentWithLearnMoreSpanner;
 import com.android.dialer.storage.StorageComponent;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.DialerUtils;
 import com.android.voicemail.VoicemailClient;
 import com.android.voicemail.VoicemailComponent;
@@ -270,7 +270,9 @@
     views.voicemailTranscriptionBrandingView.setTypeface(typeface);
     views.callLocationAndDate.setTypeface(typeface);
     views.callLocationAndDate.setTextColor(
-        details.isRead ? ThemeUtil.getTextColorSecondary() : ThemeUtil.getTextColorPrimary());
+        details.isRead
+            ? ThemeComponent.get(context).theme().getTextColorSecondary()
+            : ThemeComponent.get(context).theme().getTextColorPrimary());
   }
 
   private void setNameView(PhoneCallDetailsViews views, PhoneCallDetails details) {
@@ -391,11 +393,11 @@
     textView.setMovementMethod(LinkMovementMethod.getInstance());
     Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
     if (positiveButton != null) {
-      positiveButton.setTextColor(ThemeUtil.getColorPrimary());
+      positiveButton.setTextColor(ThemeComponent.get(context).theme().getColorPrimary());
     }
     Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
     if (negativeButton != null) {
-      negativeButton.setTextColor(ThemeUtil.getTextColorSecondary());
+      negativeButton.setTextColor(ThemeComponent.get(context).theme().getTextColorSecondary());
     }
   }
 
diff --git a/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java b/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java
index 793d962..a29bb62 100644
--- a/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java
+++ b/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java
@@ -47,6 +47,7 @@
 import com.android.dialer.notification.NotificationManagerUtils;
 import com.android.dialer.phonenumbercache.ContactInfo;
 import com.android.dialer.telecom.TelecomUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import java.util.List;
 import java.util.Map;
 
@@ -144,7 +145,7 @@
   private static NotificationCompat.Builder createNotificationBuilder(@NonNull Context context) {
     return new NotificationCompat.Builder(context)
         .setSmallIcon(android.R.drawable.stat_notify_voicemail)
-        .setColor(context.getColor(R.color.dialer_theme_color))
+        .setColor(ThemeComponent.get(context).theme().getColorPrimary())
         .setGroup(GROUP_KEY)
         .setOnlyAlertOnce(true)
         .setAutoCancel(true);
diff --git a/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java b/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java
index ab03080..bf40fdf 100644
--- a/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java
+++ b/java/com/android/dialer/app/filterednumber/BlockedNumbersFragment.java
@@ -23,7 +23,6 @@
 import android.database.Cursor;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
-import android.support.v4.app.ActivityCompat;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AppCompatActivity;
 import android.view.LayoutInflater;
@@ -39,7 +38,7 @@
 import com.android.dialer.blocking.FilteredNumbersUtil.ImportSendToVoicemailContactsListener;
 import com.android.dialer.database.FilteredNumberContract;
 import com.android.dialer.lettertile.LetterTileDrawable;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.voicemailstatus.VisualVoicemailEnabledChecker;
 
 /** TODO(calderwoodra): documentation */
@@ -75,7 +74,7 @@
     //replace the icon for add number with LetterTileDrawable(), so it will have identical style
     LetterTileDrawable drawable = new LetterTileDrawable(getResources());
     drawable.setLetter(ADD_BLOCKED_NUMBER_ICON_LETTER);
-    drawable.setColor(ThemeUtil.getColorIcon());
+    drawable.setColor(ThemeComponent.get(getContext()).theme().getColorIcon());
     drawable.setIsCircular(true);
 
     if (adapter == null) {
@@ -119,7 +118,7 @@
 
     ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
     ColorDrawable backgroundDrawable =
-        new ColorDrawable(ActivityCompat.getColor(getActivity(), R.color.dialer_theme_color));
+        new ColorDrawable(ThemeComponent.get(getContext()).theme().getColorPrimary());
     actionBar.setBackgroundDrawable(backgroundDrawable);
     actionBar.setDisplayShowCustomEnabled(false);
     actionBar.setDisplayHomeAsUpEnabled(true);
diff --git a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
index e650e77..ae068ac 100644
--- a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
+++ b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
@@ -41,6 +41,7 @@
 import com.android.dialer.spam.stub.StubSpamModule;
 import com.android.dialer.storage.StorageModule;
 import com.android.dialer.strictmode.impl.SystemStrictModeModule;
+import com.android.dialer.theme.base.impl.AospThemeModule;
 import com.android.incallui.calllocation.stub.StubCallLocationModule;
 import com.android.incallui.maps.stub.StubMapsModule;
 import com.android.incallui.speakeasy.StubSpeakEasyModule;
@@ -79,6 +80,7 @@
       StubSpamModule.class,
       StubSpeakEasyModule.class,
       SystemStrictModeModule.class,
+      AospThemeModule.class,
       VoicemailModule.class,
     })
 public interface AospDialerRootComponent extends BaseDialerRootComponent {}
diff --git a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
index 1d346ac..666a0be 100644
--- a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
+++ b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
@@ -42,6 +42,7 @@
 import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
 import com.android.dialer.storage.StorageComponent;
 import com.android.dialer.strictmode.StrictModeComponent;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.incallui.calllocation.CallLocationComponent;
 import com.android.incallui.maps.MapsComponent;
 import com.android.incallui.speakeasy.SpeakEasyComponent;
@@ -81,4 +82,5 @@
         SpeakEasyComponent.HasComponent,
         StorageComponent.HasComponent,
         StrictModeComponent.HasComponent,
+        ThemeComponent.HasComponent,
         VoicemailComponent.HasComponent {}
diff --git a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
index 8c0ac56..622bd5d 100644
--- a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
+++ b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
@@ -41,6 +41,7 @@
 import com.android.dialer.spam.stub.StubSpamModule;
 import com.android.dialer.storage.StorageModule;
 import com.android.dialer.strictmode.impl.SystemStrictModeModule;
+import com.android.dialer.theme.base.impl.AospThemeModule;
 import com.android.incallui.calllocation.impl.CallLocationModule;
 import com.android.incallui.maps.impl.MapsModule;
 import com.android.incallui.speakeasy.StubSpeakEasyModule;
@@ -82,6 +83,7 @@
       StubSpamModule.class,
       StubSpeakEasyModule.class,
       SystemStrictModeModule.class,
+      AospThemeModule.class,
       VoicemailModule.class,
     })
 public interface GoogleStubDialerRootComponent extends BaseDialerRootComponent {}
diff --git a/java/com/android/dialer/blockreportspam/res/layout/block_report_spam_dialog.xml b/java/com/android/dialer/blockreportspam/res/layout/block_report_spam_dialog.xml
index 9ae30b6..af89ab7 100644
--- a/java/com/android/dialer/blockreportspam/res/layout/block_report_spam_dialog.xml
+++ b/java/com/android/dialer/blockreportspam/res/layout/block_report_spam_dialog.xml
@@ -16,7 +16,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
-  android:padding="25dp"
+  android:padding="24dp"
   android:orientation="vertical">
   <TextView
     android:id="@+id/block_details"
@@ -24,12 +24,13 @@
     android:layout_height="wrap_content"
     android:layout_marginBottom="10dp"
     android:text="@string/block_report_number_alert_details"
-    style="@style/Dialer.TextAppearance.Primary"/>
+    style="@style/Dialer.TextAppearance.Secondary"/>
 
   <CheckBox
     android:id="@+id/report_number_as_spam_action"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="@string/checkbox_report_as_spam_action"
-    android:textSize="@dimen/blocked_report_spam_primary_text_size"/>
+    android:textSize="@dimen/blocked_report_spam_primary_text_size"
+    style="@style/DialerCheckboxStyle"/>
 </LinearLayout>
diff --git a/java/com/android/dialer/callcomposer/CameraComposerFragment.java b/java/com/android/dialer/callcomposer/CameraComposerFragment.java
index a5c65fd..4881220 100644
--- a/java/com/android/dialer/callcomposer/CameraComposerFragment.java
+++ b/java/com/android/dialer/callcomposer/CameraComposerFragment.java
@@ -26,7 +26,6 @@
 import android.provider.Settings;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -49,6 +48,7 @@
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.PermissionsUtil;
 
 /** Fragment used to compose call with image from the user's camera. */
@@ -117,8 +117,7 @@
       allowPermission.setOnClickListener(this);
       permissionText.setText(R.string.camera_permission_text);
       permissionImage.setImageResource(R.drawable.quantum_ic_camera_alt_white_48);
-      permissionImage.setColorFilter(
-          ContextCompat.getColor(getContext(), R.color.dialer_theme_color));
+      permissionImage.setColorFilter(ThemeComponent.get(getContext()).theme().getColorPrimary());
       permissionView.setVisibility(View.VISIBLE);
     } else {
       if (bundle != null) {
diff --git a/java/com/android/dialer/callcomposer/GalleryComposerFragment.java b/java/com/android/dialer/callcomposer/GalleryComposerFragment.java
index e604ec1..6265308 100644
--- a/java/com/android/dialer/callcomposer/GalleryComposerFragment.java
+++ b/java/com/android/dialer/callcomposer/GalleryComposerFragment.java
@@ -29,7 +29,6 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v4.app.LoaderManager.LoaderCallbacks;
-import android.support.v4.content.ContextCompat;
 import android.support.v4.content.CursorLoader;
 import android.support.v4.content.Loader;
 import android.view.LayoutInflater;
@@ -44,6 +43,7 @@
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.PermissionsUtil;
 import java.util.ArrayList;
 import java.util.List;
@@ -94,8 +94,7 @@
       allowPermission.setOnClickListener(this);
       permissionText.setText(R.string.gallery_permission_text);
       permissionImage.setImageResource(R.drawable.quantum_ic_photo_white_48);
-      permissionImage.setColorFilter(
-          ContextCompat.getColor(getContext(), R.color.dialer_theme_color));
+      permissionImage.setColorFilter(ThemeComponent.get(getContext()).theme().getColorPrimary());
       permissionView.setVisibility(View.VISIBLE);
     } else {
       if (bundle != null) {
diff --git a/java/com/android/dialer/calldetails/ReportDialogFragment.java b/java/com/android/dialer/calldetails/ReportDialogFragment.java
index d75fe51..e1c0e9d 100644
--- a/java/com/android/dialer/calldetails/ReportDialogFragment.java
+++ b/java/com/android/dialer/calldetails/ReportDialogFragment.java
@@ -37,6 +37,7 @@
 import com.android.dialer.phonenumbercache.CachedNumberLookupService;
 import com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
 import com.android.dialer.phonenumbercache.PhoneNumberCache;
+import com.android.dialer.theme.base.ThemeComponent;
 
 /** Dialog for reporting an inaccurate caller id information. */
 public class ReportDialogFragment extends DialogFragment {
@@ -92,7 +93,7 @@
   }
 
   private static void onShow(Context context, AlertDialog dialog) {
-    int buttonTextColor = context.getColor(R.color.dialer_theme_color);
+    int buttonTextColor = ThemeComponent.get(context).theme().getColorPrimary();
     dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(buttonTextColor);
     dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(buttonTextColor);
   }
diff --git a/java/com/android/dialer/calllogutils/CallTypeIconsView.java b/java/com/android/dialer/calllogutils/CallTypeIconsView.java
index 990fa73..19c30c5 100644
--- a/java/com/android/dialer/calllogutils/CallTypeIconsView.java
+++ b/java/com/android/dialer/calllogutils/CallTypeIconsView.java
@@ -27,7 +27,8 @@
 import android.support.annotation.VisibleForTesting;
 import android.util.AttributeSet;
 import android.view.View;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.Theme;
+import com.android.dialer.theme.base.ThemeComponent;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -304,40 +305,41 @@
       missed = drawable.mutate();
       missed.setColorFilter(r.getColor(R.color.dialer_red), PorterDuff.Mode.MULTIPLY);
 
+      Theme theme = ThemeComponent.get(context).theme();
       iconId = R.drawable.quantum_ic_voicemail_white_24;
       drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId);
       voicemail = drawable.mutate();
-      voicemail.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      voicemail.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconId = R.drawable.quantum_ic_block_white_24;
       drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId);
       blocked = drawable.mutate();
-      blocked.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      blocked.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconId = R.drawable.quantum_ic_videocam_vd_white_24;
       drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId);
       videoCall = drawable.mutate();
-      videoCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      videoCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconId = R.drawable.quantum_ic_hd_white_24;
       drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId);
       hdCall = drawable.mutate();
-      hdCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      hdCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconId = R.drawable.quantum_ic_signal_wifi_4_bar_white_24;
       drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId);
       wifiCall = drawable.mutate();
-      wifiCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      wifiCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconId = R.drawable.quantum_ic_language_white_24;
       drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId);
       assistedDialedCall = drawable.mutate();
-      assistedDialedCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      assistedDialedCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconId = R.drawable.quantum_ic_rtt_vd_theme_24;
       drawable = largeIcons ? r.getDrawable(iconId, null) : getScaledBitmap(context, iconId);
       rttCall = drawable.mutate();
-      rttCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY);
+      rttCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY);
 
       iconMargin = largeIcons ? 0 : r.getDimensionPixelSize(R.dimen.call_log_icon_margin);
     }
diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java
index 206a2d3..f5cdc4d 100644
--- a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java
+++ b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java
@@ -33,7 +33,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import com.android.dialer.common.Assert;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.widget.ContactPhotoView;
 import java.util.List;
 
@@ -156,7 +156,8 @@
         .setImageResource(module.getDrawableId());
     if (module.tintDrawable()) {
       ((ImageView) moduleView.findViewById(R.id.module_image))
-          .setImageTintList(ColorStateList.valueOf(ThemeUtil.getColorIcon()));
+          .setImageTintList(
+              ColorStateList.valueOf(ThemeComponent.get(getContext()).theme().getColorIcon()));
     }
     moduleView.setOnClickListener(this);
     moduleView.setTag(module);
diff --git a/java/com/android/dialer/inject/ContextModule.java b/java/com/android/dialer/inject/ContextModule.java
index edfc42f..72febbb 100644
--- a/java/com/android/dialer/inject/ContextModule.java
+++ b/java/com/android/dialer/inject/ContextModule.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.support.annotation.NonNull;
-import com.android.dialer.theme.base.ThemeUtil;
 import dagger.Module;
 import dagger.Provides;
 
@@ -30,8 +29,7 @@
   @NonNull private final Context context;
 
   public ContextModule(@NonNull Context appContext) {
-    ThemeUtil.initializeTheme(appContext);
-    this.context = ThemeUtil.getThemedContext(appContext);
+    this.context = appContext;
   }
 
   @Provides
diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
index 62ad5b5..e14c5b9 100644
--- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java
+++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
@@ -116,8 +116,8 @@
 import com.android.dialer.speeddial.SpeedDialFragment;
 import com.android.dialer.storage.StorageComponent;
 import com.android.dialer.telecom.TelecomUtil;
-import com.android.dialer.theme.base.ThemeUtil;
-import com.android.dialer.theme.base.ThemeUtil.Theme;
+import com.android.dialer.theme.base.Theme;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.util.PermissionsUtil;
 import com.android.dialer.util.TransactionSafeActivity;
@@ -240,15 +240,16 @@
 
   /** should be called before {@link AppCompatActivity#setContentView(int)}. */
   private void setTheme() {
-    @Theme int theme = ThemeUtil.getTheme();
+    @Theme.Type int theme = ThemeComponent.get(activity).theme().getTheme();
     switch (theme) {
-      case ThemeUtil.DARK:
+      case Theme.DARK:
         activity.setTheme(R.style.MainActivityTheme_Dark);
         break;
-      case ThemeUtil.LIGHT:
+      case Theme.LIGHT:
+      case Theme.LIGHT_M2:
         activity.setTheme(R.style.MainActivityTheme);
         break;
-      case ThemeUtil.UNKNOWN:
+      case Theme.UNKNOWN:
       default:
         throw new IllegalArgumentException("Invalid theme.");
     }
diff --git a/java/com/android/dialer/main/impl/bottomnav/BottomNavItem.java b/java/com/android/dialer/main/impl/bottomnav/BottomNavItem.java
index dec6350..3a43f84 100644
--- a/java/com/android/dialer/main/impl/bottomnav/BottomNavItem.java
+++ b/java/com/android/dialer/main/impl/bottomnav/BottomNavItem.java
@@ -30,7 +30,7 @@
 import android.widget.TextView;
 import com.android.dialer.common.Assert;
 import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 
 /** Navigation item in a bottom nav. */
 final class BottomNavItem extends LinearLayout {
@@ -54,7 +54,10 @@
   @Override
   public void setSelected(boolean selected) {
     super.setSelected(selected);
-    int colorId = selected ? ThemeUtil.getColorPrimary() : ThemeUtil.getTextColorSecondary();
+    int colorId =
+        selected
+            ? ThemeComponent.get(getContext()).theme().getColorPrimary()
+            : ThemeComponent.get(getContext()).theme().getTextColorSecondary();
     image.setImageTintList(ColorStateList.valueOf(colorId));
     text.setTextColor(colorId);
   }
diff --git a/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java
index a24c238..34209cc 100644
--- a/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java
+++ b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java
@@ -36,6 +36,7 @@
 import com.android.dialer.spam.SpamSettings;
 import com.android.dialer.spam.promo.SpamBlockingPromoDialogFragment.OnEnableListener;
 import com.android.dialer.storage.StorageComponent;
+import com.android.dialer.theme.base.ThemeComponent;
 
 /** Helper class for showing spam blocking on-boarding promotions. */
 public class SpamBlockingPromoHelper {
@@ -178,7 +179,7 @@
             .setContentIntent(contentIntent)
             .setCategory(Notification.CATEGORY_STATUS)
             .setPriority(Notification.PRIORITY_DEFAULT)
-            .setColor(context.getColor(R.color.dialer_theme_color))
+            .setColor(ThemeComponent.get(context).theme().getColorPrimary())
             .setSmallIcon(R.drawable.quantum_ic_call_vd_theme_24)
             .setLargeIcon(Icon.createWithResource(context, R.drawable.spam_blocking_promo_icon))
             .setContentText(context.getString(R.string.spam_blocking_promo_text))
diff --git a/java/com/android/dialer/theme/base/Theme.java b/java/com/android/dialer/theme/base/Theme.java
new file mode 100644
index 0000000..6e0d20a
--- /dev/null
+++ b/java/com/android/dialer/theme/base/Theme.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.theme.base;
+
+import android.content.Context;
+import android.support.annotation.ColorInt;
+import android.support.annotation.IntDef;
+import android.support.annotation.StyleRes;
+import android.view.LayoutInflater;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Interface for theme. */
+public interface Theme {
+
+  /** IntDef for the different themes Dialer supports. */
+  @Retention(RetentionPolicy.SOURCE)
+  @IntDef({UNKNOWN, LIGHT, DARK, LIGHT_M2})
+  @interface Type {}
+
+  int UNKNOWN = 0;
+  int LIGHT = 1;
+  int DARK = 2;
+  int LIGHT_M2 = 3;
+
+  @Type
+  int getTheme();
+
+  @StyleRes
+  int getApplicationThemeRes();
+
+  Context getThemedContext(Context context);
+
+  LayoutInflater getThemedLayoutInflator(LayoutInflater inflater);
+
+  @ColorInt
+  int getColorIcon();
+
+  @ColorInt
+  int getColorIconSecondary();
+
+  @ColorInt
+  int getColorPrimary();
+
+  @ColorInt
+  int getColorPrimaryDark();
+
+  @ColorInt
+  int getColorAccent();
+
+  @ColorInt
+  int getTextColorSecondary();
+
+  @ColorInt
+  int getTextColorPrimary();
+
+  @ColorInt
+  int getColorTextOnUnthemedDarkBackground();
+
+  @ColorInt
+  int getColorIconOnUnthemedDarkBackground();
+}
diff --git a/java/com/android/dialer/theme/base/ThemeComponent.java b/java/com/android/dialer/theme/base/ThemeComponent.java
new file mode 100644
index 0000000..d906761
--- /dev/null
+++ b/java/com/android/dialer/theme/base/ThemeComponent.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.theme.base;
+
+import android.content.Context;
+import com.android.dialer.inject.HasRootComponent;
+import com.android.dialer.inject.IncludeInDialerRoot;
+import dagger.Subcomponent;
+
+/** Component for Theme. */
+@Subcomponent
+public abstract class ThemeComponent {
+
+  public abstract Theme theme();
+
+  public static ThemeComponent get(Context context) {
+    return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
+        .themeComponent();
+  }
+
+  /** Used to refer to the root application component. */
+  @IncludeInDialerRoot
+  public interface HasComponent {
+    ThemeComponent themeComponent();
+  }
+}
diff --git a/java/com/android/dialer/theme/base/ThemeUtil.java b/java/com/android/dialer/theme/base/impl/AospThemeImpl.java
similarity index 68%
rename from java/com/android/dialer/theme/base/ThemeUtil.java
rename to java/com/android/dialer/theme/base/impl/AospThemeImpl.java
index a2d70c9..b8c7e52 100644
--- a/java/com/android/dialer/theme/base/ThemeUtil.java
+++ b/java/com/android/dialer/theme/base/impl/AospThemeImpl.java
@@ -14,51 +14,39 @@
  * limitations under the License.
  */
 
-package com.android.dialer.theme.base;
+package com.android.dialer.theme.base.impl;
 
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.ColorInt;
-import android.support.annotation.IntDef;
 import android.support.annotation.StyleRes;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import com.android.dialer.common.Assert;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import com.android.dialer.theme.base.R;
+import com.android.dialer.theme.base.Theme;
+import javax.inject.Singleton;
 
 /** Utility for fetching */
 @SuppressWarnings("unused")
-public class ThemeUtil {
+@Singleton
+public class AospThemeImpl implements Theme {
 
-  /** IntDef for the different themes Dialer supports. */
-  @Retention(RetentionPolicy.SOURCE)
-  @IntDef({UNKNOWN, LIGHT, DARK})
-  public @interface Theme {}
+  private int colorIcon = -1;
+  private int colorIconSecondary = -1;
+  private int colorPrimary = -1;
+  private int colorPrimaryDark = -1;
+  private int colorAccent = -1;
+  private int textColorPrimary = -1;
+  private int textColorSecondary = -1;
+  private int textColorPrimaryInverse = -1;
+  private int textColorHint = -1;
+  private int colorBackground = -1;
+  private int colorBackgroundFloating = -1;
+  private int colorTextOnUnthemedDarkBackground = -1;
+  private int colorIconOnUnthemedDarkBackground = -1;
 
-  public static final int UNKNOWN = 0;
-  public static final int LIGHT = 1;
-  public static final int DARK = 2;
-
-  private static @Theme int theme = UNKNOWN;
-
-  private static int colorIcon = -1;
-  private static int colorIconSecondary = -1;
-  private static int colorPrimary = -1;
-  private static int colorPrimaryDark = -1;
-  private static int colorAccent = -1;
-  private static int textColorPrimary = -1;
-  private static int textColorSecondary = -1;
-  private static int textColorPrimaryInverse = -1;
-  private static int textColorHint = -1;
-  private static int colorBackground = -1;
-  private static int colorBackgroundFloating = -1;
-  private static int colorTextOnUnthemedDarkBackground = -1;
-  private static int colorIconOnUnthemedDarkBackground = -1;
-
-  public static void initializeTheme(Context context) {
-    // TODO(a bug): add share prefs check to configure this
-    theme = LIGHT;
+  public AospThemeImpl(Context context) {
 
     context = context.getApplicationContext();
     context.setTheme(getApplicationThemeRes());
@@ -102,13 +90,15 @@
    * Returns the {@link Theme} that the application is using. Activities should check this value if
    * their custom style needs to customize further based on the application theme.
    */
-  public static @Theme int getTheme() {
-    Assert.checkArgument(theme != UNKNOWN);
-    return theme;
+  @Override
+  public @Type int getTheme() {
+    // TODO(a bug): add share prefs check to configure this
+    return LIGHT;
   }
 
-  public static @StyleRes int getApplicationThemeRes() {
-    switch (theme) {
+  @Override
+  public @StyleRes int getApplicationThemeRes() {
+    switch (getTheme()) {
       case DARK:
         return R.style.Dialer_Dark_ThemeBase_NoActionBar;
       case LIGHT:
@@ -119,50 +109,66 @@
     }
   }
 
-  public static Context getThemedContext(Context context) {
+  @Override
+  public Context getThemedContext(Context context) {
     return new ContextThemeWrapper(context, getApplicationThemeRes());
   }
 
-  public static LayoutInflater getThemedLayoutInflator(LayoutInflater inflater) {
+  @Override
+  public LayoutInflater getThemedLayoutInflator(LayoutInflater inflater) {
     return inflater.cloneInContext(getThemedContext(inflater.getContext()));
   }
 
-  public static @ColorInt int getColorIcon() {
+  @Override
+  public @ColorInt int getColorIcon() {
     Assert.checkArgument(colorIcon != -1);
     return colorIcon;
   }
 
-  public static @ColorInt int getColorIconSecondary() {
+  @Override
+  public @ColorInt int getColorIconSecondary() {
     Assert.checkArgument(colorIconSecondary != -1);
     return colorIconSecondary;
   }
 
-  public static @ColorInt int getColorPrimary() {
+  @Override
+  public @ColorInt int getColorPrimary() {
     Assert.checkArgument(colorPrimary != -1);
     return colorPrimary;
   }
 
-  public static @ColorInt int getColorAccent() {
+  @Override
+  public int getColorPrimaryDark() {
+    Assert.checkArgument(colorPrimary != -1);
+    return 0;
+  }
+
+  @Override
+  public @ColorInt int getColorAccent() {
     Assert.checkArgument(colorAccent != -1);
     return colorAccent;
   }
 
-  public static @ColorInt int getTextColorSecondary() {
+  @Override
+  public @ColorInt int getTextColorSecondary() {
     Assert.checkArgument(textColorSecondary != -1);
     return textColorSecondary;
   }
 
-  public static @ColorInt int getTextColorPrimary() {
+  @Override
+  public @ColorInt int getTextColorPrimary() {
     Assert.checkArgument(textColorPrimary != -1);
     return textColorPrimary;
   }
 
-  public static @ColorInt int getColorTextOnUnthemedDarkBackground() {
+  @Override
+  public @ColorInt int getColorTextOnUnthemedDarkBackground() {
     Assert.checkArgument(colorTextOnUnthemedDarkBackground != -1);
     return colorTextOnUnthemedDarkBackground;
   }
 
-  public static @ColorInt int getColorIconOnUnthemedDarkBackground() {
+  @Override
+  public @ColorInt int getColorIconOnUnthemedDarkBackground() {
     Assert.checkArgument(colorIconOnUnthemedDarkBackground != -1);
     return colorIconOnUnthemedDarkBackground;
   }
diff --git a/java/com/android/dialer/theme/base/impl/AospThemeModule.java b/java/com/android/dialer/theme/base/impl/AospThemeModule.java
new file mode 100644
index 0000000..7cf52ca
--- /dev/null
+++ b/java/com/android/dialer/theme/base/impl/AospThemeModule.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.theme.base.impl;
+
+import android.content.Context;
+import com.android.dialer.inject.ApplicationContext;
+import com.android.dialer.inject.DialerVariant;
+import com.android.dialer.inject.InstallIn;
+import com.android.dialer.theme.base.Theme;
+import dagger.Module;
+import dagger.Provides;
+
+/** Module which binds {@link AospThemeImpl}. */
+@InstallIn(variants = {DialerVariant.DIALER_TEST})
+@Module
+public class AospThemeModule {
+
+  @Provides
+  static Theme provideThemeModule(@ApplicationContext Context context) {
+    return new AospThemeImpl(context);
+  }
+}
diff --git a/java/com/android/dialer/theme/common/res/values/text_styles.xml b/java/com/android/dialer/theme/common/res/values/text_styles.xml
index 9cf4a76..def5862 100644
--- a/java/com/android/dialer/theme/common/res/values/text_styles.xml
+++ b/java/com/android/dialer/theme/common/res/values/text_styles.xml
@@ -31,6 +31,12 @@
     <item name="android:fontFamily">sans-serif-medium</item>
   </style>
 
+  <style name="Dialer.TextAppearance.SubHeader" parent="TextAppearance.AppCompat">
+    <item name="android:textColor">?android:attr/textColorPrimary</item>
+    <item name="android:textSize">16sp</item>
+    <item name="android:fontFamily">sans-serif-medium</item>
+  </style>
+
   <style name="Dialer.TextAppearance.Primary" parent="TextAppearance.AppCompat">
     <item name="android:textColor">?android:attr/textColorPrimary</item>
     <item name="android:textSize">16sp</item>
@@ -55,32 +61,37 @@
     <item name="android:fontFamily">sans-serif-medium</item>
   </style>
 
-  <style name="Dialer.TextAppearance.Header1.Ellipsize" parent="Dialer.TextAppearance.Header1">
+  <style name="Dialer.TextAppearance.Header1.Ellipsize">
     <item name="android:ellipsize">end</item>
     <item name="android:maxLines">1</item>
   </style>
 
-  <style name="Dialer.TextAppearance.Header2.Ellipsize" parent="Dialer.TextAppearance.Header2">
+  <style name="Dialer.TextAppearance.Header2.Ellipsize">
     <item name="android:ellipsize">end</item>
     <item name="android:maxLines">1</item>
   </style>
 
-  <style name="Dialer.TextAppearance.Primary.Ellipsize" parent="Dialer.TextAppearance.Primary">
+  <style name="Dialer.TextAppearance.SubHeader.Ellipsize">
     <item name="android:ellipsize">end</item>
     <item name="android:maxLines">1</item>
   </style>
 
-  <style name="Dialer.TextAppearance.Secondary.Ellipsize" parent="Dialer.TextAppearance.Secondary">
+  <style name="Dialer.TextAppearance.Primary.Ellipsize">
     <item name="android:ellipsize">end</item>
     <item name="android:maxLines">1</item>
   </style>
 
-  <style name="Dialer.TextAppearance.Secondary2.Ellipsize" parent="Dialer.TextAppearance.Secondary">
+  <style name="Dialer.TextAppearance.Secondary.Ellipsize">
     <item name="android:ellipsize">end</item>
     <item name="android:maxLines">1</item>
   </style>
 
-  <style name="Dialer.TextAppearance.OVERLINE.Ellipsize" parent="Dialer.TextAppearance.OVERLINE">
+  <style name="Dialer.TextAppearance.Secondary2.Ellipsize">
+    <item name="android:ellipsize">end</item>
+    <item name="android:maxLines">1</item>
+  </style>
+
+  <style name="Dialer.TextAppearance.OVERLINE.Ellipsize">
     <item name="android:ellipsize">end</item>
     <item name="android:maxLines">1</item>
   </style>
diff --git a/java/com/android/dialer/theme/res/values/theme_dialer_light.xml b/java/com/android/dialer/theme/res/values/theme_dialer_light.xml
deleted file mode 100644
index ab4ae93..0000000
--- a/java/com/android/dialer/theme/res/values/theme_dialer_light.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-
-  <style name="Dialer"/>
-
-  <!-- Should be kept in sync with the theme below (minus anything related to actionbars) -->
-  <style name="Dialer.ThemeBase" parent="@style/Theme.AppCompat.Light.DarkActionBar">
-    <item name="android:textAppearanceButton">@style/DialerButtonTextStyle</item>
-
-    <!-- These values should be used to color all backgrounds. -->
-    <item name="android:colorBackground">@color/dialer_background_light</item>
-    <item name="android:colorBackgroundFloating">@color/dialer_background_floating_light</item>
-
-    <!-- These values should be used to set text color. -->
-    <item name="android:textColorPrimary">@color/dialer_primary_text_color</item>
-    <item name="android:textColorSecondary">@color/dialer_secondary_text_color</item>
-    <item name="android:textColorPrimaryInverse">@color/dialer_primary_text_color_inverse</item>
-    <item name="android:textColorSecondaryInverse">@color/dialer_secondary_text_color_inverse</item>
-    <item name="android:textColorHint">@color/dialer_text_hint_color</item>
-
-    <!-- These will be automatically used to color most Appcompat/Material widgets. -->
-    <item name="android:colorPrimary">@color/dialer_theme_color</item>
-    <item name="colorPrimary">@color/dialer_theme_color</item>
-    <item name="android:colorPrimaryDark">@color/dialer_theme_color</item>
-    <item name="colorPrimaryDark">@color/dialer_theme_color</item>
-    <item name="android:colorAccent">@color/dialer_secondary_color</item>
-    <item name="colorAccent">@color/dialer_secondary_color</item>
-
-    <!-- Used to automatically style check/selected checkbox, switches and radio buttons -->
-    <item name="colorControlActivated">?android:attr/colorPrimary</item>
-
-    <!-- Used to automatically style AlertDialogs -->
-    <item name="alertDialogTheme">@style/AlertDialogTheme</item>
-
-    <!-- Dialer specific attributes. -->
-    <item name="colorIcon">@color/dialer_secondary_text_color</item>
-
-    <!-- These are used to style the actionbar. -->
-    <item name="actionBarStyle">@style/DialerActionBarBaseStyle</item>
-    <item name="actionBarSize">@dimen/action_bar_height</item>
-
-    <!-- Theme for the dialpad. -->
-    <item name="dialpad_style">@style/Dialpad.Light</item>
-  </style>
-
-  <!-- Should be kept in sync with the theme above (minus anything related to actionbars) -->
-  <style name="Dialer.ThemeBase.NoActionBar" parent="@style/Theme.AppCompat.Light.NoActionBar">
-    <!-- These values should be used to color all backgrounds. -->
-    <item name="android:colorBackground">@color/dialer_background_light</item>
-    <item name="android:colorBackgroundFloating">@color/dialer_background_floating_light</item>
-
-    <!-- These values should be used to set text color. -->
-    <item name="android:textColorPrimary">@color/dialer_primary_text_color</item>
-    <item name="android:textColorSecondary">@color/dialer_secondary_text_color</item>
-    <item name="android:textColorPrimaryInverse">@color/dialer_primary_text_color_inverse</item>
-    <item name="android:textColorSecondaryInverse">@color/dialer_secondary_text_color_inverse</item>
-    <item name="android:textColorHint">@color/dialer_text_hint_color</item>
-    <item name="android:textColorLink">@color/dialer_theme_color</item>
-
-    <!-- These will be automatically used to color most Appcompat/Material widgets. -->
-    <item name="android:colorPrimary">@color/dialer_theme_color</item>
-    <item name="colorPrimary">@color/dialer_theme_color</item>
-    <item name="android:colorPrimaryDark">@color/dialer_theme_color_dark</item>
-    <item name="colorPrimaryDark">@color/dialer_theme_color_dark</item>
-    <item name="android:colorAccent">@color/dialer_secondary_color</item>
-    <item name="colorAccent">@color/dialer_secondary_color</item>
-
-    <!-- Used for material buttons and widgets -->
-    <item name="android:colorButtonNormal">@color/dialer_theme_color</item>
-    <item name="android:textAppearanceButton">@style/DialerButtonTextStyle</item>
-
-    <!-- Used to automatically style check/selected checkbox, switches and radio buttons -->
-    <item name="colorControlActivated">?android:attr/colorPrimary</item>
-
-    <!-- Used to automatically style AlertDialogs -->
-    <item name="alertDialogTheme">@style/AlertDialogTheme</item>
-
-    <!-- Dialer specific attributes. -->
-    <item name="colorIcon">@color/dialer_secondary_text_color</item>
-
-    <!-- Theme for the dialpad. -->
-    <item name="dialpad_style">@style/Dialpad.Light</item>
-  </style>
-
-  <!-- TODO(a bug): flesh this out some more. -->
-  <style name="Dialer.ThemeBase.NoActionBar.Dark" parent="Dialer.ThemeBase.NoActionBar">
-    <!-- swap text colors. -->
-    <item name="android:textColorPrimary">@color/dialer_primary_text_color_inverse</item>
-    <item name="android:textColorSecondary">@color/dialer_secondary_text_color_inverse</item>
-    <item name="android:textColorPrimaryInverse">@color/dialer_primary_text_color</item>
-    <item name="android:textColorSecondaryInverse">@color/dialer_secondary_text_color</item>
-  </style>
-
-  <!-- TODO(a bug): investigate making this style's parent Dialer.ThemeBase.NoActionBar -->
-  <style name="Theme.AppCompat.Translucent" parent="Theme.AppCompat.NoActionBar">
-    <item name="android:windowNoTitle">true</item>
-    <item name="android:windowBackground">@android:color/transparent</item>
-    <item name="android:colorBackgroundCacheHint">@null</item>
-    <item name="android:windowIsTranslucent">true</item>
-    <item name="android:windowAnimationStyle">@android:style/Animation</item>
-  </style>
-</resources>
diff --git a/java/com/android/dialer/widget/DialerToolbar.java b/java/com/android/dialer/widget/DialerToolbar.java
index fe0e861..02ec8c0 100644
--- a/java/com/android/dialer/widget/DialerToolbar.java
+++ b/java/com/android/dialer/widget/DialerToolbar.java
@@ -23,6 +23,7 @@
 import android.support.v7.widget.Toolbar;
 import android.util.AttributeSet;
 import android.widget.TextView;
+import com.android.dialer.theme.base.ThemeComponent;
 
 /** Toolbar widget for Dialer. */
 public class DialerToolbar extends Toolbar {
@@ -37,7 +38,7 @@
     subtitle = (TextView) findViewById(R.id.subtitle);
 
     setElevation(getResources().getDimensionPixelSize(R.dimen.toolbar_elevation));
-    setBackgroundColor(getResources().getColor(R.color.dialer_theme_color));
+    setBackgroundColor(ThemeComponent.get(context).theme().getColorPrimary());
     setNavigationIcon(R.drawable.quantum_ic_close_white_24);
     setNavigationContentDescription(R.string.toolbar_close);
     setNavigationOnClickListener(v -> ((Activity) context).finish());
diff --git a/java/com/android/dialer/widget/EmptyContentView.java b/java/com/android/dialer/widget/EmptyContentView.java
index 6d598ff..c0f9c9c 100644
--- a/java/com/android/dialer/widget/EmptyContentView.java
+++ b/java/com/android/dialer/widget/EmptyContentView.java
@@ -25,7 +25,7 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-import com.android.dialer.theme.base.ThemeUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 
 public class EmptyContentView extends LinearLayout implements View.OnClickListener {
 
@@ -67,7 +67,8 @@
     actionView = (TextView) findViewById(R.id.empty_list_view_action);
     actionView.setOnClickListener(this);
 
-    imageView.setImageTintList(ColorStateList.valueOf(ThemeUtil.getColorIconSecondary()));
+    imageView.setImageTintList(
+        ColorStateList.valueOf(ThemeComponent.get(context).theme().getColorIconSecondary()));
   }
 
   public void setDescription(int resourceId) {
diff --git a/java/com/android/incallui/ExternalCallNotifier.java b/java/com/android/incallui/ExternalCallNotifier.java
index 8c882d2..10c4a64 100644
--- a/java/com/android/incallui/ExternalCallNotifier.java
+++ b/java/com/android/incallui/ExternalCallNotifier.java
@@ -45,6 +45,7 @@
 import com.android.dialer.notification.DialerNotificationManager;
 import com.android.dialer.notification.NotificationChannelId;
 import com.android.dialer.telecom.TelecomCallUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.incallui.call.DialerCall;
 import com.android.incallui.call.DialerCallDelegate;
 import com.android.incallui.call.ExternalCallList;
@@ -239,7 +240,7 @@
     builder.setSmallIcon(R.drawable.quantum_ic_call_white_24);
     builder.setContentTitle(info.getContentTitle());
     builder.setLargeIcon(info.getLargeIcon());
-    builder.setColor(context.getResources().getColor(R.color.dialer_theme_color));
+    builder.setColor(ThemeComponent.get(context).theme().getColorPrimary());
     builder.addPerson(info.getPersonReference());
     if (BuildCompat.isAtLeastO()) {
       builder.setChannelId(NotificationChannelId.DEFAULT);
@@ -275,7 +276,7 @@
      */
     Notification.Builder publicBuilder = new Notification.Builder(context);
     publicBuilder.setSmallIcon(R.drawable.quantum_ic_call_white_24);
-    publicBuilder.setColor(context.getResources().getColor(R.color.dialer_theme_color));
+    publicBuilder.setColor(ThemeComponent.get(context).theme().getColorPrimary());
     if (BuildCompat.isAtLeastO()) {
       publicBuilder.setChannelId(NotificationChannelId.DEFAULT);
     }
diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java
index da5d20f..5aabf06 100644
--- a/java/com/android/incallui/InCallPresenter.java
+++ b/java/com/android/incallui/InCallPresenter.java
@@ -365,8 +365,7 @@
     addListener(this.proximitySensor);
 
     if (themeColorManager == null) {
-      themeColorManager =
-          new ThemeColorManager(new InCallUIMaterialColorMapUtils(this.context.getResources()));
+      themeColorManager = new ThemeColorManager(new InCallUIMaterialColorMapUtils(this.context));
     }
 
     this.callList = callList;
diff --git a/java/com/android/incallui/InCallUIMaterialColorMapUtils.java b/java/com/android/incallui/InCallUIMaterialColorMapUtils.java
index 945e9fb..c566f79 100644
--- a/java/com/android/incallui/InCallUIMaterialColorMapUtils.java
+++ b/java/com/android/incallui/InCallUIMaterialColorMapUtils.java
@@ -16,31 +16,35 @@
 
 package com.android.incallui;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.telecom.PhoneAccount;
 import com.android.contacts.common.util.MaterialColorMapUtils;
+import com.android.dialer.theme.base.ThemeComponent;
 
 public class InCallUIMaterialColorMapUtils extends MaterialColorMapUtils {
 
   private final TypedArray primaryColors;
   private final TypedArray secondaryColors;
   private final Resources resources;
+  private final Context context;
 
-  public InCallUIMaterialColorMapUtils(Resources resources) {
-    super(resources);
+  public InCallUIMaterialColorMapUtils(Context context) {
+    super(context.getResources());
+    this.resources = context.getResources();
+    this.context = context;
     primaryColors = resources.obtainTypedArray(R.array.background_colors);
     secondaryColors = resources.obtainTypedArray(R.array.background_colors_dark);
-    this.resources = resources;
   }
 
   /**
    * {@link Resources#getColor(int) used for compatibility
    */
   @SuppressWarnings("deprecation")
-  public static MaterialPalette getDefaultPrimaryAndSecondaryColors(Resources resources) {
-    final int primaryColor = resources.getColor(R.color.dialer_theme_color);
-    final int secondaryColor = resources.getColor(R.color.dialer_theme_color_dark);
+  public static MaterialPalette getDefaultPrimaryAndSecondaryColors(Context context) {
+    final int primaryColor = ThemeComponent.get(context).theme().getColorPrimary();
+    final int secondaryColor = ThemeComponent.get(context).theme().getColorPrimaryDark();
     return new MaterialPalette(primaryColor, secondaryColor);
   }
 
@@ -52,7 +56,7 @@
   @Override
   public MaterialPalette calculatePrimaryAndSecondaryColor(int color) {
     if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) {
-      return getDefaultPrimaryAndSecondaryColors(resources);
+      return getDefaultPrimaryAndSecondaryColors(context);
     }
 
     for (int i = 0; i < primaryColors.length(); i++) {
diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java
index 7c4585c..09e1845 100644
--- a/java/com/android/incallui/ReturnToCallController.java
+++ b/java/com/android/incallui/ReturnToCallController.java
@@ -35,6 +35,7 @@
 import com.android.dialer.configprovider.ConfigProviderBindings;
 import com.android.dialer.lettertile.LetterTileDrawable;
 import com.android.dialer.telecom.TelecomUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.incallui.ContactInfoCache.ContactCacheEntry;
 import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
 import com.android.incallui.InCallPresenter.InCallState;
@@ -288,7 +289,7 @@
 
   private BubbleInfo generateBubbleInfo() {
     return BubbleInfo.builder()
-        .setPrimaryColor(context.getResources().getColor(R.color.dialer_theme_color, null))
+        .setPrimaryColor(ThemeComponent.get(context).theme().getColorPrimary())
         .setPrimaryIcon(Icon.createWithResource(context, R.drawable.on_going_call))
         .setStartingYPosition(
             InCallPresenter.getInstance().shouldStartInBubbleMode()
@@ -302,7 +303,7 @@
 
   private BubbleInfo generateBubbleInfoForBackgroundCalling() {
     return BubbleInfo.builder()
-        .setPrimaryColor(context.getResources().getColor(R.color.dialer_theme_color, null))
+        .setPrimaryColor(ThemeComponent.get(context).theme().getColorPrimary())
         .setPrimaryIcon(Icon.createWithResource(context, R.drawable.on_going_call))
         .setStartingYPosition(context.getResources().getDisplayMetrics().heightPixels / 2)
         .setActions(generateActions())
diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java
index 32d2025..27d23c4 100644
--- a/java/com/android/incallui/StatusBarNotifier.java
+++ b/java/com/android/incallui/StatusBarNotifier.java
@@ -75,6 +75,7 @@
 import com.android.dialer.multimedia.MultimediaData;
 import com.android.dialer.notification.NotificationChannelId;
 import com.android.dialer.oem.MotorolaUtils;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.DrawableConverter;
 import com.android.incallui.ContactInfoCache.ContactCacheEntry;
 import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
@@ -333,7 +334,7 @@
     Notification.Builder publicBuilder = new Notification.Builder(context);
     publicBuilder
         .setSmallIcon(iconResId)
-        .setColor(context.getResources().getColor(R.color.dialer_theme_color, context.getTheme()))
+        .setColor(ThemeComponent.get(context).theme().getColorPrimary())
         // Hide work call state for the lock screen notification
         .setContentTitle(getContentString(call, ContactsUtils.USER_TYPE_CURRENT));
     setNotificationWhen(call, callState, publicBuilder);
diff --git a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java
index a561b5e..846834f 100644
--- a/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java
+++ b/java/com/android/incallui/audioroute/AudioRouteSelectorDialogFragment.java
@@ -39,6 +39,7 @@
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.logging.DialerImpression;
 import com.android.dialer.logging.Logger;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.incallui.call.CallList;
 import com.android.incallui.call.DialerCall;
 import com.android.incallui.call.TelecomAdapter;
@@ -154,7 +155,7 @@
       final int itemRoute,
       CallAudioState audioState,
       DialerImpression.Type impressionType) {
-    int selectedColor = getResources().getColor(R.color.dialer_theme_color);
+    int selectedColor = ThemeComponent.get(getContext()).theme().getColorPrimary();
     if ((audioState.getSupportedRouteMask() & itemRoute) == 0) {
       item.setVisibility(View.GONE);
     } else if (audioState.getRoute() == itemRoute) {
@@ -174,7 +175,7 @@
   }
 
   private TextView createBluetoothItem(BluetoothDevice bluetoothDevice, boolean selected) {
-    int selectedColor = getResources().getColor(R.color.dialer_theme_color);
+    int selectedColor = ThemeComponent.get(getContext()).theme().getColorPrimary();
     TextView textView =
         (TextView) getLayoutInflater().inflate(R.layout.audioroute_item, null, false);
     textView.setText(getAliasName(bluetoothDevice));
diff --git a/java/com/android/incallui/spam/SpamCallListListener.java b/java/com/android/incallui/spam/SpamCallListListener.java
index d030555..3b2f1c5 100644
--- a/java/com/android/incallui/spam/SpamCallListListener.java
+++ b/java/com/android/incallui/spam/SpamCallListListener.java
@@ -49,6 +49,7 @@
 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
 import com.android.dialer.spam.SpamComponent;
 import com.android.dialer.telecom.TelecomUtil;
+import com.android.dialer.theme.base.ThemeComponent;
 import com.android.dialer.util.PermissionsUtil;
 import com.android.incallui.call.CallList;
 import com.android.incallui.call.DialerCall;
@@ -256,7 +257,7 @@
                 createActivityPendingIntent(call, SpamNotificationActivity.ACTION_SHOW_DIALOG))
             .setCategory(Notification.CATEGORY_STATUS)
             .setPriority(Notification.PRIORITY_DEFAULT)
-            .setColor(context.getColor(R.color.dialer_theme_color))
+            .setColor(ThemeComponent.get(context).theme().getColorPrimary())
             .setSmallIcon(R.drawable.quantum_ic_call_end_vd_theme_24)
             .setGroup(GROUP_KEY);
     if (BuildCompat.isAtLeastO()) {
diff --git a/packages.mk b/packages.mk
index 37090cc..3767e3c 100644
--- a/packages.mk
+++ b/packages.mk
@@ -69,6 +69,7 @@
 	com.android.dialer.spannable \
 	com.android.dialer.theme \
 	com.android.dialer.theme.base \
+	com.android.dialer.theme.base.impl \
 	com.android.dialer.theme.common \
 	com.android.dialer.theme.private \
 	com.android.dialer.util \