Implemented drag to remove in NUI with old favorites.

This change moves the remove button to overlap the search bar
instead of reside underneath it since we no longer have top tabs.

Bug: 72722364
Test: manual
PiperOrigin-RevId: 184347110
Change-Id: I5bfa70fec9dd7ee6ee0b7270039931f9277291f4
diff --git a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
index ed64f7a..a201859 100644
--- a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
+++ b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java
@@ -46,6 +46,7 @@
 import com.android.dialer.logging.InteractionEvent;
 import com.android.dialer.logging.Logger;
 import com.android.dialer.shortcuts.ShortcutRefresher;
+import com.android.dialer.strictmode.StrictModeUtils;
 import com.google.common.collect.ComparisonChain;
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -519,22 +520,27 @@
       }
 
       if (changed && dropEntryIndex < PIN_LIMIT) {
-        final ArrayList<ContentProviderOperation> operations =
+        ArrayList<ContentProviderOperation> operations =
             getReflowedPinningOperations(contactEntries, draggedEntryIndex, dropEntryIndex);
-        if (!operations.isEmpty()) {
-          // update the database here with the new pinned positions
-          try {
-            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
-            Logger.get(context).logInteraction(InteractionEvent.Type.SPEED_DIAL_PIN_CONTACT);
-          } catch (RemoteException | OperationApplicationException e) {
-            LogUtil.e(TAG, "Exception thrown when pinning contacts", e);
-          }
-        }
+        StrictModeUtils.bypass(() -> updateDatabaseWithPinnedPositions(operations));
       }
       draggedEntry = null;
     }
   }
 
+  private void updateDatabaseWithPinnedPositions(ArrayList<ContentProviderOperation> operations) {
+    if (operations.isEmpty()) {
+      // Nothing to update
+      return;
+    }
+    try {
+      context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
+      Logger.get(context).logInteraction(InteractionEvent.Type.SPEED_DIAL_PIN_CONTACT);
+    } catch (RemoteException | OperationApplicationException e) {
+      LogUtil.e(TAG, "Exception thrown when pinning contacts", e);
+    }
+  }
+
   /**
    * Used when a contact is removed from speeddial. This will both unstar and set pinned position of
    * the contact to PinnedPosition.DEMOTED so that it doesn't show up anymore in the favorites list.
@@ -543,7 +549,8 @@
     final ContentValues values = new ContentValues(2);
     values.put(Contacts.STARRED, false);
     values.put(Contacts.PINNED, PinnedPositions.DEMOTED);
-    context.getContentResolver().update(contactUri, values, null, null);
+    StrictModeUtils.bypass(
+        () -> context.getContentResolver().update(contactUri, values, null, null));
   }
 
   /**
diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
index c7410d5..16b74d5 100644
--- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java
+++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
@@ -34,6 +34,7 @@
 import android.view.View;
 import android.widget.ImageView;
 import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
+import com.android.dialer.animation.AnimUtils;
 import com.android.dialer.app.calllog.CallLogAdapter;
 import com.android.dialer.app.calllog.CallLogFragment;
 import com.android.dialer.app.calllog.CallLogFragment.CallLogFragmentListener;
@@ -44,6 +45,7 @@
 import com.android.dialer.app.list.OnDragDropListener;
 import com.android.dialer.app.list.OnListFragmentScrolledListener;
 import com.android.dialer.app.list.PhoneFavoriteSquareTileView;
+import com.android.dialer.app.list.RemoveView;
 import com.android.dialer.callintent.CallIntentBuilder;
 import com.android.dialer.callintent.CallSpecificAppData;
 import com.android.dialer.common.FragmentUtils.FragmentUtilListener;
@@ -112,8 +114,7 @@
 
   // Speed Dial
   private MainOnPhoneNumberPickerActionListener onPhoneNumberPickerActionListener;
-  private MainOldSpeedDialFragmentHostInterface oldSpeedDialFragmentHostInterface;
-  private MainOnDragDropListener onDragDropListener;
+  private MainOldSpeedDialFragmentHost oldSpeedDialFragmentHost;
 
   /** Language the device was in last time {@link #onSaveInstanceState(Bundle)} was called. */
   private String savedLanguageCode;
@@ -177,10 +178,12 @@
 
     onListFragmentScrolledListener = new MainOnListFragmentScrolledListener(snackbarContainer);
     onPhoneNumberPickerActionListener = new MainOnPhoneNumberPickerActionListener(mainActivity);
-    oldSpeedDialFragmentHostInterface =
-        new MainOldSpeedDialFragmentHostInterface(
-            bottomNav, mainActivity.findViewById(R.id.contact_tile_drag_shadow_overlay));
-    onDragDropListener = new MainOnDragDropListener();
+    oldSpeedDialFragmentHost =
+        new MainOldSpeedDialFragmentHost(
+            bottomNav,
+            mainActivity.findViewById(R.id.contact_tile_drag_shadow_overlay),
+            mainActivity.findViewById(R.id.remove_view),
+            mainActivity.findViewById(R.id.search_view_container));
 
     lastTabController = new LastTabController(mainActivity, bottomNav);
 
@@ -283,10 +286,8 @@
       return (T) onListFragmentScrolledListener;
     } else if (callbackInterface.isInstance(onPhoneNumberPickerActionListener)) {
       return (T) onPhoneNumberPickerActionListener;
-    } else if (callbackInterface.isInstance(oldSpeedDialFragmentHostInterface)) {
-      return (T) oldSpeedDialFragmentHostInterface;
-    } else if (callbackInterface.isInstance(onDragDropListener)) {
-      return (T) onDragDropListener;
+    } else if (callbackInterface.isInstance(oldSpeedDialFragmentHost)) {
+      return (T) oldSpeedDialFragmentHost;
     } else {
       return null;
     }
@@ -644,25 +645,38 @@
     }
   }
 
-  /** @see OldSpeedDialFragment.HostInterface */
-  private static final class MainOldSpeedDialFragmentHostInterface
-      implements OldSpeedDialFragment.HostInterface {
+  /**
+   * Handles the callbacks for {@link OldSpeedDialFragment} and drag/drop logic for drag to remove.
+   *
+   * @see OldSpeedDialFragment.HostInterface
+   * @see OnDragDropListener
+   */
+  private static final class MainOldSpeedDialFragmentHost
+      implements OldSpeedDialFragment.HostInterface, OnDragDropListener {
 
     private final BottomNavBar bottomNavBar;
     private final ImageView dragShadowOverlay;
+    private final RemoveView removeView;
+    private final View searchViewContainer;
 
     // TODO(calderwoodra): Use this for drag and drop
     @SuppressWarnings("unused")
     private DragDropController dragDropController;
 
-    MainOldSpeedDialFragmentHostInterface(BottomNavBar bottomNavBar, ImageView dragShadowOverlay) {
+    MainOldSpeedDialFragmentHost(
+        BottomNavBar bottomNavBar,
+        ImageView dragShadowOverlay,
+        RemoveView removeView,
+        View searchViewContainer) {
       this.bottomNavBar = bottomNavBar;
       this.dragShadowOverlay = dragShadowOverlay;
+      this.removeView = removeView;
+      this.searchViewContainer = searchViewContainer;
     }
 
     @Override
     public void setDragDropController(DragDropController dragDropController) {
-      this.dragDropController = dragDropController;
+      removeView.setDragDropController(dragDropController);
     }
 
     @Override
@@ -674,23 +688,30 @@
     public ImageView getDragShadowOverlay() {
       return dragShadowOverlay;
     }
-  }
-
-  /** @see com.android.dialer.app.list.OnDragDropListener */
-  // TODO(calderwoodra): implement drag and drop
-  private static final class MainOnDragDropListener implements OnDragDropListener {
 
     @Override
-    public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {}
+    public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {
+      showRemoveView(true);
+    }
 
     @Override
     public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {}
 
     @Override
-    public void onDragFinished(int x, int y) {}
+    public void onDragFinished(int x, int y) {
+      showRemoveView(false);
+    }
 
     @Override
     public void onDroppedOnRemove() {}
+
+    private void showRemoveView(boolean show) {
+      if (show) {
+        AnimUtils.crossFadeViews(removeView, searchViewContainer, 300);
+      } else {
+        AnimUtils.crossFadeViews(searchViewContainer, removeView, 300);
+      }
+    }
   }
 
   /**
diff --git a/java/com/android/dialer/main/impl/toolbar/res/layout/toolbar_layout.xml b/java/com/android/dialer/main/impl/toolbar/res/layout/toolbar_layout.xml
index 9b0086b..7c4cee2 100644
--- a/java/com/android/dialer/main/impl/toolbar/res/layout/toolbar_layout.xml
+++ b/java/com/android/dialer/main/impl/toolbar/res/layout/toolbar_layout.xml
@@ -18,8 +18,7 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="?attr/actionBarSize"
+    android:layout_height="?attr/actionBarSize"
     android:background="@color/dialer_theme_color"
     app:contentInsetStart="0dp"
     app:contentInsetEnd="0dp">
@@ -89,4 +88,45 @@
 
     <include layout="@layout/expanded_search_bar"/>
   </com.android.dialer.main.impl.toolbar.SearchBarView>
+
+  <!-- Sets android:importantForAccessibility="no" to avoid being announced when navigating with
+       talkback enabled. It will still be announced when user drag or drop contact onto it.
+       This is required since drag and drop event is only sent to views are visible when drag
+       starts. -->
+  <com.android.dialer.app.list.RemoveView
+      android:id="@+id/remove_view"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:layout_gravity="center_vertical"
+      android:layout_margin="@dimen/search_bar_margin"
+      android:contentDescription="@string/main_remove_contact"
+      android:visibility="gone"
+      android:importantForAccessibility="no">
+
+    <LinearLayout
+        android:id="@+id/remove_view_content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/dialer_theme_color"
+        android:gravity="center"
+        android:orientation="horizontal">
+
+      <ImageView
+          android:id="@+id/remove_view_icon"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_marginTop="8dp"
+          android:layout_marginBottom="8dp"
+          android:src="@drawable/quantum_ic_close_vd_theme_24"
+          android:tint="@color/dialer_primary_text_color_white"/>
+
+      <TextView
+          android:id="@+id/remove_view_text"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/main_remove_contact"
+          android:textColor="@color/dialer_primary_text_color_white"
+          android:textSize="16sp"/>
+    </LinearLayout>
+  </com.android.dialer.app.list.RemoveView>
 </com.android.dialer.main.impl.toolbar.MainToolbar>
\ No newline at end of file
diff --git a/java/com/android/dialer/main/impl/toolbar/res/values/strings.xml b/java/com/android/dialer/main/impl/toolbar/res/values/strings.xml
index c1d153f..6af235b 100644
--- a/java/com/android/dialer/main/impl/toolbar/res/values/strings.xml
+++ b/java/com/android/dialer/main/impl/toolbar/res/values/strings.xml
@@ -39,4 +39,7 @@
   <string name="settings">Settings</string>
   <!-- Send feedback about the app [CHAR LIMIT=20] -->
   <string name="main_send_feedback">Send feedback</string>
+
+  <!-- Remove button that shows up when contact is long-pressed. [CHAR LIMIT=NONE] -->
+  <string name="main_remove_contact">Remove</string>
 </resources>
\ No newline at end of file