Merge "Make sure ReorderAlgorithm only work on the logic layer and not on the view layer" into main
diff --git a/src/com/android/launcher3/celllayout/ReorderAlgorithm.java b/src/com/android/launcher3/celllayout/ReorderAlgorithm.java
index 5e5eefe..17786f2 100644
--- a/src/com/android/launcher3/celllayout/ReorderAlgorithm.java
+++ b/src/com/android/launcher3/celllayout/ReorderAlgorithm.java
@@ -15,10 +15,13 @@
  */
 package com.android.launcher3.celllayout;
 
+import android.graphics.Rect;
 import android.view.View;
 
 import com.android.launcher3.CellLayout;
 
+import java.util.Map.Entry;
+
 /**
  * Contains the logic of a reorder.
  *
@@ -109,14 +112,16 @@
      */
     public CellLayout.ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX,
             int spanY, View dragView) {
-        int[] result = new int[2];
-        if (mCellLayout.isNearestDropLocationOccupied(pixelX, pixelY, spanX, spanY, dragView,
-                result)) {
-            result[0] = result[1] = -1;
-        }
+        int[] result = mCellLayout.findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY,
+                new int[2]);
         CellLayout.ItemConfiguration solution = new CellLayout.ItemConfiguration();
         mCellLayout.copyCurrentStateToSolution(solution, false);
-        solution.isSolution = result[0] != -1;
+
+        solution.isSolution = !isConfigurationRegionOccupied(
+                new Rect(result[0], result[1], result[0] + spanX, result[1] + spanY),
+                solution,
+                dragView
+        );
         if (!solution.isSolution) {
             return solution;
         }
@@ -127,6 +132,17 @@
         return solution;
     }
 
+    private boolean isConfigurationRegionOccupied(Rect region,
+            CellLayout.ItemConfiguration configuration, View ignoreView) {
+        return configuration.map.entrySet()
+                .stream()
+                .filter(entry -> entry.getKey() != ignoreView)
+                .map(Entry::getValue)
+                .anyMatch(cellAndSpan -> region.intersect(cellAndSpan.cellX, cellAndSpan.cellY,
+                        cellAndSpan.cellX + cellAndSpan.spanX,
+                        cellAndSpan.cellY + cellAndSpan.spanY));
+    }
+
     /**
      * Returns a "reorder" where we simply drop the item in the closest empty space, without moving
      * any other item in the way.