Fixing multiwindow drag operation during with rotation.

> Finishing activity when rotation preference change. This ensures that
  any prefenrece change is immediately applied instead of waiting for resume
  as the new activity is always started with proper setting.
> Clearing task when starting drag in landscape mode. This ensures that a new
  activity instance is started in this case, which overrides previous locked
  rotation by launcher activity.
> Handling drag request in onCreate and enabling rotation based on it.
> Clearing any request from the launcher intent once the drag operation
  is complete

Bug: 36226746
Change-Id: I69f56c13827c25f3e1bc84935cb2acc59b6bd349
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2dba83d..3be6225 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -49,7 +49,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.Parcelable;
 import android.os.Process;
 import android.os.StrictMode;
 import android.os.SystemClock;
@@ -444,6 +443,11 @@
             mSharedPrefs.registerOnSharedPreferenceChangeListener(mRotationPrefChangeHandler);
         }
 
+        if (PinItemDragListener.handleDragRequest(this, getIntent())) {
+            // Temporarily enable the rotation
+            mRotationEnabled = true;
+        }
+
         // On large interfaces, or on devices that a user has specifically enabled screen rotation,
         // we want the screen to auto-rotate based on the current orientation
         setOrientation();
@@ -1769,15 +1773,8 @@
             if (mLauncherCallbacks != null) {
                 mLauncherCallbacks.onHomeIntent();
             }
-
-            Parcelable dragExtra = intent
-                    .getParcelableExtra(PinItemDragListener.EXTRA_PIN_ITEM_DRAG_LISTENER);
-            if (dragExtra instanceof PinItemDragListener) {
-                PinItemDragListener dragListener = (PinItemDragListener) dragExtra;
-                dragListener.setLauncher(this);
-                mDragLayer.setOnDragListener(dragListener);
-            }
         }
+        PinItemDragListener.handleDragRequest(this, intent);
 
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onNewIntent(intent);
@@ -4096,22 +4093,16 @@
         return ((Launcher) ((ContextWrapper) context).getBaseContext());
     }
 
-    private class RotationPrefChangeHandler implements OnSharedPreferenceChangeListener, Runnable {
+    private class RotationPrefChangeHandler implements OnSharedPreferenceChangeListener {
 
         @Override
         public void onSharedPreferenceChanged(
                 SharedPreferences sharedPreferences, String key) {
             if (Utilities.ALLOW_ROTATION_PREFERENCE_KEY.equals(key)) {
-                mRotationEnabled = Utilities.isAllowRotationPrefEnabled(getApplicationContext());
-                if (!waitUntilResume(this, true)) {
-                    run();
-                }
+                // Finish this instance of the activity. When the activity is recreated,
+                // it will initialize the rotation preference again.
+                finish();
             }
         }
-
-        @Override
-        public void run() {
-            setOrientation();
-        }
     }
 }
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index c2a4820..629f78a 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -23,6 +23,7 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -40,6 +41,7 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.PinItemRequestCompat;
 import com.android.launcher3.model.WidgetItem;
@@ -132,6 +134,16 @@
                 .setPackage(getPackageName())
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                 .putExtra(PinItemDragListener.EXTRA_PIN_ITEM_DRAG_LISTENER, listener);
+
+        if (!getResources().getBoolean(R.bool.allow_rotation) &&
+                !Utilities.isAllowRotationPrefEnabled(this) &&
+                (getResources().getConfiguration().orientation ==
+                        Configuration.ORIENTATION_LANDSCAPE && !isInMultiWindowMode())) {
+            // If we are starting the drag in landscape even though home is locked in portrait,
+            // restart the home activity to temporarily allow rotation.
+            homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        }
+
         startActivity(homeIntent,
                 ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle());
 
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index fd252a2..e714778 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -18,6 +18,7 @@
 
 import android.appwidget.AppWidgetManager;
 import android.content.ClipDescription;
+import android.content.Intent;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -244,6 +245,13 @@
     }
 
     private void postCleanup() {
+        if (mLauncher != null) {
+            // Remove any drag params from the launcher intent since the drag operation is complete.
+            Intent newIntent = new Intent(mLauncher.getIntent());
+            newIntent.removeExtra(EXTRA_PIN_ITEM_DRAG_LISTENER);
+            mLauncher.setIntent(newIntent);
+        }
+
         new Handler(Looper.getMainLooper()).post(new Runnable() {
             @Override
             public void run() {
@@ -267,6 +275,21 @@
         return null;
     }
 
+    public static boolean handleDragRequest(Launcher launcher, Intent intent) {
+        if (intent == null || !Intent.ACTION_MAIN.equals(intent.getAction())) {
+            return false;
+        }
+        Parcelable dragExtra = intent.getParcelableExtra(EXTRA_PIN_ITEM_DRAG_LISTENER);
+        if (dragExtra instanceof PinItemDragListener) {
+            PinItemDragListener dragListener = (PinItemDragListener) dragExtra;
+            dragListener.setLauncher(launcher);
+
+            launcher.getDragLayer().setOnDragListener(dragListener);
+            return true;
+        }
+        return false;
+    }
+
     public static final Parcelable.Creator<PinItemDragListener> CREATOR =
             new Parcelable.Creator<PinItemDragListener>() {
                 public PinItemDragListener createFromParcel(Parcel source) {