Update widget picker two pane to support foldables

Bug: 301918659
Test: WidgetPickerImageTest
Flag: ACONFIG com.android.launcher3.enable_unfolded_two_pane_picker DEVELOPMENT
Change-Id: I5beecf4f8c46235f3e89c7bd8aed65fd292883ce
diff --git a/res/layout/widgets_two_pane_sheet_foldable.xml b/res/layout/widgets_two_pane_sheet_foldable.xml
new file mode 100644
index 0000000..93c0c70
--- /dev/null
+++ b/res/layout/widgets_two_pane_sheet_foldable.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.widget.picker.WidgetsTwoPaneSheet
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:theme="?attr/widgetsTheme">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:focusable="true"
+        android:importantForAccessibility="no">
+
+        <View
+            android:id="@+id/collapse_handle"
+            android:gravity="center_horizontal"
+            android:layout_width="@dimen/bottom_sheet_handle_width"
+            android:layout_height="@dimen/bottom_sheet_handle_height"
+            android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:background="@drawable/widget_picker_collapse_handle"/>
+
+        <TextView
+            android:id="@+id/title"
+            android:gravity="center_horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="24dp"
+            android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
+            android:text="@string/widget_button_text"
+            app:layout_constraintTop_toBottomOf="@id/collapse_handle"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:textColor="?attr/widgetPickerTitleColor"
+            android:textSize="24sp" />
+
+        <FrameLayout
+            android:id="@+id/recycler_view_container"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toBottomOf="@id/title"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintWidth_percent="0.33"
+            app:layout_constraintWidth_min="254dp"
+            app:layout_constraintWidth_max="395dp">
+            <TextView
+                android:id="@+id/fast_scroller_popup"
+                style="@style/FastScrollerPopup"
+                android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
+
+            <!-- Fast scroller popup -->
+            <com.android.launcher3.views.RecyclerViewFastScroller
+                android:id="@+id/fast_scroller"
+                android:layout_width="@dimen/fastscroll_width"
+                android:layout_height="match_parent"
+                android:layout_marginEnd="@dimen/fastscroll_end_margin" />
+
+            <com.android.launcher3.widget.picker.WidgetsRecyclerView
+                android:id="@+id/search_widgets_list_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:clipToPadding="false"
+                android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
+                android:visibility="gone" />
+        </FrameLayout>
+
+        <FrameLayout
+            android:id="@+id/right_pane_container"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginEnd="@dimen/widget_list_horizontal_margin_two_pane"
+            android:paddingTop="@dimen/widget_list_horizontal_margin_two_pane"
+            app:layout_constraintTop_toBottomOf="@id/title"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toEndOf="@id/recycler_view_container"
+            app:layout_constraintEnd_toEndOf="parent">
+            <TextView
+                android:id="@+id/no_widgets_text"
+                style="@style/PrimaryHeadline"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:gravity="center"
+                android:textSize="18sp"
+                android:visibility="gone"
+                tools:text="No widgets available" />
+            <ScrollView
+                android:id="@+id/right_pane_scroll_view"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:fillViewport="true">
+                <LinearLayout
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_vertical"
+                    android:clipToOutline="true"
+                    android:paddingBottom="36dp"
+                    android:background="@drawable/widgets_surface_background"
+                    android:id="@+id/right_pane">
+                    <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
+                        android:id="@+id/recommended_widget_table"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:paddingHorizontal=
+                            "@dimen/widget_list_horizontal_margin_two_pane"
+                        android:visibility="gone" />
+                </LinearLayout>
+            </ScrollView>
+        </FrameLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.launcher3.widget.picker.WidgetsTwoPaneSheet>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 025003b..242c439 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -176,6 +176,7 @@
     <dimen name="widget_tabs_horizontal_padding">16dp</dimen>
     <dimen name="widget_apps_tabs_vertical_padding">6dp</dimen>
     <dimen name="widget_picker_landscape_tablet_left_right_margin">117dp</dimen>
+    <dimen name="widget_picker_two_panels_left_right_margin">0dp</dimen>
 
     <dimen name="recommended_widgets_table_vertical_padding">8dp</dimen>
 
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 9855b20..9adc2ee 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.widget;
 
 import static com.android.app.animation.Interpolators.EMPHASIZED;
+import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
 import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_TIP_SEEN;
 
 import android.content.Context;
@@ -182,12 +183,8 @@
         DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
         int widthUsed;
         if (deviceProfile.isTablet) {
-            int margin = deviceProfile.allAppsLeftRightMargin;
-            if (deviceProfile.isLandscape && !deviceProfile.isTwoPanels) {
-                margin = getResources().getDimensionPixelSize(
-                        R.dimen.widget_picker_landscape_tablet_left_right_margin);
-            }
-            widthUsed = Math.max(2 * margin, 2 * (mInsets.left + mInsets.right));
+            widthUsed = Math.max(2 * getTabletMargin(deviceProfile),
+                    2 * (mInsets.left + mInsets.right));
         } else if (mInsets.bottom > 0) {
             widthUsed = mInsets.left + mInsets.right;
         } else {
@@ -202,6 +199,18 @@
                 MeasureSpec.getSize(heightMeasureSpec));
     }
 
+    private int getTabletMargin(DeviceProfile deviceProfile) {
+        if (deviceProfile.isLandscape && !deviceProfile.isTwoPanels) {
+            return getResources().getDimensionPixelSize(
+                    R.dimen.widget_picker_landscape_tablet_left_right_margin);
+        }
+        if (deviceProfile.isTwoPanels && enableUnfoldedTwoPanePicker()) {
+            return getResources().getDimensionPixelSize(
+                    R.dimen.widget_picker_two_panels_left_right_margin);
+        }
+        return deviceProfile.allAppsLeftRightMargin;
+    }
+
     @Override
     protected Interpolator getIdleInterpolator() {
         return mActivityContext.getDeviceProfile().isTablet
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index da90f17..583ef1a 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -17,6 +17,7 @@
 
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 
+import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
 import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_DIALOG_SEEN;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_SEARCHED;
@@ -62,7 +63,6 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.UserManagerState;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.pm.UserCache;
@@ -163,9 +163,7 @@
     private boolean mIsInSearchMode;
     private boolean mIsNoWidgetsViewNeeded;
     @Px private int mMaxSpanPerRow;
-    private final DeviceProfile mDeviceProfile;
-
-    private int mOrientation;
+    private DeviceProfile mDeviceProfile;
 
     protected TextView mNoWidgetsView;
     protected StickyHeaderLayout mSearchScrollView;
@@ -179,7 +177,6 @@
     public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mDeviceProfile = mActivityContext.getDeviceProfile();
-        mOrientation = context.getResources().getConfiguration().orientation;
         mUserCache = UserCache.INSTANCE.get(context);
         mHasWorkProfile = mUserCache.getUserProfiles()
                 .stream()
@@ -676,30 +673,31 @@
 
     /** Shows the {@link WidgetsFullSheet} on the launcher. */
     public static WidgetsFullSheet show(BaseActivity activity, boolean animate) {
-        boolean isTwoPane = activity.getDeviceProfile().isTablet
-                && activity.getDeviceProfile().isLandscape
-                && (!activity.getDeviceProfile().isTwoPanels
-                    || FeatureFlags.UNFOLDED_WIDGET_PICKER.get());
-
-        WidgetsFullSheet sheet;
-        if (isTwoPane) {
-            sheet = (WidgetsTwoPaneSheet) activity.getLayoutInflater().inflate(
-                    R.layout.widgets_two_pane_sheet,
-                    activity.getDragLayer(),
-                    false);
-        } else {
-            sheet = (WidgetsFullSheet) activity.getLayoutInflater().inflate(
-                    R.layout.widgets_full_sheet,
-                    activity.getDragLayer(),
-                    false);
-        }
-
+        WidgetsFullSheet sheet = (WidgetsFullSheet) activity.getLayoutInflater().inflate(
+                getWidgetSheetId(activity),
+                activity.getDragLayer(),
+                false);
         sheet.attachToContainer();
         sheet.mIsOpen = true;
         sheet.open(animate);
         return sheet;
     }
 
+    private static int getWidgetSheetId(BaseActivity activity) {
+        boolean isTwoPane = (activity.getDeviceProfile().isTablet
+                && activity.getDeviceProfile().isLandscape
+                && !activity.getDeviceProfile().isTwoPanels)
+                // Enables two pane picker for unfolded foldables if the flag is on.
+                || (activity.getDeviceProfile().isTwoPanels && enableUnfoldedTwoPanePicker());
+
+        if (isTwoPane && activity.getDeviceProfile().isTwoPanels) {
+            return R.layout.widgets_two_pane_sheet_foldable;
+        } else if (isTwoPane) {
+            return R.layout.widgets_two_pane_sheet;
+        }
+        return R.layout.widgets_full_sheet;
+    }
+
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         return isTouchOnScrollbar(ev) || super.onInterceptTouchEvent(ev);
@@ -790,17 +788,25 @@
         if (mIsInSearchMode) {
             mSearchBar.reset();
         }
+    }
 
-        // Checks the orientation of the screen
-        if (mOrientation != newConfig.orientation) {
-            mOrientation = newConfig.orientation;
-            if (mDeviceProfile.isTablet && !mDeviceProfile.isTwoPanels) {
-                handleClose(false);
-                show(BaseActivity.fromContext(getContext()), false);
-            } else {
-                reset();
-            }
+    @Override
+    public void onDeviceProfileChanged(DeviceProfile dp) {
+        if (mDeviceProfile.isLandscape != dp.isLandscape && dp.isTablet && !dp.isTwoPanels) {
+            handleClose(false);
+            show(BaseActivity.fromContext(getContext()), false);
+        } else {
+            reset();
         }
+
+        // When folding/unfolding the foldables, we need to switch between the regular widget picker
+        // and the two pane picker, so we rebuild the picker with the correct layout.
+        if (mDeviceProfile.isTwoPanels != dp.isTwoPanels && enableUnfoldedTwoPanePicker()) {
+            handleClose(false);
+            show(BaseActivity.fromContext(getContext()), false);
+        }
+
+        mDeviceProfile = dp;
     }
 
     @Override