Implement contacts promo in NUI.

Bug: 72525950
Test: ContactsPromoFragmentTest, MainSearchControllerTest, OldGoogleMainActivityPeerTest
PiperOrigin-RevId: 187224361
Change-Id: Idc43255ccc673c6c5c17b70d1f367d1a4802bfd0
diff --git a/java/com/android/dialer/contactsfragment/ContactsFragment.java b/java/com/android/dialer/contactsfragment/ContactsFragment.java
index ae2bd74..794a5b9 100644
--- a/java/com/android/dialer/contactsfragment/ContactsFragment.java
+++ b/java/com/android/dialer/contactsfragment/ContactsFragment.java
@@ -158,6 +158,11 @@
     contactsPrefs.registerChangeListener(this);
     header = getArguments().getInt(EXTRA_HEADER);
     hasPhoneNumbers = getArguments().getBoolean(EXTRA_HAS_PHONE_NUMBERS);
+    if (savedInstanceState == null) {
+      // The onHiddenChanged callback does not get called the first time the fragment is
+      // attached, so call it ourselves here.
+      onHiddenChanged(false);
+    }
   }
 
   @Override
@@ -354,6 +359,16 @@
     }
   }
 
+  @Override
+  public void onHiddenChanged(boolean hidden) {
+    super.onHiddenChanged(hidden);
+    OnContactsFragmentHiddenChangedListener listener =
+        FragmentUtils.getParent(this, OnContactsFragmentHiddenChangedListener.class);
+    if (listener != null) {
+      listener.onContactsFragmentHiddenChanged(hidden);
+    }
+  }
+
   private void loadContacts() {
     getLoaderManager().initLoader(0, null, this);
     recyclerView.setVisibility(View.VISIBLE);
@@ -371,4 +386,9 @@
     /** Called when a contact is selected in {@link ContactsFragment}. */
     void onContactSelected(ImageView photo, Uri contactUri, long contactId);
   }
+
+  /** Listener for contacts fragment hidden state */
+  public interface OnContactsFragmentHiddenChangedListener {
+    void onContactsFragmentHiddenChanged(boolean hidden);
+  }
 }
diff --git a/java/com/android/dialer/main/impl/MainSearchController.java b/java/com/android/dialer/main/impl/MainSearchController.java
index 33e0981..4f3ee60 100644
--- a/java/com/android/dialer/main/impl/MainSearchController.java
+++ b/java/com/android/dialer/main/impl/MainSearchController.java
@@ -52,6 +52,7 @@
 import com.android.dialer.smartdial.util.SmartDialNameMatcher;
 import com.google.common.base.Optional;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Search controller for handling all the logic related to entering and exiting the search UI.
@@ -83,6 +84,8 @@
   private final MainToolbar toolbar;
   private final View toolbarShadow;
 
+  private final List<OnSearchShowListener> onSearchShowListenerList = new ArrayList<>();
+
   public MainSearchController(
       MainActivity mainActivity,
       BottomNavBar bottomNav,
@@ -142,6 +145,8 @@
       transaction.show(dialpadFragment);
     }
     transaction.commit();
+
+    notifyListenersOnSearchOpen();
   }
 
   /**
@@ -288,6 +293,8 @@
     if (getDialpadFragment() != null) {
       getDialpadFragment().clearDialpad();
     }
+
+    notifyListenersOnSearchClose();
   }
 
   @Nullable
@@ -356,6 +363,8 @@
     searchFragment.setQuery(
         query.isPresent() ? query.get() : "", CallInitiationType.Type.REGULAR_SEARCH);
     transaction.commit();
+
+    notifyListenersOnSearchOpen();
   }
 
   @Override
@@ -455,4 +464,31 @@
       toolbar.slideUp(false);
     }
   }
+
+  public void addOnSearchShowListener(OnSearchShowListener listener) {
+    onSearchShowListenerList.add(listener);
+  }
+
+  public void removeOnSearchShowListener(OnSearchShowListener listener) {
+    onSearchShowListenerList.remove(listener);
+  }
+
+  private void notifyListenersOnSearchOpen() {
+    for (OnSearchShowListener listener : onSearchShowListenerList) {
+      listener.onSearchOpen();
+    }
+  }
+
+  private void notifyListenersOnSearchClose() {
+    for (OnSearchShowListener listener : onSearchShowListenerList) {
+      listener.onSearchClose();
+    }
+  }
+
+  /** Listener for search fragment show states change */
+  public interface OnSearchShowListener {
+    void onSearchOpen();
+
+    void onSearchClose();
+  }
 }