pin-shortcut: Implements the actual pinning functionality

This cl implements the onClick function for the pin shortcut, so
that clicking on it will actually pin an app/item to the taskbar.

Bug: 375648361
Test: Manual, Recording uploaded to buganizer
Flag: com.android.launcher3.enable_pinning_app_with_context_menu
Change-Id: Ia0e9464ceb99efd47a9fefd8136b930f908599cb
diff --git a/quickstep/src/com/android/launcher3/taskbar/PinToTaskbarShortcut.kt b/quickstep/src/com/android/launcher3/taskbar/PinToTaskbarShortcut.kt
index b9a211d..da6932f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/PinToTaskbarShortcut.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/PinToTaskbarShortcut.kt
@@ -17,9 +17,15 @@
 package com.android.launcher3.taskbar
 
 import android.content.Context
+import android.util.SparseArray
 import android.view.View
+import com.android.launcher3.DeviceProfile
+import com.android.launcher3.LauncherAppState
+import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
 import com.android.launcher3.R
+import com.android.launcher3.model.BgDataModel
 import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.WorkspaceItemInfo
 import com.android.launcher3.popup.SystemShortcut
 import com.android.launcher3.views.ActivityContext
 
@@ -27,16 +33,59 @@
  * A single menu item shortcut to allow users to pin an item to the taskbar and unpin an item from
  * the taskbar.
  */
-class PinToTaskbarShortcut<T>(target: T, itemInfo: ItemInfo?, originalView: View, isPin: Boolean) :
+class PinToTaskbarShortcut<T>(
+    target: T,
+    itemInfo: ItemInfo?,
+    originalView: View,
+    private val mIsPin: Boolean,
+    private val mPinnedInfoList: SparseArray<ItemInfo?>,
+) :
     SystemShortcut<T>(
-        if (isPin) R.drawable.ic_pin else R.drawable.ic_unpin,
-        if (isPin) R.string.pin_to_taskbar else R.string.unpin_from_taskbar,
+        if (mIsPin) R.drawable.ic_pin else R.drawable.ic_unpin,
+        if (mIsPin) R.string.pin_to_taskbar else R.string.unpin_from_taskbar,
         target,
         itemInfo,
         originalView,
     ) where T : Context?, T : ActivityContext? {
 
     override fun onClick(v: View?) {
-        // TODO(b/375648361): Pin/Unpin the item here.
+        dismissTaskMenuView()
+        // Create a placeholder callbacks for the writer to notify other launcher model callbacks
+        // after update.
+        val callbacks: BgDataModel.Callbacks = object : BgDataModel.Callbacks {}
+
+        val writer =
+            LauncherAppState.getInstance(mOriginalView.context)
+                .model
+                .getWriter(true, mTarget!!.cellPosMapper, callbacks)
+
+        if (!mIsPin) {
+            writer.deleteItemFromDatabase(mItemInfo, "item unpinned through long-press menu")
+            return
+        }
+
+        val newInfo =
+            if (mItemInfo is com.android.launcher3.model.data.AppInfo) {
+                mItemInfo.makeWorkspaceItem(mOriginalView.context)
+            } else if (mItemInfo is WorkspaceItemInfo) {
+                mItemInfo.clone()
+            } else {
+                return
+            }
+
+        val dp: DeviceProfile = mTarget.deviceProfile
+        var targetIdx = -1
+
+        for (i in 0 until dp.numShownHotseatIcons) {
+            if (mPinnedInfoList[i] == null) {
+                targetIdx = i
+                break
+            }
+        }
+
+        val cellX = if (dp.isVerticalBarLayout()) 0 else targetIdx
+        val cellY = if (dp.isVerticalBarLayout()) (dp.numShownHotseatIcons - (targetIdx + 1)) else 0
+
+        writer.addItemToDatabase(newInfo, CONTAINER_HOTSEAT, mItemInfo.screenId, cellX, cellY)
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 80944bb..33a78d5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -250,11 +250,13 @@
             return null;
         }
         if (itemInfo.container == CONTAINER_HOTSEAT) {
-            return new PinToTaskbarShortcut<>(target, itemInfo, originalView, false);
+            return new PinToTaskbarShortcut<>(target, itemInfo, originalView, false,
+                    mHotseatInfosList);
         }
         if (mHotseatInfosList.size()
                 < mContext.getTaskbarSpecsEvaluator().getNumShownHotseatIcons()) {
-            return new PinToTaskbarShortcut<>(target, itemInfo, originalView, true);
+            return new PinToTaskbarShortcut<>(target, itemInfo, originalView, true,
+                    mHotseatInfosList);
         }
 
         return null;