Add support for multiple focus listeners to ExtendedEditText.

Bug: 249952937
Test: manual, see other bug in the topic
Change-Id: I8cc6f525d1a895cc9ee6c6087b51af330d4f25a6
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index 11f2020..c59f25d 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.SHOW;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.DragEvent;
@@ -27,12 +28,17 @@
 
 import com.android.launcher3.views.ActivityContext;
 
+import java.util.HashSet;
+import java.util.Set;
+
 
 /**
  * The edit text that reports back when the back key has been pressed.
  * Note: AppCompatEditText doesn't fully support #displayCompletions and #onCommitCompletion
  */
 public class ExtendedEditText extends EditText {
+    private final Set<OnFocusChangeListener> mOnFocusChangeListeners = new HashSet<>();
+
     private boolean mForceDisableSuggestions = false;
 
     /**
@@ -129,4 +135,28 @@
             setText("");
         }
     }
+
+    /**
+     * This method should be preferred to {@link #setOnFocusChangeListener(OnFocusChangeListener)},
+     * as it allows for multiple listeners from different sources.
+     */
+    public void addOnFocusChangeListener(OnFocusChangeListener listener) {
+        mOnFocusChangeListeners.add(listener);
+    }
+
+    /**
+     * Removes the given listener from the set of registered focus listeners, or does nothing if it
+     * wasn't registered in the first place.
+     */
+    public void removeOnFocusChangeListener(OnFocusChangeListener listener) {
+        mOnFocusChangeListeners.remove(listener);
+    }
+
+    @Override
+    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+        super.onFocusChanged(focused, direction, previouslyFocusedRect);
+        for (OnFocusChangeListener listener : mOnFocusChangeListeners) {
+            listener.onFocusChange(this, focused);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 4c461aa..9d085d1 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -70,7 +70,7 @@
         mInput.addTextChangedListener(this);
         mInput.setOnEditorActionListener(this);
         mInput.setOnBackKeyListener(this);
-        mInput.setOnFocusChangeListener(this);
+        mInput.addOnFocusChangeListener(this);
         mSearchAlgorithm = searchAlgorithm;
     }
 
@@ -160,6 +160,7 @@
         mCallback.clearSearchResult();
         mInput.reset();
         mQuery = null;
+        mInput.removeOnFocusChangeListener(this);
     }
 
     /**
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 99822da..94eea35 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -282,7 +282,6 @@
         mFolderName = findViewById(R.id.folder_name);
         mFolderName.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.folderLabelTextSizePx);
         mFolderName.setOnBackKeyListener(this);
-        mFolderName.setOnFocusChangeListener(this);
         mFolderName.setOnEditorActionListener(this);
         mFolderName.setSelectAllOnFocus(true);
         mFolderName.setInputType(mFolderName.getInputType()
@@ -457,6 +456,13 @@
         // the folder itself.
         requestFocus();
         super.onAttachedToWindow();
+        mFolderName.addOnFocusChangeListener(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mFolderName.removeOnFocusChangeListener(this);
     }
 
     @Override