Extract common codes for personal / work profile tabs

These codes can be reused in the FullWidgetsSheet which we will be
adding tabs for personal / work profile.

Test: Set up work profile and then switch person / work profile tabs
      in the AllAppsContainerView.

Bug: 179797520

Change-Id: Ib7eb1190e1384a664cbe3e34411c9362f1f6db03
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 0041c9a..8ed16c7 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -40,35 +40,7 @@
 
         <include layout="@layout/floating_header_content" />
 
-        <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
-            android:id="@+id/tabs"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/all_apps_header_tab_height"
-            android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
-            android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
-            android:orientation="horizontal"
-            style="@style/TextHeadline">
-
-            <Button
-                android:id="@+id/tab_personal"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:background="?android:attr/selectableItemBackground"
-                android:text="@string/all_apps_personal_tab"
-                android:textColor="@color/all_apps_tab_text"
-                android:textSize="14sp" />
-
-            <Button
-                android:id="@+id/tab_work"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:background="?android:attr/selectableItemBackground"
-                android:text="@string/all_apps_work_tab"
-                android:textColor="@color/all_apps_tab_text"
-                android:textSize="14sp" />
-        </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
+        <include layout="@layout/personal_work_tabs" />
     </com.android.launcher3.allapps.FloatingHeaderView>
 
     <include
diff --git a/res/layout/personal_work_tabs.xml b/res/layout/personal_work_tabs.xml
new file mode 100644
index 0000000..8f29997
--- /dev/null
+++ b/res/layout/personal_work_tabs.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.workprofile.PersonalWorkSlidingTabStrip
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/tabs"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/all_apps_header_tab_height"
+    android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
+    android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
+    android:orientation="horizontal"
+    style="@style/TextHeadline">
+
+    <Button
+        android:id="@+id/tab_personal"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:text="@string/all_apps_personal_tab"
+        android:textColor="@color/all_apps_tab_text"
+        android:textSize="14sp" />
+
+    <Button
+        android:id="@+id/tab_work"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:text="@string/all_apps_work_tab"
+        android:textColor="@color/all_apps_tab_text"
+        android:textSize="14sp" />
+</com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
\ No newline at end of file
diff --git a/res/layout/secondary_launcher.xml b/res/layout/secondary_launcher.xml
index fdf4446..e3c60ec 100644
--- a/res/layout/secondary_launcher.xml
+++ b/res/layout/secondary_launcher.xml
@@ -67,7 +67,7 @@
             android:paddingTop="@dimen/all_apps_header_top_padding"
             android:orientation="vertical" >
 
-            <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
+            <com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
                 android:id="@+id/tabs"
                 android:layout_width="match_parent"
                 android:layout_height="@dimen/all_apps_header_tab_height"
@@ -97,7 +97,7 @@
                     android:textAllCaps="true"
                     android:textColor="@color/all_apps_tab_text"
                     android:textSize="14sp" />
-            </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
+            </com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
         </com.android.launcher3.allapps.FloatingHeaderView>
 
         <com.android.launcher3.allapps.search.AppsSearchContainerLayout
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 505e6d8..746bfba 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -67,12 +67,13 @@
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 import com.android.launcher3.views.SpringRelativeLayout;
+import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
 
 /**
  * The all apps view container.
  */
 public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
-        Insettable, OnDeviceProfileChangeListener {
+        Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
 
     private static final float FLING_VELOCITY_MULTIPLIER = 135f;
     // Starts the springs after at least 55% of the animation has passed.
@@ -434,7 +435,7 @@
                     .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.MAIN));
             findViewById(R.id.tab_work)
                     .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
-            onTabChanged(mViewPager.getNextPage());
+            onActivePageChanged(mViewPager.getNextPage());
         } else {
             mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
             mAH[AdapterHolder.WORK].recyclerView = null;
@@ -483,7 +484,7 @@
         if (showTabs) {
             mViewPager = (AllAppsPagedView) newView;
             mViewPager.initParentViews(this);
-            mViewPager.getPageIndicator().setContainerView(this);
+            mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
         } else {
             mViewPager = null;
         }
@@ -493,14 +494,15 @@
         return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
     }
 
-    public void onTabChanged(int pos) {
-        mHeader.setMainActive(pos == 0);
-        if (mAH[pos].recyclerView != null) {
-            mAH[pos].recyclerView.bindFastScrollbar();
+    @Override
+    public void onActivePageChanged(int currentActivePage) {
+        mHeader.setMainActive(currentActivePage == 0);
+        if (mAH[currentActivePage].recyclerView != null) {
+            mAH[currentActivePage].recyclerView.bindFastScrollbar();
         }
         reset(true /* animate */);
         if (mWorkModeSwitch != null) {
-            mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK
+            mWorkModeSwitch.setWorkTabVisible(currentActivePage == AdapterHolder.WORK
                     && mAllAppsStore.hasModelFlag(
                     FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION));
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsPagedView.java b/src/com/android/launcher3/allapps/AllAppsPagedView.java
index e2550f5..647402b 100644
--- a/src/com/android/launcher3/allapps/AllAppsPagedView.java
+++ b/src/com/android/launcher3/allapps/AllAppsPagedView.java
@@ -17,17 +17,17 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.view.MotionEvent;
 
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.workprofile.PersonalWorkPagedView;
 
-public class AllAppsPagedView extends PagedView<PersonalWorkSlidingTabStrip> {
-
-    static final float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6;
-    static final float MAX_SWIPE_ANGLE = (float) Math.PI / 3;
-    static final float TOUCH_SLOP_DAMPING_FACTOR = 4;
+/**
+ *  A {@link PagedView} for showing different views for the personal and work profile respectively
+ *  in the {@link AllAppsContainerView}.
+ */
+public class AllAppsPagedView extends PersonalWorkPagedView {
 
     public AllAppsPagedView(Context context) {
         this(context, null);
@@ -44,52 +44,4 @@
                         R.dimen.all_apps_header_top_padding);
         setPadding(0, topPadding, 0, 0);
     }
-
-    @Override
-    protected String getCurrentPageDescription() {
-        // Not necessary, tab-bar already has two tabs with their own descriptions.
-        return "";
-    }
-
-    @Override
-    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
-        super.onScrollChanged(l, t, oldl, oldt);
-        mPageIndicator.setScroll(l, mMaxScroll);
-    }
-
-    @Override
-    protected void determineScrollingStart(MotionEvent ev) {
-        float absDeltaX = Math.abs(ev.getX() - getDownMotionX());
-        float absDeltaY = Math.abs(ev.getY() - getDownMotionY());
-
-        if (Float.compare(absDeltaX, 0f) == 0) return;
-
-        float slope = absDeltaY / absDeltaX;
-        float theta = (float) Math.atan(slope);
-
-        if (absDeltaX > mTouchSlop || absDeltaY > mTouchSlop) {
-            cancelCurrentPageLongPress();
-        }
-
-        if (theta > MAX_SWIPE_ANGLE) {
-            return;
-        } else if (theta > START_DAMPING_TOUCH_SLOP_ANGLE) {
-            theta -= START_DAMPING_TOUCH_SLOP_ANGLE;
-            float extraRatio = (float)
-                    Math.sqrt((theta / (MAX_SWIPE_ANGLE - START_DAMPING_TOUCH_SLOP_ANGLE)));
-            super.determineScrollingStart(ev, 1 + TOUCH_SLOP_DAMPING_FACTOR * extraRatio);
-        } else {
-            super.determineScrollingStart(ev);
-        }
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
-    @Override
-    protected boolean canScroll(float absVScroll, float absHScroll) {
-        return (absHScroll > absVScroll) && super.canScroll(absVScroll, absHScroll);
-    }
 }
diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
index 4876298..bc2e66c 100644
--- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
@@ -87,17 +87,18 @@
     }
 
     @Override
-    public void onTabChanged(int pos) {
-        super.onTabChanged(pos);
+    public void onActivePageChanged(int currentActivePage) {
+        super.onActivePageChanged(currentActivePage);
         if (mUsingTabs) {
             // Log tab switches only when the launcher is in AllApps state
             if (mLauncher.getStateManager().getCurrentStableState() == LauncherState.ALL_APPS) {
                 mLauncher.getStatsLogManager().logger()
-                        .log(pos == AdapterHolder.WORK ? LAUNCHER_ALLAPPS_SWITCHED_TO_WORK_TAB
+                        .log(currentActivePage == AdapterHolder.WORK
+                                ? LAUNCHER_ALLAPPS_SWITCHED_TO_WORK_TAB
                                 : LAUNCHER_ALLAPPS_SWITCHED_TO_MAIN_TAB);
             }
 
-            if (pos == AdapterHolder.WORK) {
+            if (currentActivePage == AdapterHolder.WORK) {
                 WorkEduView.showWorkEduIfNeeded(mLauncher);
             } else {
                 mWorkTabListener = WorkEduView.showEduFlowIfNeeded(mLauncher, mWorkTabListener);
diff --git a/src/com/android/launcher3/workprofile/PersonalWorkPagedView.java b/src/com/android/launcher3/workprofile/PersonalWorkPagedView.java
new file mode 100644
index 0000000..8b05a0d
--- /dev/null
+++ b/src/com/android/launcher3/workprofile/PersonalWorkPagedView.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+package com.android.launcher3.workprofile;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import com.android.launcher3.PagedView;
+
+/**
+ *  A {@link PagedView} for showing different views for the personal and work profile respectively.
+ */
+public class PersonalWorkPagedView extends PagedView<PersonalWorkSlidingTabStrip> {
+
+    static final float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6;
+    static final float MAX_SWIPE_ANGLE = (float) Math.PI / 3;
+    static final float TOUCH_SLOP_DAMPING_FACTOR = 4;
+
+    public PersonalWorkPagedView(Context context) {
+        this(context, null);
+    }
+
+    public PersonalWorkPagedView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PersonalWorkPagedView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected String getCurrentPageDescription() {
+        // Not necessary, tab-bar already has two tabs with their own descriptions.
+        return "";
+    }
+
+    @Override
+    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+        super.onScrollChanged(l, t, oldl, oldt);
+        mPageIndicator.setScroll(l, mMaxScroll);
+    }
+
+    @Override
+    protected void determineScrollingStart(MotionEvent ev) {
+        float absDeltaX = Math.abs(ev.getX() - getDownMotionX());
+        float absDeltaY = Math.abs(ev.getY() - getDownMotionY());
+
+        if (Float.compare(absDeltaX, 0f) == 0) return;
+
+        float slope = absDeltaY / absDeltaX;
+        float theta = (float) Math.atan(slope);
+
+        if (absDeltaX > mTouchSlop || absDeltaY > mTouchSlop) {
+            cancelCurrentPageLongPress();
+        }
+
+        if (theta > MAX_SWIPE_ANGLE) {
+            return;
+        } else if (theta > START_DAMPING_TOUCH_SLOP_ANGLE) {
+            theta -= START_DAMPING_TOUCH_SLOP_ANGLE;
+            float extraRatio = (float)
+                    Math.sqrt((theta / (MAX_SWIPE_ANGLE - START_DAMPING_TOUCH_SLOP_ANGLE)));
+            super.determineScrollingStart(ev, 1 + TOUCH_SLOP_DAMPING_FACTOR * extraRatio);
+        } else {
+            super.determineScrollingStart(ev);
+        }
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+
+    @Override
+    protected boolean canScroll(float absVScroll, float absHScroll) {
+        return (absHScroll > absVScroll) && super.canScroll(absVScroll, absHScroll);
+    }
+}
diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
similarity index 85%
rename from src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
rename to src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
index 2de425e..3a3028f 100644
--- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.allapps;
+package com.android.launcher3.workprofile;
 
 import android.content.Context;
 import android.graphics.Canvas;
@@ -35,9 +35,6 @@
  * Supports two indicator colors, dedicated for personal and work tabs.
  */
 public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageIndicator {
-    private static final int POSITION_PERSONAL = 0;
-    private static final int POSITION_WORK = 1;
-
     private final Paint mSelectedIndicatorPaint;
     private final Paint mDividerPaint;
 
@@ -47,7 +44,7 @@
     private float mScrollOffset;
     private int mSelectedPosition = 0;
 
-    private AllAppsContainerView mContainerView;
+    private OnActivePageChangedListener mOnActivePageChangedListener;
     private int mLastActivePage = 0;
     private boolean mIsRtl;
 
@@ -123,7 +120,7 @@
         float y = getHeight() - mDividerPaint.getStrokeWidth();
         canvas.drawLine(getPaddingLeft(), y, getWidth() - getPaddingRight(), y, mDividerPaint);
         canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
-            mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
+                mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
     }
 
     @Override
@@ -135,15 +132,15 @@
     @Override
     public void setActiveMarker(int activePage) {
         updateTabTextColor(activePage);
-        if (mContainerView != null && mLastActivePage != activePage) {
+        if (mOnActivePageChangedListener != null && mLastActivePage != activePage) {
             updateIndicatorPosition(activePage);
-            mContainerView.onTabChanged(activePage);
+            mOnActivePageChangedListener.onActivePageChanged(activePage);
         }
         mLastActivePage = activePage;
     }
 
-    public void setContainerView(AllAppsContainerView containerView) {
-        mContainerView = containerView;
+    public void setOnActivePageChangedListener(OnActivePageChangedListener listener) {
+        mOnActivePageChangedListener = listener;
     }
 
     @Override
@@ -153,4 +150,12 @@
     public boolean hasOverlappingRendering() {
         return false;
     }
+
+    /**
+     * Interface definition for a callback to be invoked when an active page has been changed.
+     */
+    public interface OnActivePageChangedListener {
+        /** Called when the active page has been changed. */
+        void onActivePageChanged(int currentActivePage);
+    }
 }