Fix 3360951: Forced orientation change during widget conf

When a widget forces an orientation change in its configuration
activity, we fail to add it because Launcher is restarted in its
original orientation, and the loader is still running when the
intent result is received.

Change-Id: I6f4e328b56b6de18bf1d3fed4d747f290e5f3283
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index e2bddde..65082c3 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -26,7 +26,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.Activity;
@@ -283,6 +282,17 @@
 
     private BubbleTextView mWaitingForResume;
 
+    private static ArrayList<PendingAddArguments> sPendingAddList
+            = new ArrayList<PendingAddArguments>();
+
+    private static class PendingAddArguments {
+        int requestCode;
+        Intent intent;
+        int screen;
+        int cellX;
+        int cellY;
+    }
+
     private CustomizationType getCustomizeFilterForTabTag(String tag) {
         if (tag.equals(WIDGETS_TAG)) {
             return CustomizationType.WidgetCustomization;
@@ -701,8 +711,38 @@
         }
     }
 
+    private void completeAdd(PendingAddArguments args) {
+        switch (args.requestCode) {
+            case REQUEST_PICK_APPLICATION:
+                completeAddApplication(args.intent, args.screen, args.cellX, args.cellY);
+                break;
+            case REQUEST_PICK_SHORTCUT:
+                processShortcut(args.intent);
+                break;
+            case REQUEST_CREATE_SHORTCUT:
+                completeAddShortcut(args.intent, args.screen, args.cellX, args.cellY);
+                break;
+            case REQUEST_PICK_LIVE_FOLDER:
+                addLiveFolder(args.intent);
+                break;
+            case REQUEST_CREATE_LIVE_FOLDER:
+                completeAddLiveFolder(args.intent, args.screen, args.cellX, args.cellY);
+                break;
+            case REQUEST_PICK_APPWIDGET:
+                addAppWidgetFromPick(args.intent);
+                break;
+            case REQUEST_CREATE_APPWIDGET:
+                int appWidgetId = args.intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
+                completeAddAppWidget(appWidgetId, args.screen);
+                break;
+            case REQUEST_PICK_WALLPAPER:
+                // We just wanted the activity result here so we can clear mWaitingForResult
+                break;
+        }
+    }
+
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    protected void onActivityResult(final int requestCode, int resultCode, final Intent data) {
         mWaitingForResult = false;
 
         // The pattern used here is that a user PICKs a specific application,
@@ -712,33 +752,18 @@
         // launch over to the Music app to actually CREATE_SHORTCUT.
 
         if (resultCode == RESULT_OK && mAddScreen != -1) {
-            switch (requestCode) {
-                case REQUEST_PICK_APPLICATION:
-                    completeAddApplication(
-                            this, data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
-                    break;
-                case REQUEST_PICK_SHORTCUT:
-                    processShortcut(data);
-                    break;
-                case REQUEST_CREATE_SHORTCUT:
-                    completeAddShortcut(data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
-                    break;
-                case REQUEST_PICK_LIVE_FOLDER:
-                    addLiveFolder(data);
-                    break;
-                case REQUEST_CREATE_LIVE_FOLDER:
-                    completeAddLiveFolder(data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
-                    break;
-                case REQUEST_PICK_APPWIDGET:
-                    addAppWidgetFromPick(data);
-                    break;
-                case REQUEST_CREATE_APPWIDGET:
-                    int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-                    completeAddAppWidget(appWidgetId, mAddScreen);
-                    break;
-                case REQUEST_PICK_WALLPAPER:
-                    // We just wanted the activity result here so we can clear mWaitingForResult
-                    break;
+            final PendingAddArguments args = new PendingAddArguments();
+            args.requestCode = requestCode;
+            args.intent = data;
+            args.screen = mAddScreen;
+            args.cellX = mAddIntersectCellX;
+            args.cellY = mAddIntersectCellY;
+
+            // If the loader is still running, defer the add until it is done.
+            if (isWorkspaceLocked()) {
+                sPendingAddList.add(args);
+            } else {
+                completeAdd(args);
             }
         } else if ((requestCode == REQUEST_PICK_APPWIDGET ||
                 requestCode == REQUEST_CREATE_APPWIDGET) && resultCode == RESULT_CANCELED &&
@@ -1158,7 +1183,7 @@
      * @param data The intent describing the application.
      * @param cellInfo The position on screen where to create the shortcut.
      */
-    void completeAddApplication(Context context, Intent data, int screen,
+    void completeAddApplication(Intent data, int screen,
             int intersectCellX, int intersectCellY) {
         final int[] cellXY = mTmpAddItemCellCoordinates;
         final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
@@ -1168,8 +1193,7 @@
             return;
         }
 
-        final ShortcutInfo info = mModel.getShortcutInfo(context.getPackageManager(),
-                data, context);
+        final ShortcutInfo info = mModel.getShortcutInfo(getPackageManager(), data, this);
 
         if (info != null) {
             info.setActivity(data.getComponent(), Intent.FLAG_ACTIVITY_NEW_TASK |
@@ -3574,6 +3598,13 @@
         }
 
         mWorkspaceLoading = false;
+
+        // If we received the result of any pending adds while the loader was running (e.g. the
+        // widget configuration forced an orientation change), process them now.
+        for (int i = 0; i < sPendingAddList.size(); i++) {
+            completeAdd(sPendingAddList.get(i));
+        }
+        sPendingAddList.clear();
     }
 
     /**