Merge changes I46e819a0,I4ee4ff98,Ifae9c912,Idc58efce,I60b0122f

* changes:
  Add skeleton for SpamPhoneLookup
  Show Icon and label for blocked numbers
  Bubble v2 a11y.
  Add flag to enable NUI shortcut.
  Rename "ApdlInfo" as "SpamInfo" in proto PhoneLookupInfo.
diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java
index c9d5f09..440055d 100644
--- a/java/com/android/dialer/calllog/CallLogFramework.java
+++ b/java/com/android/dialer/calllog/CallLogFramework.java
@@ -21,11 +21,11 @@
 import android.support.annotation.MainThread;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
-import com.android.dialer.buildtype.BuildType;
 import com.android.dialer.calllog.datasources.CallLogDataSource;
 import com.android.dialer.calllog.datasources.DataSources;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
+import com.android.dialer.configprovider.ConfigProviderBindings;
 import com.android.dialer.storage.Unencrypted;
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -61,7 +61,7 @@
     // users will have "new call log" content observers firing. These observers usually do simple
     // things like writing shared preferences.
     // TODO(zachh): Find a way to access Main#isNewUiEnabled without creating a circular dependency.
-    if (BuildType.get() == BuildType.BUGFOOD || LogUtil.isDebugEnabled()) {
+    if (ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false)) {
       for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) {
         dataSource.registerContentObservers(appContext, this);
       }
diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java
index 2427624..77de62e 100644
--- a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java
+++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java
@@ -75,7 +75,6 @@
   }
 
   private AnnotatedCallLogDatabaseHelper databaseHelper;
-  private Coalescer coalescer;
 
   private final ThreadLocal<Boolean> applyingBatch = new ThreadLocal<>();
 
@@ -87,7 +86,12 @@
   @Override
   public boolean onCreate() {
     databaseHelper = new AnnotatedCallLogDatabaseHelper(getContext(), MAX_ROWS);
-    coalescer = CallLogDatabaseComponent.get(getContext()).coalescer();
+
+    // Note: As this method is called before Application#onCreate, we must *not* initialize objects
+    // that require preparation work done in Application#onCreate.
+    // One example is to avoid obtaining an instance that depends on Google's proprietary config,
+    // which is initialized in Application#onCreate.
+
     return true;
   }
 
@@ -158,7 +162,10 @@
                 null,
                 null,
                 AnnotatedCallLog.TIMESTAMP + " DESC")) {
-          Cursor coalescedRows = coalescer.coalesce(allAnnotatedCallLogRows);
+          Cursor coalescedRows =
+              CallLogDatabaseComponent.get(getContext())
+                  .coalescer()
+                  .coalesce(allAnnotatedCallLogRows);
           coalescedRows.setNotificationUri(
               getContext().getContentResolver(), CoalescedAnnotatedCallLog.CONTENT_URI);
           return coalescedRows;
diff --git a/java/com/android/dialer/calllog/database/contract/number_attributes.proto b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
index 64f8f18..b1a7566 100644
--- a/java/com/android/dialer/calllog/database/contract/number_attributes.proto
+++ b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
@@ -58,4 +58,7 @@
   // True if the CP2 information is incomplete and needs to be queried at
   // display time.
   optional bool is_cp2_info_incomplete = 9;
+
+  // The number is blocked.
+  optional bool is_blocked = 10;
 }
\ No newline at end of file
diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
index a0874f0..565a2a3 100644
--- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
+++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
@@ -37,7 +37,6 @@
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
 import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
-import com.android.dialer.inject.ApplicationContext;
 import com.android.dialer.phonelookup.PhoneLookup;
 import com.android.dialer.phonelookup.PhoneLookupInfo;
 import com.android.dialer.phonelookup.consolidator.PhoneLookupInfoConsolidator;
@@ -68,7 +67,6 @@
 public final class PhoneLookupDataSource
     implements CallLogDataSource, PhoneLookup.ContentObserverCallbacks {
 
-  private final Context appContext;
   private final PhoneLookup<PhoneLookupInfo> phoneLookup;
   private final ListeningExecutorService backgroundExecutorService;
   private final ListeningExecutorService lightweightExecutorService;
@@ -95,11 +93,9 @@
   @Inject
   PhoneLookupDataSource(
       PhoneLookup<PhoneLookupInfo> phoneLookup,
-      @ApplicationContext Context appContext,
       @BackgroundExecutor ListeningExecutorService backgroundExecutorService,
       @LightweightExecutor ListeningExecutorService lightweightExecutorService) {
     this.phoneLookup = phoneLookup;
-    this.appContext = appContext;
     this.backgroundExecutorService = backgroundExecutorService;
     this.lightweightExecutorService = lightweightExecutorService;
   }
@@ -584,7 +580,7 @@
 
   private void updateContentValues(ContentValues contentValues, PhoneLookupInfo phoneLookupInfo) {
     PhoneLookupInfoConsolidator phoneLookupInfoConsolidator =
-        new PhoneLookupInfoConsolidator(appContext, phoneLookupInfo);
+        new PhoneLookupInfoConsolidator(phoneLookupInfo);
     contentValues.put(
         AnnotatedCallLog.NUMBER_ATTRIBUTES,
         NumberAttributes.newBuilder()
@@ -595,6 +591,7 @@
             .setNumberTypeLabel(phoneLookupInfoConsolidator.getNumberLabel())
             .setIsBusiness(phoneLookupInfoConsolidator.isBusiness())
             .setIsVoicemail(phoneLookupInfoConsolidator.isVoicemail())
+            .setIsBlocked(phoneLookupInfoConsolidator.isBlocked())
             .setCanReportAsInvalidNumber(phoneLookupInfoConsolidator.canReportAsInvalidNumber())
             .setIsCp2InfoIncomplete(phoneLookupInfoConsolidator.isCp2LocalInfoIncomplete())
             .build()
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
index 67fb4f0..ab94299 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
@@ -36,6 +36,7 @@
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.compat.telephony.TelephonyManagerCompat;
 import com.android.dialer.contactphoto.ContactPhotoManager;
+import com.android.dialer.contactphoto.NumberAttributeConverter;
 import com.android.dialer.oem.MotorolaUtils;
 import com.android.dialer.time.Clock;
 import com.google.common.util.concurrent.FutureCallback;
@@ -138,7 +139,7 @@
             quickContactBadge,
             parseUri(row.numberAttributes().getLookupUri()),
             row.numberAttributes().getPhotoId(),
-            parseUri(row.numberAttributes().getPhotoUri()),
+            NumberAttributeConverter.getPhotoUri(context, row.numberAttributes()),
             CallLogEntryText.buildPrimaryText(context, row).toString(),
             CallLogContactTypes.getContactType(row));
   }
diff --git a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
index 86cc24c..501dce4 100644
--- a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
+++ b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
@@ -202,7 +202,7 @@
   private CoalescedRow applyPhoneLookupInfoToRow(
       PhoneLookupInfo phoneLookupInfo, CoalescedRow row) {
     PhoneLookupInfoConsolidator phoneLookupInfoConsolidator =
-        new PhoneLookupInfoConsolidator(appContext, phoneLookupInfo);
+        new PhoneLookupInfoConsolidator(phoneLookupInfo);
     return row.toBuilder()
         .setNumberAttributes(
             // TODO(zachh): Put this in a common location.
@@ -214,6 +214,7 @@
                 .setNumberTypeLabel(phoneLookupInfoConsolidator.getNumberLabel())
                 .setIsBusiness(phoneLookupInfoConsolidator.isBusiness())
                 .setIsVoicemail(phoneLookupInfoConsolidator.isVoicemail())
+                .setIsBlocked(phoneLookupInfoConsolidator.isBlocked())
                 .setCanReportAsInvalidNumber(phoneLookupInfoConsolidator.canReportAsInvalidNumber())
                 .build())
         .build();
diff --git a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
index c7126e9..2a43a3c 100644
--- a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
@@ -24,6 +24,7 @@
 import com.android.dialer.calllogutils.CallLogIntents;
 import com.android.dialer.contactactions.ContactPrimaryActionInfo;
 import com.android.dialer.contactactions.ContactPrimaryActionInfo.PhotoInfo;
+import com.android.dialer.contactphoto.NumberAttributeConverter;
 
 /** Configures the primary action row (top row) for the bottom sheet. */
 final class PrimaryAction {
@@ -35,7 +36,7 @@
         .setPhotoInfo(
             PhotoInfo.builder()
                 .setPhotoId(row.numberAttributes().getPhotoId())
-                .setPhotoUri(row.numberAttributes().getPhotoUri())
+                .setPhotoUri(NumberAttributeConverter.getPhotoUri(context, row.numberAttributes()))
                 .setLookupUri(row.numberAttributes().getLookupUri())
                 .setIsVideo((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO)
                 .setContactType(CallLogContactTypes.getContactType(row))
diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java
index a7a6bba..aa45a69 100644
--- a/java/com/android/dialer/calllogutils/CallLogEntryText.java
+++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java
@@ -21,6 +21,9 @@
 import android.text.TextUtils;
 import com.android.dialer.calllog.model.CoalescedRow;
 import com.android.dialer.time.Clock;
+import com.google.common.collect.Collections2;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Computes the primary text and secondary text for call log entries.
@@ -52,7 +55,7 @@
   /**
    * The secondary text to show in the main call log entry list.
    *
-   * <p>Rules: (Duo video, )?$Label|$Location • Date
+   * <p>Rules: (Blocked • )?(Duo video, )?$Label|$Location • Date
    *
    * <p>Examples:
    *
@@ -68,14 +71,16 @@
    */
   public static CharSequence buildSecondaryTextForEntries(
       Context context, Clock clock, CoalescedRow row) {
-    StringBuilder secondaryText = secondaryTextPrefix(context, row);
-
-    if (secondaryText.length() > 0) {
-      secondaryText.append(" • ");
+    List<CharSequence> components = new ArrayList<>();
+    if (row.numberAttributes().getIsBlocked()) {
+      components.add(context.getText(R.string.new_call_log_secondary_blocked));
     }
-    secondaryText.append(
+
+    components.add(getNumberTypeLabel(context, row));
+
+    components.add(
         CallLogDates.newCallLogTimestampLabel(context, clock.currentTimeMillis(), row.timestamp()));
-    return secondaryText.toString();
+    return joinSecondaryTextComponents(components);
   }
 
   /**
@@ -85,9 +90,9 @@
    * CoalescedRow)} except that instead of suffixing with the time of the call, we suffix with the
    * formatted number.
    */
-  public static String buildSecondaryTextForBottomSheet(Context context, CoalescedRow row) {
+  public static CharSequence buildSecondaryTextForBottomSheet(Context context, CoalescedRow row) {
     /*
-     * Rules: (Duo video, )?$Label|$Location [• NumberIfNoName]?
+     * Rules: (Blocked • )(Duo video, )?$Label|$Location [• NumberIfNoName]?
      *
      * The number is shown at the end if there is no name for the entry. (It is shown in primary
      * text otherwise.)
@@ -96,25 +101,27 @@
      *   Duo Video, Mobile • 555-1234
      *   Duo Video • 555-1234
      *   Mobile • 555-1234
+     *   Blocked • Mobile • 555-1234
      *   Mobile • 555-1234
      *   Brooklyn, NJ
      */
-    StringBuilder secondaryText = secondaryTextPrefix(context, row);
+    List<CharSequence> components = new ArrayList<>();
+    if (row.numberAttributes().getIsBlocked()) {
+      components.add(context.getText(R.string.new_call_log_secondary_blocked));
+    }
+
+    components.add(getNumberTypeLabel(context, row));
 
     if (TextUtils.isEmpty(row.numberAttributes().getName())) {
       // If the name is empty the number is shown as the primary text and there's nothing to add.
-      return secondaryText.toString();
+      return joinSecondaryTextComponents(components);
     }
     if (TextUtils.isEmpty(row.formattedNumber())) {
       // If there's no number, don't append anything.
-      return secondaryText.toString();
+      return joinSecondaryTextComponents(components);
     }
-    // Otherwise append the number.
-    if (secondaryText.length() > 0) {
-      secondaryText.append(" • ");
-    }
-    secondaryText.append(row.formattedNumber());
-    return secondaryText.toString();
+    components.add(row.formattedNumber());
+    return joinSecondaryTextComponents(components);
   }
 
   /**
@@ -125,7 +132,7 @@
    * time of the call, and when it is shown in a bottom sheet, it is suffixed with the formatted
    * number.
    */
-  private static StringBuilder secondaryTextPrefix(Context context, CoalescedRow row) {
+  private static CharSequence getNumberTypeLabel(Context context, CoalescedRow row) {
     StringBuilder secondaryText = new StringBuilder();
     if ((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) {
       // TODO(zachh): Add "Duo" prefix?
@@ -148,4 +155,9 @@
     }
     return secondaryText;
   }
+
+  private static CharSequence joinSecondaryTextComponents(List<CharSequence> components) {
+    return TextUtils.join(
+        " • ", Collections2.filter(components, (text) -> !TextUtils.isEmpty(text)));
+  }
 }
diff --git a/java/com/android/dialer/calllogutils/res/values/strings.xml b/java/com/android/dialer/calllogutils/res/values/strings.xml
index 8784bf8..4622e50 100644
--- a/java/com/android/dialer/calllogutils/res/values/strings.xml
+++ b/java/com/android/dialer/calllogutils/res/values/strings.xml
@@ -136,4 +136,7 @@
 
   <!-- String used to display calls from unknown numbers in the call log.  [CHAR LIMIT=30] -->
   <string name="new_call_log_unknown">Unknown</string>
+
+  <!-- String used to display calls from blocked numbers in the call log.   [CHAR LIMIT=30] -->
+  <string name="new_call_log_secondary_blocked">Blocked</string>
 </resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/contactactions/ContactActionBottomSheet.java b/java/com/android/dialer/contactactions/ContactActionBottomSheet.java
index 7e216aa..27e3187 100644
--- a/java/com/android/dialer/contactactions/ContactActionBottomSheet.java
+++ b/java/com/android/dialer/contactactions/ContactActionBottomSheet.java
@@ -91,7 +91,7 @@
             contactView.findViewById(R.id.quick_contact_photo),
             !TextUtils.isEmpty(photoInfo.lookupUri()) ? Uri.parse(photoInfo.lookupUri()) : null,
             photoInfo.photoId(),
-            !TextUtils.isEmpty(photoInfo.photoUri()) ? Uri.parse(photoInfo.photoUri()) : null,
+            photoInfo.photoUri(),
             photoInfo.displayName(),
             photoInfo.contactType());
 
diff --git a/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java b/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java
index 2535f85..f19fd28 100644
--- a/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java
+++ b/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java
@@ -16,6 +16,7 @@
 package com.android.dialer.contactactions;
 
 import android.content.Intent;
+import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import com.android.dialer.DialerPhoneNumber;
@@ -40,7 +41,7 @@
     public abstract long photoId();
 
     @Nullable
-    public abstract String photoUri();
+    public abstract Uri photoUri();
 
     @Nullable
     public abstract String lookupUri();
@@ -60,7 +61,7 @@
     public abstract static class Builder {
       public abstract Builder setPhotoId(long photoId);
 
-      public abstract Builder setPhotoUri(@Nullable String photoUri);
+      public abstract Builder setPhotoUri(@Nullable Uri photoUri);
 
       public abstract Builder setLookupUri(@Nullable String lookupUri);
 
diff --git a/java/com/android/dialer/contactphoto/ContactPhotoManagerImpl.java b/java/com/android/dialer/contactphoto/ContactPhotoManagerImpl.java
index edeeb78..cf42606 100644
--- a/java/com/android/dialer/contactphoto/ContactPhotoManagerImpl.java
+++ b/java/com/android/dialer/contactphoto/ContactPhotoManagerImpl.java
@@ -414,20 +414,32 @@
       // No photo is needed
       defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme, defaultImageRequest);
       pendingRequests.remove(view);
-    } else {
-      if (DEBUG) {
-        LogUtil.d("ContactPhotoManagerImpl.loadPhoto", "loadPhoto request: " + photoUri);
-      }
-      if (isDefaultImageUri(photoUri)) {
-        createAndApplyDefaultImageForUri(
-            view, photoUri, requestedExtent, darkTheme, isCircular, defaultProvider);
-      } else {
-        loadPhotoByIdOrUri(
-            view,
-            Request.createFromUri(
-                photoUri, requestedExtent, darkTheme, isCircular, defaultProvider));
-      }
+      return;
     }
+    if (isDrawableUri(photoUri)) {
+      view.setImageURI(photoUri);
+      pendingRequests.remove(view);
+      return;
+    }
+    if (DEBUG) {
+      LogUtil.d("ContactPhotoManagerImpl.loadPhoto", "loadPhoto request: " + photoUri);
+    }
+
+    if (isDefaultImageUri(photoUri)) {
+      createAndApplyDefaultImageForUri(
+          view, photoUri, requestedExtent, darkTheme, isCircular, defaultProvider);
+    } else {
+      loadPhotoByIdOrUri(
+          view,
+          Request.createFromUri(photoUri, requestedExtent, darkTheme, isCircular, defaultProvider));
+    }
+  }
+
+  private static boolean isDrawableUri(Uri uri) {
+    if (!ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
+      return false;
+    }
+    return uri.getPathSegments().get(0).equals("drawable");
   }
 
   private void createAndApplyDefaultImageForUri(
diff --git a/java/com/android/dialer/contactphoto/NumberAttributeConverter.java b/java/com/android/dialer/contactphoto/NumberAttributeConverter.java
new file mode 100644
index 0000000..d7bf9bd
--- /dev/null
+++ b/java/com/android/dialer/contactphoto/NumberAttributeConverter.java
@@ -0,0 +1,66 @@
+/*
+ * 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.contactphoto;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import com.android.dialer.NumberAttributes;
+
+/**
+ * Convert photo information in {@link NumberAttributes} to an URI suitable for {@link
+ * ContactPhotoManager}.
+ *
+ * <p>This class is temporary. The new photo manager should take NumberAttributes directly.
+ */
+public final class NumberAttributeConverter {
+
+  /**
+   * Computes the photo URI from NumberAttributes.
+   *
+   * <p>The photo URI is shown in the quick contact badge in the main call log list or in the top
+   * item of the bottom sheet menu.
+   */
+  @Nullable
+  public static Uri getPhotoUri(Context context, NumberAttributes numberAttributes) {
+    if (numberAttributes.getIsBlocked()) {
+      return getResourceUri(context.getResources(), R.drawable.ic_block_grey_48dp);
+    } else {
+      return parseUri(numberAttributes.getPhotoUri());
+    }
+  }
+
+  @Nullable
+  private static Uri parseUri(@Nullable String uri) {
+    return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
+  }
+
+  private static Uri getResourceUri(Resources resources, @DrawableRes int drawable) {
+    return Uri.parse(
+        ContentResolver.SCHEME_ANDROID_RESOURCE
+            + "://"
+            + resources.getResourcePackageName(drawable)
+            + "/"
+            + resources.getResourceTypeName(drawable)
+            + "/"
+            + resources.getResourceEntryName(drawable));
+  }
+}
diff --git a/java/com/android/dialer/contactphoto/res/drawable-xxxhdpi/ic_block_black_48dp.png b/java/com/android/dialer/contactphoto/res/drawable-xxxhdpi/ic_block_black_48dp.png
new file mode 100644
index 0000000..1168bd8
--- /dev/null
+++ b/java/com/android/dialer/contactphoto/res/drawable-xxxhdpi/ic_block_black_48dp.png
Binary files differ
diff --git a/java/com/android/dialer/contactphoto/res/drawable/ic_block_grey_48dp.xml b/java/com/android/dialer/contactphoto/res/drawable/ic_block_grey_48dp.xml
new file mode 100644
index 0000000..42cfa99
--- /dev/null
+++ b/java/com/android/dialer/contactphoto/res/drawable/ic_block_grey_48dp.xml
@@ -0,0 +1,17 @@
+<!-- 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.
+-->
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_block_black_48dp"
+    android:tint="#757575" />
\ No newline at end of file
diff --git a/java/com/android/dialer/main/impl/MainImpl.java b/java/com/android/dialer/main/impl/MainImpl.java
index 675533c..e6d9a43 100644
--- a/java/com/android/dialer/main/impl/MainImpl.java
+++ b/java/com/android/dialer/main/impl/MainImpl.java
@@ -26,8 +26,7 @@
 import android.support.v4.content.pm.ShortcutInfoCompat;
 import android.support.v4.content.pm.ShortcutManagerCompat;
 import android.support.v4.graphics.drawable.IconCompat;
-import com.android.dialer.buildtype.BuildType;
-import com.android.dialer.common.LogUtil;
+import com.android.dialer.configprovider.ConfigProviderBindings;
 import com.android.dialer.main.Main;
 import javax.inject.Inject;
 
@@ -40,7 +39,7 @@
 
   @Override
   public boolean isNewUiEnabled(Context context) {
-    return BuildType.get() == BuildType.BUGFOOD || LogUtil.isDebugEnabled();
+    return ConfigProviderBindings.get(context).getBoolean("is_nui_shortcut_enabled", false);
   }
 
   @Override
diff --git a/java/com/android/dialer/phonelookup/PhoneLookupModule.java b/java/com/android/dialer/phonelookup/PhoneLookupModule.java
index 8a78ba0..d4cd60a 100644
--- a/java/com/android/dialer/phonelookup/PhoneLookupModule.java
+++ b/java/com/android/dialer/phonelookup/PhoneLookupModule.java
@@ -21,6 +21,7 @@
 import com.android.dialer.phonelookup.composite.CompositePhoneLookup;
 import com.android.dialer.phonelookup.cp2.Cp2LocalPhoneLookup;
 import com.android.dialer.phonelookup.cp2.Cp2RemotePhoneLookup;
+import com.android.dialer.phonelookup.spam.SpamPhoneLookup;
 import com.google.common.collect.ImmutableList;
 import dagger.Module;
 import dagger.Provides;
@@ -35,12 +36,14 @@
       Cp2LocalPhoneLookup cp2LocalPhoneLookup,
       Cp2RemotePhoneLookup cp2RemotePhoneLookup,
       DialerBlockedNumberPhoneLookup dialerBlockedNumberPhoneLookup,
-      SystemBlockedNumberPhoneLookup systemBlockedNumberPhoneLookup) {
+      SystemBlockedNumberPhoneLookup systemBlockedNumberPhoneLookup,
+      SpamPhoneLookup spamPhoneLookup) {
     return ImmutableList.of(
         cp2LocalPhoneLookup,
         cp2RemotePhoneLookup,
         dialerBlockedNumberPhoneLookup,
-        systemBlockedNumberPhoneLookup);
+        systemBlockedNumberPhoneLookup,
+        spamPhoneLookup);
   }
 
   @Provides
diff --git a/java/com/android/dialer/phonelookup/consolidator/AndroidManifest.xml b/java/com/android/dialer/phonelookup/consolidator/AndroidManifest.xml
deleted file mode 100644
index 98e07e5..0000000
--- a/java/com/android/dialer/phonelookup/consolidator/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--
- ~ 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
- -->
-<manifest
-    package="com.android.dialer.phonelookup.consolidator">
-</manifest>
diff --git a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
index 27f0d21..0373cfe 100644
--- a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
+++ b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
@@ -15,7 +15,6 @@
  */
 package com.android.dialer.phonelookup.consolidator;
 
-import android.content.Context;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
 import com.android.dialer.common.Assert;
@@ -68,15 +67,13 @@
   private static final ImmutableList<Integer> NAME_SOURCES_IN_PRIORITY_ORDER =
       ImmutableList.of(NameSource.CP2_LOCAL, NameSource.CP2_REMOTE, NameSource.PEOPLE_API);
 
-  private final Context appContext;
   private final @NameSource int nameSource;
   private final PhoneLookupInfo phoneLookupInfo;
 
   @Nullable private final Cp2ContactInfo firstCp2LocalContact;
   @Nullable private final Cp2ContactInfo firstCp2RemoteContact;
 
-  public PhoneLookupInfoConsolidator(Context appContext, PhoneLookupInfo phoneLookupInfo) {
-    this.appContext = appContext;
+  public PhoneLookupInfoConsolidator(PhoneLookupInfo phoneLookupInfo) {
     this.phoneLookupInfo = phoneLookupInfo;
 
     this.firstCp2LocalContact = getFirstLocalContact();
@@ -179,10 +176,6 @@
    * returned.
    */
   public String getNumberLabel() {
-    if (isBlocked()) {
-      return appContext.getString(R.string.blocked_number_new_call_log_label);
-    }
-
     switch (nameSource) {
       case NameSource.CP2_LOCAL:
         return Assert.isNotNull(firstCp2LocalContact).getLabel();
@@ -215,6 +208,10 @@
     return false;
   }
 
+  /**
+   * The {@link PhoneLookupInfo} passed to the constructor is associated with a number. This method
+   * returns whether the number is blocked.
+   */
   public boolean isBlocked() {
     // If system blocking reported blocked state it always takes priority over the dialer blocking.
     // It will be absent if dialer blocking should be used.
diff --git a/java/com/android/dialer/phonelookup/consolidator/res/values/strings.xml b/java/com/android/dialer/phonelookup/consolidator/res/values/strings.xml
deleted file mode 100644
index 2080b39..0000000
--- a/java/com/android/dialer/phonelookup/consolidator/res/values/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
-  ~ 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-  <!-- Label under the name of a blocked number in the call log. [CHAR LIMIT=15] -->
-  <string name="blocked_number_new_call_log_label">Blocked</string>
-
-</resources>
diff --git a/java/com/android/dialer/phonelookup/phone_lookup_info.proto b/java/com/android/dialer/phonelookup/phone_lookup_info.proto
index b5e73cc..57a61ac 100644
--- a/java/com/android/dialer/phonelookup/phone_lookup_info.proto
+++ b/java/com/android/dialer/phonelookup/phone_lookup_info.proto
@@ -81,11 +81,12 @@
   // Cp2RemotePhoneLookup is responsible for populating this field.
   optional Cp2Info cp2_remote_info = 6;
 
-  // Message for APDL, a lookup for the proprietary Google dialer.
-  message ApdlInfo {
+  // Message for spam info.
+  // SpamPhoneLookup is responsible for populating this message.
+  message SpamInfo {
     optional bool is_spam = 1;
   }
-  optional ApdlInfo apdl_info = 2;
+  optional SpamInfo spam_info = 2;
 
   // Message for PeopleApi, including G+ contacts and nearby places
   message PeopleApiInfo {
diff --git a/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java b/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java
new file mode 100644
index 0000000..0196ec5
--- /dev/null
+++ b/java/com/android/dialer/phonelookup/spam/SpamPhoneLookup.java
@@ -0,0 +1,81 @@
+/*
+ * 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.phonelookup.spam;
+
+import android.content.Context;
+import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.phonelookup.PhoneLookup;
+import com.android.dialer.phonelookup.PhoneLookupInfo;
+import com.android.dialer.phonelookup.PhoneLookupInfo.SpamInfo;
+import com.android.dialer.spam.Spam;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import javax.inject.Inject;
+
+/** PhoneLookup implementation for Spam info. */
+public final class SpamPhoneLookup implements PhoneLookup<SpamInfo> {
+
+  private final Spam spam;
+
+  @Inject
+  SpamPhoneLookup(Spam spam) {
+    this.spam = spam;
+  }
+
+  @Override
+  public ListenableFuture<SpamInfo> lookup(DialerPhoneNumber dialerPhoneNumber) {
+    // TODO(a bug): Use Spam to look up spam info.
+    return Futures.immediateFuture(SpamInfo.getDefaultInstance());
+  }
+
+  @Override
+  public ListenableFuture<Boolean> isDirty(ImmutableSet<DialerPhoneNumber> phoneNumbers) {
+    // TODO(a bug): Use Spam to check if its underlying data have been updated.
+    return Futures.immediateFuture(false);
+  }
+
+  @Override
+  public ListenableFuture<ImmutableMap<DialerPhoneNumber, SpamInfo>> getMostRecentInfo(
+      ImmutableMap<DialerPhoneNumber, SpamInfo> existingInfoMap) {
+    // TODO(a bug): Use Spam to retrieve the most recent spam info.
+    return Futures.immediateFuture(existingInfoMap);
+  }
+
+  @Override
+  public SpamInfo getSubMessage(PhoneLookupInfo phoneLookupInfo) {
+    return phoneLookupInfo.getSpamInfo();
+  }
+
+  @Override
+  public void setSubMessage(PhoneLookupInfo.Builder destination, SpamInfo subMessage) {
+    destination.setSpamInfo(subMessage);
+  }
+
+  @Override
+  public ListenableFuture<Void> onSuccessfulBulkUpdate() {
+    // TODO(a bug): Properly implement this method.
+    return Futures.immediateFuture(null);
+  }
+
+  @Override
+  public void registerContentObservers(
+      Context appContext, ContentObserverCallbacks contentObserverCallbacks) {
+    // No content observer needed for spam info
+  }
+}
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
index 46e2995..71c9803 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
@@ -44,6 +44,7 @@
 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.contactphoto.ContactPhotoManager;
+import com.android.dialer.contactphoto.NumberAttributeConverter;
 import com.android.dialer.lettertile.LetterTileDrawable;
 import com.android.dialer.time.Clock;
 import com.android.dialer.voicemail.listui.menu.NewVoicemailMenu;
@@ -201,14 +202,13 @@
     }
   }
 
-  // TODO(uabdullah): Consider/Implement TYPE (e.g Spam, TYPE_VOICEMAIL)
   private void setPhoto(VoicemailEntry voicemailEntry) {
     ContactPhotoManager.getInstance(context)
         .loadDialerThumbnailOrPhoto(
             quickContactBadge,
             parseUri(voicemailEntry.numberAttributes().getLookupUri()),
             voicemailEntry.numberAttributes().getPhotoId(),
-            parseUri(voicemailEntry.numberAttributes().getPhotoUri()),
+            NumberAttributeConverter.getPhotoUri(context, voicemailEntry.numberAttributes()),
             VoicemailEntryText.buildPrimaryVoicemailText(context, voicemailEntry),
             LetterTileDrawable.TYPE_DEFAULT);
   }
diff --git a/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java b/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
index 7b8adfe..ffc53e7 100644
--- a/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
@@ -20,6 +20,7 @@
 import android.text.TextUtils;
 import com.android.dialer.contactactions.ContactPrimaryActionInfo;
 import com.android.dialer.contactactions.ContactPrimaryActionInfo.PhotoInfo;
+import com.android.dialer.contactphoto.NumberAttributeConverter;
 import com.android.dialer.lettertile.LetterTileDrawable;
 import com.android.dialer.voicemail.model.VoicemailEntry;
 
@@ -39,7 +40,9 @@
         .setPhotoInfo(
             PhotoInfo.builder()
                 .setPhotoId(voicemailEntry.numberAttributes().getPhotoId())
-                .setPhotoUri(voicemailEntry.numberAttributes().getPhotoUri())
+                .setPhotoUri(
+                    NumberAttributeConverter.getPhotoUri(
+                        context, voicemailEntry.numberAttributes()))
                 .setIsVideo(false)
                 .setContactType(
                     LetterTileDrawable.TYPE_DEFAULT) // TODO(uabdullah): Use proper type.
diff --git a/java/com/android/incallui/NewReturnToCallController.java b/java/com/android/incallui/NewReturnToCallController.java
index b8798b1..4c3c2a2 100644
--- a/java/com/android/incallui/NewReturnToCallController.java
+++ b/java/com/android/incallui/NewReturnToCallController.java
@@ -238,6 +238,7 @@
             .setIconDrawable(context.getDrawable(R.drawable.quantum_ic_exit_to_app_vd_theme_24))
             .setIntent(fullScreen)
             .setName(context.getText(R.string.bubble_return_to_call))
+            .setCheckable(false)
             .build());
     // Mute/unmute
     actions.add(
@@ -252,6 +253,7 @@
         Action.builder()
             .setIconDrawable(context.getDrawable(speakerButtonInfo.icon))
             .setName(context.getText(speakerButtonInfo.label))
+            .setCheckable(speakerButtonInfo.checkable)
             .setChecked(speakerButtonInfo.isChecked)
             .setIntent(speakerButtonInfo.checkable ? toggleSpeaker : showSpeakerSelect)
             .build());
@@ -261,6 +263,7 @@
             .setIconDrawable(context.getDrawable(R.drawable.quantum_ic_call_end_vd_theme_24))
             .setIntent(endCall)
             .setName(context.getText(R.string.incall_label_end_call))
+            .setCheckable(false)
             .build());
     return actions;
   }
diff --git a/java/com/android/incallui/PhoneLookupHistoryRecorder.java b/java/com/android/incallui/PhoneLookupHistoryRecorder.java
index abbf934..017e6f4 100644
--- a/java/com/android/incallui/PhoneLookupHistoryRecorder.java
+++ b/java/com/android/incallui/PhoneLookupHistoryRecorder.java
@@ -20,10 +20,10 @@
 import android.support.annotation.Nullable;
 import android.telecom.Call;
 import com.android.dialer.DialerPhoneNumber;
-import com.android.dialer.buildtype.BuildType;
 import com.android.dialer.common.Assert;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
+import com.android.dialer.configprovider.ConfigProviderBindings;
 import com.android.dialer.phonelookup.PhoneLookupComponent;
 import com.android.dialer.phonelookup.PhoneLookupInfo;
 import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory;
@@ -48,7 +48,7 @@
    * writes it to the PhoneLookupHistory. Otherwise does nothing.
    */
   static void recordPhoneLookupInfo(Context appContext, Call call) {
-    if (!(BuildType.get() == BuildType.BUGFOOD || LogUtil.isDebugEnabled())) {
+    if (!(ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false))) {
       return;
     }
 
diff --git a/java/com/android/newbubble/BottomActionViewController.java b/java/com/android/newbubble/BottomActionViewController.java
index 04e0e5f..b480ac9 100644
--- a/java/com/android/newbubble/BottomActionViewController.java
+++ b/java/com/android/newbubble/BottomActionViewController.java
@@ -23,6 +23,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.LinearInterpolator;
 
 /** Controller for showing and hiding bubble bottom action view. */
@@ -157,10 +158,14 @@
 
     // Scale unhighlight target back to 1x
     if (!shouldHighlightDismiss && dismissHighlighted) {
+      // A11y
+      dismissView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
       // Unhighlight dismiss
       dismissView.animate().scaleX(1f).scaleY(1f).setDuration(HIGHLIGHT_TARGET_DURATION).start();
       dismissHighlighted = false;
     } else if (!shouldHighlightEndCall && endCallHighlighted) {
+      // A11y
+      endCallView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
       // Unhighlight end call
       endCallView.animate().scaleX(1f).scaleY(1f).setDuration(HIGHLIGHT_TARGET_DURATION).start();
       endCallHighlighted = false;
@@ -168,6 +173,8 @@
 
     // Scale highlight target larger
     if (shouldHighlightDismiss && !dismissHighlighted) {
+      // A11y
+      dismissView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
       // Highlight dismiss
       dismissView.setPivotY(dismissView.getHeight() / 2 + textOffsetSize);
       dismissView
@@ -184,6 +191,8 @@
           .start();
       dismissHighlighted = true;
     } else if (shouldHighlightEndCall && !endCallHighlighted) {
+      // A11y
+      endCallView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
       // Highlight end call
       endCallView.setPivotY(dismissView.getHeight() / 2 + textOffsetSize);
       endCallView
diff --git a/java/com/android/newbubble/NewBubble.java b/java/com/android/newbubble/NewBubble.java
index 8b188ba..2e98ad1 100644
--- a/java/com/android/newbubble/NewBubble.java
+++ b/java/com/android/newbubble/NewBubble.java
@@ -722,7 +722,7 @@
       button.setCompoundDrawablesWithIntrinsicBounds(action.getIconDrawable(), null, null, null);
     }
     button.setChecked(action.isChecked());
-    button.setEnabled(action.isEnabled());
+    button.setCheckable(action.isCheckable());
     button.setText(action.getName());
     button.setContentDescription(action.getName());
     button.setOnClickListener(v -> doAction(action));
diff --git a/java/com/android/newbubble/NewBubbleInfo.java b/java/com/android/newbubble/NewBubbleInfo.java
index ec26a31..cc7ac7c 100644
--- a/java/com/android/newbubble/NewBubbleInfo.java
+++ b/java/com/android/newbubble/NewBubbleInfo.java
@@ -86,19 +86,19 @@
     @NonNull
     public abstract PendingIntent getIntent();
 
-    public abstract boolean isEnabled();
+    public abstract boolean isCheckable();
 
     public abstract boolean isChecked();
 
     public static Builder builder() {
-      return new AutoValue_NewBubbleInfo_Action.Builder().setEnabled(true).setChecked(false);
+      return new AutoValue_NewBubbleInfo_Action.Builder().setCheckable(true).setChecked(false);
     }
 
     public static Builder from(@NonNull Action action) {
       return builder()
           .setIntent(action.getIntent())
           .setChecked(action.isChecked())
-          .setEnabled(action.isEnabled())
+          .setCheckable(action.isCheckable())
           .setName(action.getName())
           .setIconDrawable(action.getIconDrawable());
     }
@@ -113,7 +113,7 @@
 
       public abstract Builder setIntent(@NonNull PendingIntent intent);
 
-      public abstract Builder setEnabled(boolean enabled);
+      public abstract Builder setCheckable(boolean enabled);
 
       public abstract Builder setChecked(boolean checked);
 
diff --git a/java/com/android/newbubble/NewCheckableButton.java b/java/com/android/newbubble/NewCheckableButton.java
index 15858d3..fda0ddc 100644
--- a/java/com/android/newbubble/NewCheckableButton.java
+++ b/java/com/android/newbubble/NewCheckableButton.java
@@ -45,22 +45,28 @@
 
   public NewCheckableButton(Context context, AttributeSet attrs, int defStyleAttr) {
     super(context, attrs, defStyleAttr);
+  }
 
+  public void setCheckable(boolean checkable) {
     ViewCompat.setAccessibilityDelegate(
         this,
         new AccessibilityDelegateCompat() {
           @Override
           public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
             super.onInitializeAccessibilityEvent(host, event);
-            event.setChecked(isChecked());
+            if (checkable) {
+              event.setChecked(isChecked());
+            }
           }
 
           @Override
           public void onInitializeAccessibilityNodeInfo(
               View host, AccessibilityNodeInfoCompat info) {
             super.onInitializeAccessibilityNodeInfo(host, info);
-            info.setCheckable(true);
-            info.setChecked(isChecked());
+            info.setCheckable(checkable);
+            if (checkable) {
+              info.setChecked(isChecked());
+            }
           }
         });
   }
diff --git a/java/com/android/newbubble/res/layout/bottom_action_base.xml b/java/com/android/newbubble/res/layout/bottom_action_base.xml
index 8f7ba75..b4d7c89 100644
--- a/java/com/android/newbubble/res/layout/bottom_action_base.xml
+++ b/java/com/android/newbubble/res/layout/bottom_action_base.xml
@@ -20,7 +20,8 @@
     android:weightSum="2"
     android:orientation="horizontal"
     android:gravity="center"
-    android:background="@drawable/bottom_action_scrim">
+    android:background="@drawable/bottom_action_scrim"
+    android:contentDescription="@string/a11y_bubble_bottom_action_description">
 
   <!-- Add space to make sure text is not off screen when scaled. (1 - 1/1.3) / 2 ~= 0.11 -->
   <View
@@ -33,7 +34,8 @@
       android:layout_width="0dp"
       android:layout_height="match_parent"
       android:layout_weight="0.78"
-      android:gravity="center">
+      android:gravity="center"
+      android:contentDescription="@string/bubble_bottom_action_hide">
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -60,7 +62,8 @@
       android:layout_width="0dp"
       android:layout_height="match_parent"
       android:layout_weight="0.78"
-      android:gravity="center">
+      android:gravity="center"
+      android:contentDescription="@string/bubble_bottom_action_end_call">
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
diff --git a/java/com/android/newbubble/res/values/strings.xml b/java/com/android/newbubble/res/values/strings.xml
index 08c685e..7ef61ce 100644
--- a/java/com/android/newbubble/res/values/strings.xml
+++ b/java/com/android/newbubble/res/values/strings.xml
@@ -18,6 +18,8 @@
 <resources>
   <!-- A string for Talkback to read when accessibility user touch bubble. -->
   <string name="a11y_bubble_description">Dialer bubble</string>
+  <!-- A string to describe bubble bottom actions for accessibility user. -->
+  <string name="a11y_bubble_bottom_action_description">Bottom action buttons</string>
   <!-- A string to describe available action for accessibility user. It will be read as "Actions:
     double tap to expand call action menu". -->
   <string name="a11y_bubble_primary_button_expand_action">Expand call action menu</string>
diff --git a/packages.mk b/packages.mk
index ee01cc8..4985425 100644
--- a/packages.mk
+++ b/packages.mk
@@ -40,7 +40,6 @@
 	com.android.dialer.notification \
 	com.android.dialer.oem \
 	com.android.dialer.phonelookup.database \
-	com.android.dialer.phonelookup.consolidator \
 	com.android.dialer.phonenumberutil \
 	com.android.dialer.postcall \
 	com.android.dialer.precall.impl \