Hide work apps when work profile is paused

- hide overlay icon in landscape mode
- don't show edu if user has already seen legacy work profile edu
- make sure personal tab is highlighted when work profile is reinstalled
- always go home after a work profile is added or removed
- add tests for work edu flow

Bug: 150122946
Test: Manual
Change-Id: I8f80ac763acf03ca31a534464f4ddfd84528d329
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index 1c18076..cf1e835 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -15,19 +15,10 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="?attr/allAppsScrimColor"
-    android:padding="8dp"
+    android:padding="48dp"
     android:orientation="vertical"
     android:gravity="center">
 
-    <ImageView
-        android:id="@+id/icon"
-        android:contentDescription="@string/work_apps_paused_title"
-        android:layout_width="32dp"
-        android:layout_height="32dp"
-        android:tint="?attr/workProfileOverlayTextColor"
-        android:src="@drawable/ic_corp_off" />
-
     <TextView
         style="@style/TextHeadline"
         android:textColor="?attr/workProfileOverlayTextColor"
diff --git a/res/layout/work_profile_edu.xml b/res/layout/work_profile_edu.xml
index 04094c4..5506b94 100644
--- a/res/layout/work_profile_edu.xml
+++ b/res/layout/work_profile_edu.xml
@@ -41,6 +41,7 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="48dp"
             android:layout_marginBottom="48dp"
+            android:gravity="center"
             android:text="@string/work_profile_edu_personal_apps"
             android:textAlignment="center"
             android:textColor="@android:color/white"
diff --git a/res/layout/work_tab_footer.xml b/res/layout/work_tab_footer.xml
index 2cffedd..dbcdbdb 100644
--- a/res/layout/work_tab_footer.xml
+++ b/res/layout/work_tab_footer.xml
@@ -19,19 +19,20 @@
     android:layout_height="wrap_content"
     android:id="@+id/work_toggle_container"
     android:focusable="true"
-    android:paddingBottom="@dimen/all_apps_work_profile_tab_footer_padding_vertical"
     android:orientation="horizontal"
-    android:paddingLeft="@dimen/all_apps_work_profile_tab_footer_padding_horizontal"
     android:background="?attr/allAppsScrimColor"
-    android:paddingRight="@dimen/all_apps_work_profile_tab_footer_padding_horizontal"
-    android:paddingTop="@dimen/all_apps_work_profile_tab_footer_padding_vertical">
+    android:paddingBottom="@dimen/all_apps_work_profile_tab_footer_padding"
+    android:paddingLeft="@dimen/all_apps_work_profile_tab_footer_padding"
+    android:paddingRight="@dimen/all_apps_work_profile_tab_footer_padding"
+    android:paddingTop="@dimen/all_apps_work_profile_tab_footer_padding">
 
     <TextView
+        style="@style/PrimaryMediumText"
         android:id="@+id/work_mode_label"
         android:layout_width="0dp"
         android:layout_weight="1"
         android:drawableStart="@drawable/ic_corp"
-        android:drawablePadding="3dp"
+        android:drawablePadding="16dp"
         android:drawableTint="?attr/workProfileOverlayTextColor"
         android:textColor="?attr/workProfileOverlayTextColor"
         android:layout_height="wrap_content"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index edae7f4..871651d 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -85,8 +85,7 @@
     <dimen name="all_apps_tabs_side_padding">12dp</dimen>
     <dimen name="all_apps_divider_height">1dp</dimen>
 
-    <dimen name="all_apps_work_profile_tab_footer_padding_vertical">20dp</dimen>
-    <dimen name="all_apps_work_profile_tab_footer_padding_horizontal">24dp</dimen>
+    <dimen name="all_apps_work_profile_tab_footer_padding">20dp</dimen>
 
 <!-- Search bar in All Apps -->
     <dimen name="all_apps_header_max_elevation">3dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index cee268b..bc6ab45 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -225,6 +225,7 @@
     <style name="DropTargetButton" parent="DropTargetButtonBase" />
 
     <style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
+    <style name="PrimaryMediumText" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
 
     <style name="TextTitle" parent="@android:style/TextAppearance.DeviceDefault" />
 
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 864fa6e..38e1201 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -22,11 +22,11 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 
-import androidx.recyclerview.widget.RecyclerView;
-
 
 /**
  * A base {@link RecyclerView}, which does the following:
@@ -138,7 +138,7 @@
         if (getCurrentScrollY() == 0) {
             return true;
         }
-        return false;
+        return getAdapter() == null || getAdapter().getItemCount() == 0;
     }
 
     /**
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index a2957bc..e085ff0 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -15,9 +15,6 @@
  */
 package com.android.launcher3.allapps;
 
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
 
 import android.animation.ValueAnimator;
@@ -395,7 +392,7 @@
         rebindAdapters(showTabs, false /* force */);
     }
 
-    private void rebindAdapters(boolean showTabs, boolean force) {
+    protected void rebindAdapters(boolean showTabs, boolean force) {
         if (showTabs == mUsingTabs && !force) {
             return;
         }
@@ -463,6 +460,7 @@
     public void onTabChanged(int pos) {
         mHeader.setMainActive(pos == 0);
         reset(true /* animate */);
+        mViewPager.getPageIndicator().updateTabTextColor(pos);
         if (mAH[pos].recyclerView != null) {
             mAH[pos].recyclerView.bindFastScrollbar();
 
@@ -608,6 +606,7 @@
         public static final int MAIN = 0;
         public static final int WORK = 1;
 
+        private ItemInfoMatcher mInfoMatcher;
         private final boolean mIsWork;
         public final AllAppsGridAdapter adapter;
         final LinearLayoutManager layoutManager;
@@ -627,6 +626,7 @@
         }
 
         void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
+            mInfoMatcher = matcher;
             appsList.updateItemFilter(matcher);
             recyclerView = (AllAppsRecyclerView) rv;
             recyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
@@ -647,19 +647,14 @@
         void setupOverlay() {
             if (!mIsWork || recyclerView == null) return;
             boolean workDisabled = UserCache.INSTANCE.get(mLauncher).isAnyProfileQuietModeEnabled();
-            recyclerView.getOverlay().clear();
+            if (mWorkDisabled == workDisabled) return;
             if (workDisabled) {
-                View pausedOverlay = mLauncher.getLayoutInflater().inflate(
-                        R.layout.work_apps_paused, null);
-                recyclerView.post(() -> {
-                    int width = recyclerView.getWidth();
-                    int height = recyclerView.getHeight() -  mWorkFooterContainer.getHeight();
-                    pausedOverlay.measure(makeMeasureSpec(recyclerView.getWidth(), EXACTLY),
-                            makeMeasureSpec(recyclerView.getHeight(), EXACTLY));
-                    pausedOverlay.layout(0, 0, width, height);
-                    applyPadding();
-                });
-                recyclerView.getOverlay().add(pausedOverlay);
+                appsList.updateItemFilter((info, cn) -> false);
+                recyclerView.addAutoSizedOverlay(
+                        mLauncher.getLayoutInflater().inflate(R.layout.work_apps_paused, null));
+            } else if (mInfoMatcher != null) {
+                appsList.updateItemFilter(mInfoMatcher);
+                recyclerView.clearAutoSizedOverlays();
             }
             mWorkDisabled = workDisabled;
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index c228ddf..8fe4633 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -15,7 +15,9 @@
  */
 package com.android.launcher3.allapps;
 
+import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.UNSPECIFIED;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
 
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
 
@@ -62,6 +64,8 @@
     private AllAppsBackgroundDrawable mEmptySearchBackground;
     private int mEmptySearchBackgroundTopOffset;
 
+    private ArrayList<View> mAutoSizedOverlays = new ArrayList<>();
+
     public AllAppsRecyclerView(Context context) {
         this(context, null);
     }
@@ -145,6 +149,30 @@
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         updateEmptySearchBackgroundBounds();
         updatePoolSize();
+        for (int i = 0; i < mAutoSizedOverlays.size(); i++) {
+            View overlay = mAutoSizedOverlays.get(i);
+            overlay.measure(makeMeasureSpec(w, EXACTLY), makeMeasureSpec(w, EXACTLY));
+            overlay.layout(0, 0, w, h);
+        }
+    }
+
+    /**
+     * Adds an overlay that automatically rescales with the recyclerview.
+     */
+    public void addAutoSizedOverlay(View overlay) {
+        mAutoSizedOverlays.add(overlay);
+        getOverlay().add(overlay);
+        onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight());
+    }
+
+    /**
+     * Clears auto scaling overlay views added by #addAutoSizedOverlay
+     */
+    public void clearAutoSizedOverlays() {
+        for (View v : mAutoSizedOverlays) {
+            getOverlay().remove(v);
+        }
+        mAutoSizedOverlays.clear();
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
index 0e39bbe..3e40392 100644
--- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
@@ -71,12 +71,10 @@
         mIsRtl = Utilities.isRtl(getResources());
     }
 
-    private void updateIndicatorPosition(float scrollOffset) {
-        mScrollOffset = scrollOffset;
-        updateIndicatorPosition();
-    }
-
-    private void updateTabTextColor(int pos) {
+    /**
+     * Highlights tab with index pos
+     */
+    public void updateTabTextColor(int pos) {
         mSelectedPosition = pos;
         for (int i = 0; i < getChildCount(); i++) {
             Button tab = (Button) getChildAt(i);
@@ -84,6 +82,11 @@
         }
     }
 
+    private void updateIndicatorPosition(float scrollOffset) {
+        mScrollOffset = scrollOffset;
+        updateIndicatorPosition();
+    }
+
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
index 81f8327..d849138 100644
--- a/src/com/android/launcher3/views/WorkEduView.java
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -46,7 +46,8 @@
 public class WorkEduView extends AbstractSlideInView implements Insettable {
 
     private static final int DEFAULT_CLOSE_DURATION = 200;
-    private static final String KEY_WORK_EDU_STEP = "showed_work_profile_edu";
+    public static final String KEY_WORK_EDU_STEP = "showed_work_profile_edu";
+    public static final String KEY_LEGACY_WORK_EDU_SEEN = "showed_bottom_user_education";
 
     private static final int WORK_EDU_NOT_STARTED = 0;
     private static final int WORK_EDU_PERSONAL_APPS = 1;
@@ -102,6 +103,8 @@
         mProceedButton = findViewById(R.id.proceed);
         mContentText = findViewById(R.id.content_text);
 
+        // make sure layout does not shrink when we change the text
+        mContentText.post(() -> mContentText.setMinLines(mContentText.getLineCount()));
         if (mLauncher.getAppsView().getContentView() instanceof AllAppsPagedView) {
             mAllAppsPagedView = (AllAppsPagedView) mLauncher.getAppsView().getContentView();
         }
@@ -179,8 +182,8 @@
         if (oldListener != null) {
             launcher.getStateManager().removeStateListener(oldListener);
         }
-        if (launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP, WORK_EDU_NOT_STARTED)
-                != WORK_EDU_NOT_STARTED) {
+        if (hasSeenLegacyEdu(launcher) || launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP,
+                WORK_EDU_NOT_STARTED) != WORK_EDU_NOT_STARTED) {
             return null;
         }
 
@@ -210,8 +213,8 @@
      * Shows work apps edu if user had dismissed full edu flow
      */
     public static void showWorkEduIfNeeded(Launcher launcher) {
-        if (launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP, WORK_EDU_NOT_STARTED)
-                != WORK_EDU_PERSONAL_APPS) {
+        if (hasSeenLegacyEdu(launcher) || launcher.getSharedPrefs().getInt(KEY_WORK_EDU_STEP,
+                WORK_EDU_NOT_STARTED) != WORK_EDU_PERSONAL_APPS) {
             return;
         }
         LayoutInflater layoutInflater = LayoutInflater.from(launcher);
@@ -220,4 +223,8 @@
         v.show();
         v.goToWorkTab(false);
     }
+
+    private static boolean hasSeenLegacyEdu(Launcher launcher) {
+        return launcher.getSharedPrefs().getBoolean(KEY_LEGACY_WORK_EDU_SEEN, false);
+    }
 }
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index 6fe6739..db2d974 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -16,8 +16,6 @@
 package com.android.launcher3.ui;
 
 import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.UNBUNDLED_POSTSUBMIT;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -25,13 +23,16 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.widget.TextView;
 
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.launcher3.R;
 import com.android.launcher3.allapps.AllAppsContainerView;
 import com.android.launcher3.allapps.AllAppsPagedView;
-import com.android.launcher3.util.rule.TestStabilityRule;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.views.WorkEduView;
 import com.android.launcher3.views.WorkFooterContainer;
 
 import org.junit.After;
@@ -48,6 +49,8 @@
 
     private int mProfileUserId;
 
+    private static final int WORK_PAGE = AllAppsContainerView.AdapterHolder.WORK;
+
     @Before
     public void createWorkProfile() throws Exception {
         String output =
@@ -67,8 +70,6 @@
     }
 
     @Test
-    // b/143285809 Remove @Stability on 02/21/20 if the test doesn't flake.
-    @TestStabilityRule.Stability(flavors = LOCAL | UNBUNDLED_POSTSUBMIT)
     public void workTabExists() {
         mDevice.pressHome();
         waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
@@ -80,8 +81,6 @@
     }
 
     @Test
-    // b/143285809 Remove @Stability on 02/21/20 if the test doesn't flake.
-    @TestStabilityRule.Stability(flavors = LOCAL | UNBUNDLED_POSTSUBMIT)
     public void toggleWorks() {
         mDevice.pressHome();
         waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
@@ -112,4 +111,78 @@
                 l -> l.getSystemService(UserManager.class).isQuietModeEnabled(workProfile));
     }
 
+    @Test
+    public void testWorkEduFlow() {
+        mDevice.pressHome();
+        waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+        executeOnLauncher(launcher -> launcher.getSharedPrefs().edit().remove(
+                WorkEduView.KEY_WORK_EDU_STEP).remove(
+                WorkEduView.KEY_LEGACY_WORK_EDU_SEEN).commit());
+
+        waitForLauncherCondition("Work tab not setup",
+                launcher -> launcher.getAppsView().getContentView() instanceof AllAppsPagedView,
+                60000);
+
+        executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+        WorkEduView workEduView = getEduView();
+        // verify personal app edu is seen first and click "next"
+        executeOnLauncher(l -> {
+            assertEquals(((TextView) workEduView.findViewById(R.id.content_text)).getText(),
+                    l.getResources().getString(R.string.work_profile_edu_personal_apps));
+            workEduView.findViewById(R.id.proceed).callOnClick();
+        });
+        // verify work edu is seen next
+        waitForLauncherCondition("Launcher did not show the next edu screen", l ->
+                ((AllAppsPagedView) l.getAppsView().getContentView()).getCurrentPage() == WORK_PAGE
+                        && ((TextView) workEduView.findViewById(
+                        R.id.content_text)).getText().equals(
+                        l.getResources().getString(R.string.work_profile_edu_work_apps)));
+    }
+
+    @Test
+    public void testWorkEduIntermittent() {
+        mDevice.pressHome();
+        waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+        executeOnLauncher(launcher -> launcher.getSharedPrefs().edit().remove(
+                WorkEduView.KEY_WORK_EDU_STEP).remove(
+                WorkEduView.KEY_LEGACY_WORK_EDU_SEEN).commit());
+
+
+        waitForLauncherCondition("Work tab not setup",
+                launcher -> launcher.getAppsView().getContentView() instanceof AllAppsPagedView,
+                60000);
+        executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+
+        // verify personal app edu is seen
+        getEduView();
+
+        // dismiss personal edu
+        mDevice.pressHome();
+
+        // open work tab
+        executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+        executeOnLauncher(launcher -> {
+            AllAppsPagedView pagedView = (AllAppsPagedView) launcher.getAppsView().getContentView();
+            pagedView.setCurrentPage(WORK_PAGE);
+        });
+
+        WorkEduView workEduView = getEduView();
+
+        // verify work tab edu is shown
+        waitForLauncherCondition("Launcher did not show the next edu screen",
+                l -> ((TextView) workEduView.findViewById(R.id.content_text)).getText().equals(
+                        l.getResources().getString(R.string.work_profile_edu_work_apps)));
+    }
+
+
+    private WorkEduView getEduView() {
+        waitForLauncherCondition("Edu did not show", l -> {
+            DragLayer dragLayer = l.getDragLayer();
+            return dragLayer.getChildCount() > 0 && dragLayer.getChildAt(
+                    dragLayer.getChildCount() - 1) instanceof WorkEduView;
+        });
+        return getFromLauncher(launcher -> (WorkEduView) launcher.getDragLayer().getChildAt(
+                launcher.getDragLayer().getChildCount() - 1));
+    }
+
 }
\ No newline at end of file