Merge "Fixing small folder bugs"
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 383f5b4..0198cc3 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -69,7 +69,7 @@
     <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Deinstallieren"</string>
     <string name="accessibility_search_button" msgid="816822994629942611">"Suchen"</string>
     <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Sprachsuche"</string>
-    <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Anwendungen"</string>
+    <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Apps"</string>
     <string name="accessibility_customize_button" msgid="585539669413531163">"Anpassen"</string>
     <string name="accessibility_delete_button" msgid="3628162007991023603">"Entfernen"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Update deinstallieren"</string>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index f0a712a..2bd2e91 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -37,10 +37,10 @@
 import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.LruCache;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -74,14 +74,20 @@
     // Content
     private ContentType mContentType;
     private ArrayList<ApplicationInfo> mApps;
-    private List<AppWidgetProviderInfo> mWidgets;
-    private List<ResolveInfo> mShortcuts;
+    private List<Object> mWidgets;
+
+    // Caching
+    private Drawable mDefaultWidgetBackground;
+    private final int sWidgetPreviewCacheSize = 1 * 1024 * 1024; // 1 MiB
+    private LruCache<Object, Bitmap> mWidgetPreviewCache;
 
     // Dimens
     private int mContentWidth;
     private int mMaxWidgetSpan, mMinWidgetSpan;
     private int mWidgetCellWidthGap, mWidgetCellHeightGap;
     private int mWidgetCountX, mWidgetCountY;
+    private final int mWidgetPreviewIconPaddedDimension;
+    private final float sWidgetPreviewIconPaddingPercentage = 0.25f;
     private PagedViewCellLayout mWidgetSpacingLayout;
 
     // Animations
@@ -95,8 +101,16 @@
         mPackageManager = context.getPackageManager();
         mContentType = ContentType.Applications;
         mApps = new ArrayList<ApplicationInfo>();
-        mWidgets = new ArrayList<AppWidgetProviderInfo>();
-        mShortcuts = new ArrayList<ResolveInfo>();
+        mWidgets = new ArrayList<Object>();
+        mWidgetPreviewCache = new LruCache<Object, Bitmap>(sWidgetPreviewCacheSize) {
+            protected int sizeOf(Object key, Bitmap value) {
+                return value.getByteCount();
+            }
+        };
+
+        // Save the default widget preview background
+        Resources resources = context.getResources();
+        mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview);
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0);
         mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 6);
@@ -121,6 +135,12 @@
         // preview can be before applying the widget scaling
         mMinWidgetSpan = 1;
         mMaxWidgetSpan = 3;
+
+        // The padding on the non-matched dimension for the default widget preview icons
+        // (top + bottom)
+        int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+        mWidgetPreviewIconPaddedDimension =
+            (int) (iconSize * (1 + (2 * sWidgetPreviewIconPaddingPercentage)));
     }
 
     @Override
@@ -134,14 +154,13 @@
     }
 
     public void onPackagesUpdated() {
-        // Get the list of widgets
-        mWidgets = AppWidgetManager.getInstance(mLauncher).getInstalledProviders();
-        Collections.sort(mWidgets, LauncherModel.WIDGET_NAME_COMPARATOR);
-
-        // Get the list of shortcuts
+        // Get the list of widgets and shortcuts
+        mWidgets.clear();
+        mWidgets.addAll(AppWidgetManager.getInstance(mLauncher).getInstalledProviders());
         Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
-        mShortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0);
-        Collections.sort(mShortcuts, new LauncherModel.ShortcutNameComparator(mPackageManager));
+        mWidgets.addAll(mPackageManager.queryIntentActivities(shortcutsIntent, 0));
+        Collections.sort(mWidgets,
+                new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
     }
 
     /**
@@ -338,23 +357,38 @@
     private void beginDraggingWidget(View v) {
         // Get the widget preview as the drag representation
         ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
-        PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) v.getTag();
+        PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
 
         // Compose the drag image
+        Bitmap b;
         Drawable preview = image.getDrawable();
         int w = preview.getIntrinsicWidth();
         int h = preview.getIntrinsicHeight();
-        Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
-        renderDrawableToBitmap(preview, b, 0, 0, w, h, 1, 1);
+        if (createItemInfo instanceof PendingAddWidgetInfo) {
+            PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) createItemInfo;
+            int[] spanXY = CellLayout.rectToCell(getResources(),
+                    createWidgetInfo.minWidth, createWidgetInfo.minHeight, null);
+            createItemInfo.spanX = spanXY[0];
+            createItemInfo.spanY = spanXY[1];
+
+            b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+            renderDrawableToBitmap(preview, b, 0, 0, w, h, 1, 1);
+        } else {
+            // Workaround for the fact that we don't keep the original ResolveInfo associated with
+            // the shortcut around.  To get the icon, we just render the preview image (which has
+            // the shortcut icon) to a new drag bitmap that clips the non-icon space.
+            b = Bitmap.createBitmap(mWidgetPreviewIconPaddedDimension,
+                    mWidgetPreviewIconPaddedDimension, Bitmap.Config.ARGB_8888);
+            Canvas c = new Canvas(b);
+            preview.draw(c);
+            createItemInfo.spanX = createItemInfo.spanY = 1;
+        }
 
         // Start the drag
-        int[] spanXY = CellLayout.rectToCell(getResources(),
-                createWidgetInfo.minWidth, createWidgetInfo.minHeight, null);
-        createWidgetInfo.spanX = spanXY[0];
-        createWidgetInfo.spanY = spanXY[1];
         mLauncher.lockScreenOrientation();
-        mLauncher.getWorkspace().onDragStartedWithItemSpans(spanXY[0], spanXY[1], b);
-        mDragController.startDrag(image, b, this, createWidgetInfo,
+        mLauncher.getWorkspace().onDragStartedWithItemSpans(createItemInfo.spanX,
+                createItemInfo.spanY, b);
+        mDragController.startDrag(image, b, this, createItemInfo,
                 DragController.DRAG_ACTION_COPY, null);
         b.recycle();
     }
@@ -362,14 +396,16 @@
     protected boolean beginDragging(View v) {
         if (!super.beginDragging(v)) return false;
 
+        // Hide the pane so that the user can drop onto the workspace, we must do this first,
+        // due to how the drop target layout is computed when we start dragging to the workspace.
+        mLauncher.showWorkspace(true);
+
         if (v instanceof PagedViewIcon) {
             beginDraggingApplication(v);
         } else if (v instanceof PagedViewWidget) {
             beginDraggingWidget(v);
         }
 
-        // Hide the pane so that the user can drop onto the workspace
-        mLauncher.showWorkspace(true);
         return true;
     }
     private void endDragging(boolean success) {
@@ -401,6 +437,27 @@
     @Override
     public void onDropCompleted(View target, Object dragInfo, boolean success) {
         endDragging(success);
+
+        // Display an error message if the drag failed due to there not being enough space on the
+        // target layout we were dropping on.
+        if (!success) {
+            boolean showOutOfSpaceMessage = false;
+            if (target instanceof Workspace) {
+                int currentScreen = mLauncher.getCurrentWorkspaceScreen();
+                Workspace workspace = (Workspace) target;
+                CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen);
+                ItemInfo itemInfo = (ItemInfo) dragInfo;
+                if (layout != null) {
+                    layout.calculateSpans(itemInfo);
+                    showOutOfSpaceMessage =
+                            !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
+                }
+            }
+            // TODO-APPS_CUSTOMIZE: We need to handle this for folders as well later.
+            if (showOutOfSpaceMessage) {
+                mLauncher.showOutOfSpaceMessage();
+            }
+        }
     }
 
     public void setContentType(ContentType type) {
@@ -479,8 +536,40 @@
         d.setBounds(oldBounds); // Restore the bounds
         c.restore();
     }
+    private FastBitmapDrawable getShortcutPreview(ResolveInfo info, int cellWidth, int cellHeight) {
+        // Return the cached version if necessary
+        Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
+        if (cachedBitmap != null) {
+            return new FastBitmapDrawable(cachedBitmap);
+        }
+
+        Resources resources = mLauncher.getResources();
+        int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+        // We only need to make it wide enough so as not allow the preview to be scaled
+        int expectedWidth = cellWidth;
+        int expectedHeight = mWidgetPreviewIconPaddedDimension;
+        int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage);
+
+        // Render the icon
+        Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
+        IconCache cache = ((LauncherApplication) mLauncher.getApplication()).getIconCache();
+        Drawable icon = cache.getFullResIcon(info, mPackageManager);
+        renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0,
+                mWidgetPreviewIconPaddedDimension, mWidgetPreviewIconPaddedDimension, 1f, 1f);
+        renderDrawableToBitmap(icon, preview, offset, offset, iconSize, iconSize, 1f, 1f);
+        FastBitmapDrawable iconDrawable = new FastBitmapDrawable(preview);
+        iconDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
+        mWidgetPreviewCache.put(info, preview);
+        return iconDrawable;
+    }
     private FastBitmapDrawable getWidgetPreview(AppWidgetProviderInfo info, int cellHSpan,
             int cellVSpan, int cellWidth, int cellHeight) {
+        // Return the cached version if necessary
+        Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
+        if (cachedBitmap != null) {
+            return new FastBitmapDrawable(cachedBitmap);
+        }
+
         // Calculate the size of the drawable
         cellHSpan = Math.max(mMinWidgetSpan, Math.min(mMaxWidgetSpan, cellHSpan));
         cellVSpan = Math.max(mMinWidgetSpan, Math.min(mMaxWidgetSpan, cellVSpan));
@@ -520,23 +609,29 @@
                 renderDrawableToBitmap(drawable, preview, 0, 0, newWidth, newHeight, 1f, 1f);
                 newDrawable = new FastBitmapDrawable(preview);
                 newDrawable.setBounds(0, 0, newWidth, newHeight);
+                mWidgetPreviewCache.put(info, preview);
             }
         }
 
         // Generate a preview image if we couldn't load one
         if (drawable == null) {
-            // The icon itself takes up space, so update expected width/height to have min of 2
-            cellHSpan = Math.max(2, cellHSpan);
-            cellVSpan = Math.max(2, cellVSpan);
-            expectedWidth = (int) (widgetPreviewScale
-                    * mWidgetSpacingLayout.estimateCellWidth(cellHSpan));
-            expectedHeight = (int) (widgetPreviewScale
-                    * mWidgetSpacingLayout.estimateCellHeight(cellVSpan));
+            Resources resources = mLauncher.getResources();
+            int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+
+            // Specify the dimensions of the bitmap
+            if (info.minWidth >= info.minHeight) {
+                expectedWidth = cellWidth;
+                expectedHeight = mWidgetPreviewIconPaddedDimension;
+            } else {
+                // Note that in vertical widgets, we might not have enough space due to the text
+                // label, so be conservative and use the width as a height bound
+                expectedWidth = mWidgetPreviewIconPaddedDimension;
+                expectedHeight = cellWidth;
+            }
 
             Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
-            Resources resources = mLauncher.getResources();
-            Drawable background = resources.getDrawable(R.drawable.default_widget_preview);
-            renderDrawableToBitmap(background, preview, 0, 0, expectedWidth, expectedHeight, 1f,1f);
+            renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0, expectedWidth,
+                    expectedHeight, 1f,1f);
 
             // Draw the icon in the top left corner
             try {
@@ -544,13 +639,13 @@
                 if (info.icon > 0) icon = mPackageManager.getDrawable(packageName, info.icon, null);
                 if (icon == null) icon = resources.getDrawable(R.drawable.ic_launcher_application);
 
-                int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
-                int offset = iconSize / 4;
+                int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage);
                 renderDrawableToBitmap(icon, preview, offset, offset, iconSize, iconSize, 1f, 1f);
             } catch (Resources.NotFoundException e) {}
 
             newDrawable = new FastBitmapDrawable(preview);
             newDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
+            mWidgetPreviewCache.put(info, preview);
         }
         return newDrawable;
     }
@@ -579,16 +674,31 @@
         int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap
                 - ((mWidgetCountY - 1) * mWidgetCellHeightGap)) / mWidgetCountY);
         for (int i = 0; i < Math.min(numWidgetsPerPage, mWidgets.size() - offset); ++i) {
-            AppWidgetProviderInfo info = (AppWidgetProviderInfo) mWidgets.get(offset + i);
-            PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo(info, null, null);
-            final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
-                    info.minHeight, null);
-            FastBitmapDrawable preview = getWidgetPreview(info, cellSpans[0], cellSpans[1],
-                    cellWidth, cellHeight);
+            Object rawInfo = mWidgets.get(offset + i);
+            PendingAddItemInfo createItemInfo = null;
             PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate(
                     R.layout.apps_customize_widget, layout, false);
-            widget.applyFromAppWidgetProviderInfo(info, preview, -1, cellSpans, null, false);
-            widget.setTag(createItemInfo);
+            if (rawInfo instanceof AppWidgetProviderInfo) {
+                // Fill in the widget information
+                AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo;
+                createItemInfo = new PendingAddWidgetInfo(info, null, null);
+                final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
+                        info.minHeight, null);
+                FastBitmapDrawable preview = getWidgetPreview(info, cellSpans[0], cellSpans[1],
+                        cellWidth, cellHeight);
+                widget.applyFromAppWidgetProviderInfo(info, preview, -1, cellSpans, null, false);
+                widget.setTag(createItemInfo);
+            } else if (rawInfo instanceof ResolveInfo) {
+                // Fill in the shortcuts information
+                ResolveInfo info = (ResolveInfo) rawInfo;
+                createItemInfo = new PendingAddItemInfo();
+                createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+                createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
+                        info.activityInfo.name);
+                FastBitmapDrawable preview = getShortcutPreview(info, cellWidth, cellHeight);
+                widget.applyFromResolveInfo(mPackageManager, info, preview, null, false);
+                widget.setTag(createItemInfo);
+            }
             widget.setOnClickListener(this);
             widget.setOnLongClickListener(this);
             widget.setOnTouchListener(this);
@@ -717,8 +827,15 @@
     }
     @Override
     public void reset() {
-        setCurrentPage(0);
-        invalidatePageData();
+        if (mContentType != ContentType.Applications) {
+            // Reset to the first page of the Apps pane
+            AppsCustomizeTabHost tabs = (AppsCustomizeTabHost)
+                    mLauncher.findViewById(R.id.apps_customize_pane);
+            tabs.setCurrentTabByTag(tabs.getTabTagForContentType(ContentType.Applications));
+        } else {
+            setCurrentPage(0);
+            invalidatePageData();
+        }
     }
     @Override
     public void dumpState() {
@@ -727,13 +844,20 @@
         dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
     }
     private void dumpAppWidgetProviderInfoList(String tag, String label,
-            List<AppWidgetProviderInfo> list) {
+            List<Object> list) {
         Log.d(tag, label + " size=" + list.size());
-        for (AppWidgetProviderInfo info: list) {
-            Log.d(tag, "   label=\"" + info.label + "\" previewImage=" + info.previewImage
-                    + " resizeMode=" + info.resizeMode + " configure=" + info.configure
-                    + " initialLayout=" + info.initialLayout
-                    + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight);
+        for (Object i: list) {
+            if (i instanceof AppWidgetProviderInfo) {
+                AppWidgetProviderInfo info = (AppWidgetProviderInfo) i;
+                Log.d(tag, "   label=\"" + info.label + "\" previewImage=" + info.previewImage
+                        + " resizeMode=" + info.resizeMode + " configure=" + info.configure
+                        + " initialLayout=" + info.initialLayout
+                        + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight);
+            } else if (i instanceof ResolveInfo) {
+                ResolveInfo info = (ResolveInfo) i;
+                Log.d(tag, "   label=\"" + info.loadLabel(mPackageManager) + "\" icon="
+                        + info.icon);
+            }
         }
     }
     @Override
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 5820ce7..15920c3 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -96,6 +96,18 @@
     }
 
     /**
+     * Returns the tab tag for a given content type.
+     */
+    public String getTabTagForContentType(AppsCustomizePagedView.ContentType type) {
+        if (type == AppsCustomizePagedView.ContentType.Applications) {
+            return APPS_TAB_TAG;
+        } else if (type == AppsCustomizePagedView.ContentType.Widgets) {
+            return WIDGETS_TAB_TAG;
+        }
+        return APPS_TAB_TAG;
+    }
+
+    /**
      * Disable focus on anything under this view in the hierarchy if we are not visible.
      */
     @Override
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index a92e33e..72e0962 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1706,6 +1706,26 @@
             return sCollator.compare(labelA, labelB);
         }
     };
+    public static class WidgetAndShortcutNameComparator implements Comparator<Object> {
+        private PackageManager mPackageManager;
+        private HashMap<Object, String> mLabelCache;
+        WidgetAndShortcutNameComparator(PackageManager pm) {
+            mPackageManager = pm;
+            mLabelCache = new HashMap<Object, String>();
+        }
+        public final int compare(Object a, Object b) {
+            String labelA, labelB;
+            if (mLabelCache.containsKey(a)) labelA = mLabelCache.get(a);
+            else labelA = (a instanceof AppWidgetProviderInfo) ?
+                    ((AppWidgetProviderInfo) a).label :
+                    ((ResolveInfo) a).loadLabel(mPackageManager).toString();
+            if (mLabelCache.containsKey(b)) labelB = mLabelCache.get(b);
+            else labelB = (b instanceof AppWidgetProviderInfo) ?
+                    ((AppWidgetProviderInfo) b).label :
+                    ((ResolveInfo) b).loadLabel(mPackageManager).toString();
+            return sCollator.compare(labelA, labelB);
+        }
+    };
 
     public void dumpState() {
         Log.d(TAG, "mCallbacks=" + mCallbacks);
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 14ac9ae..88c5537 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -200,6 +200,26 @@
         }
     }
 
+    public void applyFromResolveInfo(PackageManager pm, ResolveInfo info,
+            FastBitmapDrawable preview, PagedViewIconCache cache, boolean createHolographicOutline){
+        final ImageView image = (ImageView) findViewById(R.id.widget_preview);
+        image.setImageDrawable(preview);
+        mPreviewImageView = image;
+        final TextView name = (TextView) findViewById(R.id.widget_name);
+        name.setText(info.loadLabel(pm));
+        name.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+        final TextView dims = (TextView) findViewById(R.id.widget_dims);
+        dims.setText(mContext.getString(R.string.widget_dims_format, 1, 1));
+        dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        if (createHolographicOutline) {
+            mIconCache = cache;
+            mIconCacheKey = new PagedViewIconCache.Key(info);
+            mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
+            mPreview = preview;
+        }
+    }
+
     public void applyFromWallpaperInfo(ResolveInfo info, PackageManager packageManager,
             FastBitmapDrawable preview, int maxWidth, PagedViewIconCache cache,
             boolean createHolographicOutline) {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 31ac11b..8a2009c 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -2396,7 +2396,9 @@
         if (source != this) {
             final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0],
                     (int) mDragViewVisualCenter[1] };
-            if ((mIsSmall || mIsInUnshrinkAnimation) && !mLauncher.isAllAppsVisible()) {
+            if (LauncherApplication.isScreenXLarge()
+                    && (mIsSmall || mIsInUnshrinkAnimation)
+                    && !mLauncher.isAllAppsVisible()) {
                 // When the workspace is shrunk and the drop comes from customize, don't actually
                 // add the item to the screen -- customize will do this itself
                 ((ItemInfo) dragInfo).dropPos = touchXY;
@@ -2898,7 +2900,7 @@
                 mLastDragYOffset = yOffset;
                 layout = findMatchingPageForDragOver(dragView, left, top, xOffset, yOffset);
 
-                if (layout != mDragTargetLayout) {
+                if (layout != null && layout != mDragTargetLayout) {
                     if (mDragTargetLayout != null) {
                         mDragTargetLayout.setIsDragOverlapping(false);
                         mSpringLoadedDragController.onDragExit();