Unit testing ButtonDropTarget

Originally there was a bug in a method (isTextClippedVertically) in ButtonDropTarget. While attempting to write a unit test it became necessary to refactor ButtonDropTarget and DeleteDropTarget to decouple them from their dependency on launcher in order to allow for a unit test to be written

The pattern we are introducing here is to decouple Launcher from a controller, in order to facilitate easier testing.
Instead of calling Launcher.getLauncher() we call the method through ActivityContext, which has a testing wrapper already defined. Here is a diagram that explains the old and new pattern

Design Pattern: https://screenshot.googleplex.com/7apiE2DaGDrFzy9.png

Test: isTextClippedVerticallyTest
Bug: b/274402490

Change-Id: I1f3003d0b62dddbceb6e492b15aa5d7352d3a293
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index e653283..fc7f614 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -18,8 +18,6 @@
 
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static com.android.launcher3.LauncherState.NORMAL;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
@@ -34,12 +32,15 @@
 import android.widget.PopupWindow;
 import android.widget.TextView;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.views.ActivityContext;
 
 /**
  * Implements a DropTarget.
@@ -59,8 +60,8 @@
 
     private final Rect mTempRect = new Rect();
 
-    protected final Launcher mLauncher;
-
+    protected final ActivityContext mActivityContext;
+    protected final DropTargetHandler mDropTargetHandler;
     protected DropTargetBar mDropTargetBar;
 
     /** Whether this drop target is active for the current drag */
@@ -83,13 +84,17 @@
     private PopupWindow mToolTip;
     private int mToolTipLocation;
 
+    public ButtonDropTarget(Context context) {
+        this(context, null, 0);
+    }
     public ButtonDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
     public ButtonDropTarget(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mLauncher = Launcher.getLauncher(context);
+        mActivityContext = ActivityContext.lookupContext(context);
+        mDropTargetHandler = mActivityContext.getDropTargetHandler();
 
         Resources resources = getResources();
         mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
@@ -210,7 +215,8 @@
     @Override
     public boolean isDropEnabled() {
         return mActive && (mAccessibleDrag ||
-                mLauncher.getDragController().getDistanceDragged() >= mDragDistanceThreshold);
+                mActivityContext.getDragController().getDistanceDragged()
+                        >= mDragDistanceThreshold);
     }
 
     @Override
@@ -229,7 +235,8 @@
             // FlingAnimation handles the animation and then calls completeDrop().
             return;
         }
-        final DragLayer dragLayer = mLauncher.getDragLayer();
+
+        final DragLayer dragLayer = mDropTargetHandler.getDragLayer();
         final DragView dragView = d.dragView;
         final Rect to = getIconRect(d);
         final float scale = (float) to.width() / dragView.getMeasuredWidth();
@@ -240,9 +247,10 @@
         Runnable onAnimationEndRunnable = () -> {
             completeDrop(d);
             mDropTargetBar.onDragEnd();
-            mLauncher.getStateManager().goToState(NORMAL);
+            mDropTargetHandler.onDropAnimationComplete();
         };
 
+
         dragLayer.animateView(d.dragView, to, scale, 0.1f, 0.1f,
                 DRAG_VIEW_DROP_DURATION,
                 Interpolators.DEACCEL_2, onAnimationEndRunnable,
@@ -261,10 +269,10 @@
     @Override
     public void getHitRectRelativeToDragLayer(android.graphics.Rect outRect) {
         super.getHitRect(outRect);
-        outRect.bottom += mLauncher.getDeviceProfile().dropTargetDragPaddingPx;
+        outRect.bottom += mActivityContext.getDeviceProfile().dropTargetDragPaddingPx;
 
         sTempCords[0] = sTempCords[1] = 0;
-        mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, sTempCords);
+        mActivityContext.getDragLayer().getDescendantCoordRelativeToSelf(this, sTempCords);
         outRect.offsetTo(sTempCords[0], sTempCords[1]);
     }
 
@@ -273,7 +281,7 @@
         int viewHeight = dragObject.dragView.getMeasuredHeight();
         int drawableWidth = mDrawable.getIntrinsicWidth();
         int drawableHeight = mDrawable.getIntrinsicHeight();
-        DragLayer dragLayer = mLauncher.getDragLayer();
+        DragLayer dragLayer = mDropTargetHandler.getDragLayer();
 
         // Find the rect to animate to (the view is center aligned)
         Rect to = new Rect();
@@ -314,7 +322,7 @@
 
     @Override
     public void onClick(View v) {
-        mLauncher.getAccessibilityDelegate().handleAccessibleDrop(this, null, null);
+        mDropTargetHandler.onClick(this);
     }
 
     public void setTextVisible(boolean isVisible) {
@@ -407,7 +415,8 @@
     /**
      * Returns if the text will be clipped vertically within the provided availableHeight.
      */
-    private boolean isTextClippedVertically(int availableHeight) {
+    @VisibleForTesting
+    protected boolean isTextClippedVertically(int availableHeight) {
         availableHeight -= getPaddingTop() + getPaddingBottom();
         if (availableHeight <= 0) {
             return true;