Merge "Add WidgetsAndMore bottom sheet" into ub-launcher3-dorval
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index 17dec37..909a429 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -79,6 +79,7 @@
   PREDICTION = 7;
   SEARCHRESULT = 8;
   DEEPSHORTCUTS = 9;
+  PINITEM = 10;    // confirmation screen
 }
 
 // Used to define what type of control a Target would represent.
@@ -124,6 +125,10 @@
   enum Command {
     HOME_INTENT = 0;
     BACK = 1;
+    ENTRY = 2;    // Indicates entry to one of Launcher container type target
+                  // not using the HOME_INTENT
+    CANCEL = 3;   // Indicates that a confirmation screen was cancelled
+    CONFIRM = 4;  // Indicates thata confirmation screen was accepted
   }
   optional Type type = 1;
   optional Touch touch = 2;
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 79277b6..99ff581 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -53,9 +53,9 @@
     <!-- Accessibility spoken message format for the dimensions of a widget in the drawer -->
     <string name="widget_accessible_dims_format">%1$d wide by %2$d high</string>
     <!-- Message to tell the user to press and hold a widget/icon to add it  -->
-    <string name="add_item_request_drag_hint">Touch &amp; hold to place on home screen</string>
+    <string name="add_item_request_drag_hint">Touch &amp; hold to place manually</string>
     <!-- Button label to automatically add icon on home screen [CHAR_LIMIT=50] -->
-    <string name="place_automatically">Place automatically</string>
+    <string name="place_automatically">Add automatically</string>
 
     <!-- All Apps -->
     <!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1ad97cc..1db9f9a 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;
@@ -443,6 +442,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();
@@ -1768,15 +1772,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);
@@ -4098,22 +4095,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/compat/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
index ebe95d6..4a55e8c 100644
--- a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
+++ b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
@@ -33,6 +33,7 @@
 import android.widget.Toast;
 
 import com.android.launcher3.IconCache;
+import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
 
@@ -61,6 +62,10 @@
         return mUser;
     }
 
+    public int getItemType() {
+        return LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+    }
+
     public abstract CharSequence getLabel();
 
     public abstract Drawable getFullResIcon(IconCache cache);
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index c2a4820..09592a8 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -16,6 +16,11 @@
 
 package com.android.launcher3.dragndrop;
 
+import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
+import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
+
 import android.annotation.TargetApi;
 import android.app.ActivityOptions;
 import android.appwidget.AppWidgetHost;
@@ -23,6 +28,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;
@@ -31,7 +37,9 @@
 import android.os.Bundle;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.View.*;
+import android.view.View.DragShadowBuilder;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.InstallShortcutReceiver;
@@ -40,10 +48,14 @@
 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;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
 import com.android.launcher3.widget.WidgetImageView;
@@ -102,6 +114,12 @@
 
         mWidgetCell.setOnTouchListener(this);
         mWidgetCell.setOnLongClickListener(this);
+
+        // savedInstanceState is null when the activity is created the first time (i.e., avoids
+        // duplicate logging during rotation)
+        if (savedInstanceState == null) {
+            logCommand(Action.Command.ENTRY);
+        }
     }
 
     @Override
@@ -132,6 +150,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());
 
@@ -154,7 +182,10 @@
     }
 
     private void setupShortcut() {
-        WidgetItem item = new WidgetItem(new PinShortcutRequestActivityInfo(mRequest, this));
+        PinShortcutRequestActivityInfo shortcutInfo =
+                new PinShortcutRequestActivityInfo(mRequest, this);
+        WidgetItem item = new WidgetItem(shortcutInfo);
+        mWidgetCell.getWidgetView().setTag(new PendingAddShortcutInfo(shortcutInfo));
         mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache());
         mWidgetCell.ensurePreview();
     }
@@ -177,6 +208,7 @@
         mWidgetOptions = WidgetHostViewLoader.getDefaultOptionsForWidget(this, mPendingWidgetInfo);
 
         WidgetItem item = new WidgetItem(widgetInfo, getPackageManager(), mIdp);
+        mWidgetCell.getWidgetView().setTag(mPendingWidgetInfo);
         mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache());
         mWidgetCell.ensurePreview();
         return true;
@@ -186,6 +218,7 @@
      * Called when the cancel button is clicked.
      */
     public void onCancelClick(View v) {
+        logCommand(Action.Command.CANCEL);
         finish();
     }
 
@@ -196,6 +229,7 @@
         if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
             InstallShortcutReceiver.queueShortcut(
                     new ShortcutInfoCompat(mRequest.getShortcutInfo()), this);
+            logCommand(Action.Command.CONFIRM);
             mRequest.accept();
             finish();
             return;
@@ -223,10 +257,17 @@
         InstallShortcutReceiver.queueWidget(mRequest.getAppWidgetProviderInfo(this), widgetId, this);
         mWidgetOptions.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
         mRequest.accept(mWidgetOptions);
+        logCommand(Action.Command.CONFIRM);
         finish();
     }
 
     @Override
+    public void onBackPressed() {
+        logCommand(Action.Command.BACK);
+        super.onBackPressed();
+    }
+
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == REQUEST_BIND_APPWIDGET) {
             int widgetId = data != null
@@ -256,4 +297,11 @@
         mPendingBindWidgetId = savedInstanceState
                 .getInt(STATE_EXTRA_WIDGET_ID, mPendingBindWidgetId);
     }
+
+    private void logCommand(int command) {
+        getUserEventDispatcher().dispatchUserEvent(newLauncherEvent(
+                newCommandAction(command),
+                newItemTarget(mWidgetCell.getWidgetView()),
+                newContainerTarget(ContainerType.PINITEM)), null);
+    }
 }
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index fd252a2..4b402f4 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;
@@ -42,6 +43,7 @@
 import com.android.launcher3.compat.PinItemRequestCompat;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.PendingItemDragHelper;
@@ -240,10 +242,17 @@
     @Override
     public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
             LauncherLogProto.Target targetParent) {
-        // TODO: We should probably log something
+        targetParent.containerType = ContainerType.PINITEM;
     }
 
     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 +276,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) {
diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
index 6a8c19f..26460d7 100644
--- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
+++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
@@ -27,6 +27,7 @@
 
 import com.android.launcher3.IconCache;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.PinItemRequestCompat;
 import com.android.launcher3.compat.ShortcutConfigActivityInfo;
@@ -55,6 +56,11 @@
     }
 
     @Override
+    public int getItemType() {
+        return LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+    }
+
+    @Override
     public CharSequence getLabel() {
         return mInfo.getShortLabel();
     }
diff --git a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
index 7eeb8bf..e8f13a1 100644
--- a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
@@ -32,6 +32,6 @@
         this.activityInfo = activityInfo;
         componentName = activityInfo.getComponent();
         user = activityInfo.getUser();
-        itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+        itemType = activityInfo.getItemType();
     }
 }