Fixing bug where widget could get added to drag layer and not removed (issue 6282757)

Change-Id: Ibc32b48f12e1c37267e140e82e1620bcb407963c
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 2518c6c..f2c50a4 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -49,7 +49,6 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
@@ -171,7 +170,7 @@
         AllAppsView, View.OnClickListener, View.OnKeyListener, DragSource,
         PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener,
         LauncherTransitionable {
-    static final String LOG_TAG = "AppsCustomizePagedView";
+    static final String TAG = "AppsCustomizePagedView";
 
     /**
      * The different content types that this paged view can show.
@@ -490,7 +489,7 @@
                     mWidgets.add(widget);
                 }
             } else {
-                Log.e(LOG_TAG, "Widget " + widget.provider + " has invalid dimensions (" +
+                Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" +
                         widget.minWidth + ", " + widget.minHeight + ")");
             }
         }
@@ -612,32 +611,43 @@
     public void onShortPress(View v) {
         // We are anticipating a long press, and we use this time to load bind and instantiate
         // the widget. This will need to be cleaned up if it turns out no long press occurs.
+        if (mCreateWidgetInfo != null) {
+            // Just in case the cleanup process wasn't properly executed. This shouldn't happen.
+            cleanupWidgetPreloading(false);
+        }
         mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag());
         preloadWidget(mCreateWidgetInfo);
     }
 
-    private void cleanupWidgetPreloading() {
-        PendingAddWidgetInfo info = mCreateWidgetInfo;
-        mCreateWidgetInfo = null;
-        if (mWidgetCleanupState >= 0 && mWidgetLoadingId != -1) {
-            mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
-        }
-        if (mWidgetCleanupState == WIDGET_BOUND) {
-            removeCallbacks(mInflateWidgetRunnable);
-        } else if (mWidgetCleanupState == WIDGET_INFLATED) {
-            AppWidgetHostView widget = info.boundWidget;
-            int widgetId = widget.getAppWidgetId();
-            mLauncher.getAppWidgetHost().deleteAppWidgetId(widgetId);
-            mLauncher.getDragLayer().removeView(widget);
+    private void cleanupWidgetPreloading(boolean widgetWasAdded) {
+        if (!widgetWasAdded) {
+            // If the widget was not added, we may need to do further cleanup.
+            PendingAddWidgetInfo info = mCreateWidgetInfo;
+            mCreateWidgetInfo = null;
+            // First step was to allocate a widget id, revert that.
+            if ((mWidgetCleanupState == WIDGET_BOUND || mWidgetCleanupState == WIDGET_INFLATED) &&
+                    mWidgetLoadingId != -1) {
+                mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
+            }
+            if (mWidgetCleanupState == WIDGET_BOUND) {
+                // We never actually inflated the widget, so remove the callback to do so.
+                removeCallbacks(mInflateWidgetRunnable);
+            } else if (mWidgetCleanupState == WIDGET_INFLATED) {
+                // The widget was inflated and added to the DragLayer -- remove it.
+                AppWidgetHostView widget = info.boundWidget;
+                mLauncher.getDragLayer().removeView(widget);
+            }
         }
         mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
         mWidgetLoadingId = -1;
+        mCreateWidgetInfo = null;
+        PagedViewWidget.resetShortPressTarget();
     }
 
     @Override
     public void cleanUpShortPress(View v) {
         if (!mDraggingWidget) {
-            cleanupWidgetPreloading();
+            cleanupWidgetPreloading(false);
         }
     }
 
@@ -829,8 +839,8 @@
             }
 
             d.deferDragViewCleanupPostAnimation = false;
-            cleanupWidgetPreloading();
         }
+        cleanupWidgetPreloading(success);
         mDraggingWidget = false;
     }
 
@@ -838,7 +848,7 @@
     public void onFlingToDeleteCompleted() {
         // We just dismiss the drag when we fling, so cleanup here
         endDragging(null, true, true);
-        cleanupWidgetPreloading();
+        cleanupWidgetPreloading(false);
         mDraggingWidget = false;
     }
 
@@ -1130,7 +1140,7 @@
         if (previewImage != 0) {
             drawable = mPackageManager.getDrawable(packageName, previewImage, null);
             if (drawable == null) {
-                Log.w(LOG_TAG, "Can't load widget preview drawable 0x" +
+                Log.w(TAG, "Can't load widget preview drawable 0x" +
                         Integer.toHexString(previewImage) + " for provider: " + provider);
             }
         }
@@ -1620,8 +1630,8 @@
     @Override
     public void dumpState() {
         // TODO: Dump information related to current list of Applications, Widgets, etc.
-        ApplicationInfo.dumpApplicationInfoList(LOG_TAG, "mApps", mApps);
-        dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
+        ApplicationInfo.dumpApplicationInfoList(TAG, "mApps", mApps);
+        dumpAppWidgetProviderInfoList(TAG, "mWidgets", mWidgets);
     }
 
     private void dumpAppWidgetProviderInfoList(String tag, String label,
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 774bf1f..f78aa4c 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -42,6 +42,7 @@
     CheckForShortPress mPendingCheckForShortPress = null;
     ShortPressListener mShortPressListener = null;
     boolean mShortPressTriggered = false;
+    static PagedViewWidget sShortpressTarget = null;
 
     public PagedViewWidget(Context context) {
         this(context, null);
@@ -141,13 +142,16 @@
     class CheckForShortPress implements Runnable {
         public void run() {
             if (mShortPressListener != null) {
+                if (sShortpressTarget != null) return;
                 mShortPressListener.onShortPress(PagedViewWidget.this);
             }
+            sShortpressTarget = PagedViewWidget.this;
             mShortPressTriggered = true;
         }
     }
 
     private void checkForShortPress() {
+        if (sShortpressTarget != null) return;
         if (mPendingCheckForShortPress == null) {
             mPendingCheckForShortPress = new CheckForShortPress();
         }
@@ -173,6 +177,10 @@
         }
     }
 
+    static void resetShortPressTarget() {
+        sShortpressTarget = null;
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         super.onTouchEvent(event);
@@ -190,6 +198,7 @@
             case MotionEvent.ACTION_MOVE:
                 break;
         }
+
         // We eat up the touch events here, since the PagedView (which uses the same swiping
         // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when
         // the user is scrolling between pages.  This means that if the pages themselves don't