Merge "Rewriting failure investigator database in a more readable way" into ub-launcher3-master
diff --git a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
index 97eef66..22f1f23 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
@@ -30,6 +30,8 @@
 
     private static final String TAG = "GraphicsUtils";
 
+    public static Runnable sOnNewBitmapRunnable = () -> { };
+
     /**
      * Set the alpha component of {@code color} to be {@code alpha}. Unlike the support lib version,
      * it bounds the alpha in valid range instead of throwing an exception to allow for safer
@@ -77,5 +79,7 @@
     /**
      * Utility method to track new bitmap creation
      */
-    public static void noteNewBitmapCreated() { }
+    public static void noteNewBitmapCreated() {
+        sOnNewBitmapRunnable.run();
+    }
 }
diff --git a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
index a7cd167..d94c665 100644
--- a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
+++ b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
@@ -34,10 +34,10 @@
         android:orientation="vertical">
 
         <TextView
+            style="@style/TextHeadline"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="18dp"
-            android:fontFamily="google-sans"
             android:paddingLeft="@dimen/bottom_sheet_edu_padding"
             android:paddingRight="@dimen/bottom_sheet_edu_padding"
             android:text="@string/hotseat_migrate_title"
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index ff1b5f6..b80830a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -43,6 +43,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppTransitionManagerImpl;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
@@ -87,6 +88,10 @@
         if (handlingOverviewAnim()) {
             mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged);
         }
+
+        if (mAtomicAnim != null) {
+            mAtomicAnim.cancel();
+        }
     }
 
     protected void onMotionPauseChanged(boolean isPaused) {
@@ -193,13 +198,27 @@
 
         Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
                 INDEX_PAUSE_TO_OVERVIEW_ANIM);
-        overviewAnim.addListener(new AnimatorListenerAdapter() {
+        mAtomicAnim = new AnimatorSet();
+        mAtomicAnim.addListener(new AnimationSuccessListener() {
             @Override
-            public void onAnimationEnd(Animator animation) {
+            public void onAnimationSuccess(Animator animator) {
                 onSwipeInteractionCompleted(OVERVIEW, Touch.SWIPE);
             }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                if (mCancelled) {
+                    mPeekAnim = mLauncher.getStateManager().createAtomicAnimation(mFromState,
+                            mToState, new AnimatorSetBuilder(), ATOMIC_OVERVIEW_PEEK_COMPONENT,
+                            PEEK_OUT_ANIM_DURATION);
+                    mPeekAnim.start();
+                }
+                mAtomicAnim = null;
+            }
         });
-        overviewAnim.start();
+        mAtomicAnim.play(overviewAnim);
+        mAtomicAnim.start();
     }
 
     @Override
diff --git a/res/drawable/ic_corp.xml b/res/drawable/ic_corp.xml
index b59113d..76dccd3 100644
--- a/res/drawable/ic_corp.xml
+++ b/res/drawable/ic_corp.xml
@@ -19,9 +19,5 @@
     android:viewportWidth="24.0"
     android:viewportHeight="24.0"
     android:tint="?android:attr/textColorHint" >
-    <path
-        android:pathData="M20 6h-4V4c0-1.11-0.89-2-2-2h-4c-1.11 0-2 0.89-2 2v2H4c-1.11 0-1.99 0.89 -1.99
-2L2 19c0 1.11 0.89 2 2 2h16c1.11 0 2-0.89 2-2V8c0-1.11-0.89-2-2-2zM10
-4h4v2h-4V4zm10 15H4V8h16v11z"
-        android:fillColor="@android:color/white"/>
+    <path android:fillColor="@android:color/white" android:pathData="M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-8 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm2-9h-4V4h4v2z"/>
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_corp_off.xml b/res/drawable/ic_corp_off.xml
new file mode 100644
index 0000000..62a9787
--- /dev/null
+++ b/res/drawable/ic_corp_off.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/textColorHint" >
+    <path
+        android:pathData="M22 7.95c.05-1.11-.84-2-1.95-1.95H16V3.95c0-1.11-.84-2-1.95-1.95h-4C8.94 1.95 8 2.84 8 3.95v.32l14 14V7.95zM14 6h-4V4h4v2zm7.54 14.28l-7.56-7.56v.01l-1.7-1.7h.01L7.21 5.95 3.25 1.99 1.99 3.27 4.69 6h-.64c-1.11 0-1.99.86-1.99 1.97l-.01 11.02c0 1.11.89 2.01 2 2.01h15.64l2.05 2.02L23 21.75l-1.46-1.47z"
+        android:fillColor="@android:color/white"/>
+</vector>
\ No newline at end of file
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
new file mode 100644
index 0000000..5607e78
--- /dev/null
+++ b/res/layout/work_apps_paused.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="8dp"
+    android:orientation="vertical"
+    android:background="?attr/allAppsScrimColor"
+    android:gravity="center">
+
+    <ImageView
+        android:id="@+id/icon"
+        android:contentDescription="@string/work_apps_paused_title"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:tint="?attr/folderTextColor"
+        android:src="@drawable/ic_corp_off" />
+
+    <TextView
+        style="@style/TextHeadline"
+        android:textColor="?attr/folderTextColor"
+        android:id="@+id/work_apps_paused_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
+        android:text="@string/work_apps_paused_title"
+        android:textAlignment="center"
+        android:textSize="24sp" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="?attr/folderTextColor"
+        android:text="@string/work_apps_paused_body"
+        android:textAlignment="center"
+        android:textSize="16sp" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/work_profile_edu.xml b/res/layout/work_profile_edu.xml
index a8e3d20..f7a529d 100644
--- a/res/layout/work_profile_edu.xml
+++ b/res/layout/work_profile_edu.xml
@@ -35,12 +35,12 @@
         android:paddingRight="@dimen/bottom_sheet_edu_padding">
 
         <TextView
+            style="@style/TextHeadline"
             android:id="@+id/content_text"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="48dp"
             android:layout_marginBottom="48dp"
-            android:fontFamily="google-sans"
             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 379e9d0..db95416 100644
--- a/res/layout/work_tab_footer.xml
+++ b/res/layout/work_tab_footer.xml
@@ -17,63 +17,31 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:id="@+id/work_toggle_container"
     android:focusable="true"
-    android:paddingBottom="@dimen/all_apps_work_profile_tab_footer_bottom_padding"
-    android:paddingLeft="@dimen/dynamic_grid_cell_padding_x"
-    android:paddingRight="@dimen/dynamic_grid_cell_padding_x"
-    android:paddingTop="@dimen/all_apps_work_profile_tab_footer_top_padding">
-
-    <ImageView
-        android:id="@+id/work_footer_divider"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:focusable="false"
-        android:importantForAccessibility="no"
-        android:paddingBottom="@dimen/all_apps_divider_margin_vertical"
-        android:paddingTop="@dimen/all_apps_divider_margin_vertical"
-        android:scaleType="fitXY"
-        android:src="@drawable/all_apps_divider"/>
-
-    <com.android.launcher3.allapps.WorkModeSwitch
-        android:id="@+id/work_mode_toggle"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_below="@id/work_footer_divider"/>
+    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">
 
     <TextView
-        android:id="@android:id/title"
-        android:layout_width="wrap_content"
+        android:id="@+id/work_mode_label"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:drawableStart="@drawable/ic_corp"
+        android:drawablePadding="3dp"
         android:layout_height="wrap_content"
-        android:layout_alignBaseline="@id/work_mode_toggle"
-        android:layout_alignParentStart="true"
-        android:ellipsize="end"
-        android:lines="1"
-        android:text="@string/work_profile_toggle_label"
-        android:textColor="?android:attr/textColorTertiary"
-        android:textSize="16sp"/>
-
-    <ImageView
-        android:id="@android:id/icon"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:layout_below="@android:id/title"
-        android:layout_marginTop="8dp"
-        android:src="@drawable/ic_corp"/>
-
-    <TextView
-        android:id="@+id/managed_by_label"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@android:id/title"
-        android:layout_marginTop="8dp"
-        android:layout_toEndOf="@android:id/icon"
         android:ellipsize="end"
         android:gravity="center_vertical"
         android:lines="1"
         android:minHeight="24dp"
-        android:paddingStart="12dp"
-        android:textColor="?android:attr/textColorHint"
-        android:textSize="13sp"/>
+        android:paddingEnd="12dp"
+        android:textSize="16sp"/>
+    <com.android.launcher3.allapps.WorkModeSwitch
+        android:id="@+id/work_mode_toggle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
 
 </com.android.launcher3.views.WorkFooterContainer>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0293573..edae7f4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -85,6 +85,9 @@
     <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>
+
 <!-- Search bar in All Apps -->
     <dimen name="all_apps_header_max_elevation">3dp</dimen>
     <dimen name="all_apps_header_scroll_to_elevation">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3f279f4..bfa92f7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -338,9 +338,12 @@
 
     <!-- This string is in the work profile tab when a user has All Apps open on their phone. It describes the label of a toggle, "Work profile," as being managed by the user's employer.
     "Organization" is used to represent a variety of businesses, non-profits, and educational institutions).-->
-    <string name="work_mode_on_label">Managed by your organization</string>
+    <string name="work_mode_on_label">Work apps: On</string>
     <!-- This string appears under a the label of a toggle in the work profile tab on a user's phone. It describes the status of the toggle, "Work profile," when it's turned off. "Work profile" means a separate profile on a user's phone that's speficially for their work apps and is managed by their company.-->
-    <string name="work_mode_off_label">Notifications and apps are off</string>
+    <string name="work_mode_off_label">Work apps: Paused</string>
+
+    <string name="work_apps_paused_title">Work apps are paused</string>
+    <string name="work_apps_paused_body">You won\'t get any work notifications, and your IT admin can\'t see your location</string>
 
     <!-- Failed action error message: e.g. Failed: Pause -->
     <string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 80c791c..35ae49c 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -55,6 +55,8 @@
         <item name="android:windowDrawsSystemBarBackgrounds">true</item>
         <item name="android:statusBarColor">#00000000</item>
         <item name="android:navigationBarColor">#00000000</item>
+
+
     </style>
 
     <style name="LauncherTheme.DarkMainColor" parent="@style/LauncherTheme">
diff --git a/src/com/android/launcher3/MainProcessInitializer.java b/src/com/android/launcher3/MainProcessInitializer.java
index 95ee687..5f6ecb5 100644
--- a/src/com/android/launcher3/MainProcessInitializer.java
+++ b/src/com/android/launcher3/MainProcessInitializer.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.BitmapCreationCheck;
 import com.android.launcher3.graphics.IconShape;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.ResourceBasedOverride;
@@ -39,5 +40,9 @@
         FeatureFlags.initialize(context);
         SessionCommitReceiver.applyDefaultUserPrefs(context);
         IconShape.init(context);
+
+        if (BitmapCreationCheck.ENABLED) {
+            BitmapCreationCheck.startTracking(context);
+        }
     }
 }
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 6f15c9b..56bd1b6 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -15,6 +15,9 @@
  */
 package com.android.launcher3.allapps;
 
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
@@ -51,6 +54,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.keyboard.FocusedItemDecorator;
+import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.ItemInfoMatcher;
@@ -59,6 +63,7 @@
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 import com.android.launcher3.views.SpringRelativeLayout;
+import com.android.launcher3.views.WorkFooterContainer;
 
 /**
  * The all apps view container.
@@ -83,7 +88,10 @@
     protected SearchUiManager mSearchUiManager;
     private View mSearchContainer;
     private AllAppsPagedView mViewPager;
+
     private FloatingHeaderView mHeader;
+    private WorkFooterContainer mWorkFooterContainer;
+
 
     private SpannableStringBuilder mSearchQueryBuilder = null;
 
@@ -173,6 +181,15 @@
             }
         }
         rebindAdapters(hasWorkApps);
+        if (hasWorkApps) {
+            resetWorkProfile();
+        }
+    }
+
+    private void resetWorkProfile() {
+        mWorkFooterContainer.refresh();
+        mAH[AdapterHolder.WORK].setupOverlay();
+        mAH[AdapterHolder.WORK].applyPadding();
     }
 
     /**
@@ -311,6 +328,7 @@
             mAH[i].padding.bottom = insets.bottom;
             mAH[i].padding.left = mAH[i].padding.right = leftRightPadding;
             mAH[i].applyPadding();
+            mAH[i].setupOverlay();
         }
 
         ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
@@ -368,12 +386,17 @@
         mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView);
 
         if (mUsingTabs) {
+            setupWorkToggle();
             mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
             mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
             onTabChanged(mViewPager.getNextPage());
         } else {
             mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
             mAH[AdapterHolder.WORK].recyclerView = null;
+            if (mWorkFooterContainer != null) {
+                ((ViewGroup) mWorkFooterContainer.getParent()).removeView(mWorkFooterContainer);
+                mWorkFooterContainer = null;
+            }
         }
         setupHeader();
 
@@ -381,6 +404,16 @@
         mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView);
     }
 
+    private void setupWorkToggle() {
+        mWorkFooterContainer = (WorkFooterContainer) mLauncher.getLayoutInflater().inflate(
+                R.layout.work_tab_footer, findViewById(R.id.work_toggle_container));
+        mWorkFooterContainer.setLayoutParams(
+                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.WRAP_CONTENT));
+        this.addView(mWorkFooterContainer);
+        mWorkFooterContainer.post(() -> mAH[AdapterHolder.WORK].applyPadding());
+    }
+
     private void replaceRVContainer(boolean showTabs) {
         for (int i = 0; i < mAH.length; i++) {
             if (mAH[i].recyclerView != null) {
@@ -417,6 +450,9 @@
             findViewById(R.id.tab_work)
                     .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
         }
+        if (mWorkFooterContainer != null) {
+            mWorkFooterContainer.setWorkTabVisible(pos == AdapterHolder.WORK);
+        }
     }
 
     // Used by tests only
@@ -562,6 +598,7 @@
         public static final int MAIN = 0;
         public static final int WORK = 1;
 
+        private final boolean mIsWork;
         public final AllAppsGridAdapter adapter;
         final LinearLayoutManager layoutManager;
         final AlphabeticalAppsList appsList;
@@ -569,7 +606,10 @@
         AllAppsRecyclerView recyclerView;
         boolean verticalFadingEdge;
 
+        boolean mWorkDisabled;
+
         AdapterHolder(boolean isWork) {
+            mIsWork = isWork;
             appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore, isWork);
             adapter = new AllAppsGridAdapter(mLauncher, appsList);
             appsList.setAdapter(adapter);
@@ -591,11 +631,36 @@
             adapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
             applyVerticalFadingEdgeEnabled(verticalFadingEdge);
             applyPadding();
+            setupOverlay();
+        }
+
+        void setupOverlay() {
+            if (!mIsWork || recyclerView == null) return;
+            boolean workDisabled = UserCache.INSTANCE.get(mLauncher).isAnyProfileQuietModeEnabled();
+            recyclerView.getOverlay().clear();
+            if (workDisabled) {
+                View pausedOverlay = mLauncher.getLayoutInflater().inflate(
+                        R.layout.work_apps_paused, null);
+                recyclerView.post(() -> {
+                    int width = recyclerView.getWidth();
+                    int height = recyclerView.getHeight();
+                    pausedOverlay.measure(makeMeasureSpec(width, EXACTLY),
+                            makeMeasureSpec(height, EXACTLY));
+                    pausedOverlay.layout(0, 0, width, height);
+                    applyPadding();
+                });
+                recyclerView.getOverlay().add(pausedOverlay);
+            }
+            mWorkDisabled = workDisabled;
         }
 
         void applyPadding() {
             if (recyclerView != null) {
-                recyclerView.setPadding(padding.left, padding.top, padding.right, padding.bottom);
+                int bottomOffset =
+                        mWorkFooterContainer != null && mIsWork ? mWorkFooterContainer.getHeight()
+                                : 0;
+                recyclerView.setPadding(padding.left, padding.top, padding.right,
+                        padding.bottom + bottomOffset);
             }
         }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 442b77b..1f861bc 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -43,7 +43,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
 import com.android.launcher3.model.AppLaunchTracker;
-import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.util.PackageManagerHelper;
 
 import java.util.List;
@@ -67,7 +66,6 @@
 
     // A divider that separates the apps list and the search market button
     public static final int VIEW_TYPE_ALL_APPS_DIVIDER = 1 << 4;
-    public static final int VIEW_TYPE_WORK_TAB_FOOTER = 1 << 5;
 
     // Common view type masks
     public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
@@ -289,9 +287,6 @@
             case VIEW_TYPE_ALL_APPS_DIVIDER:
                 return new ViewHolder(mLayoutInflater.inflate(
                         R.layout.all_apps_divider, parent, false));
-            case VIEW_TYPE_WORK_TAB_FOOTER:
-                View footer = mLayoutInflater.inflate(R.layout.work_tab_footer, parent, false);
-                return new ViewHolder(footer);
             default:
                 throw new RuntimeException("Unexpected view type");
         }
@@ -323,15 +318,6 @@
             case VIEW_TYPE_ALL_APPS_DIVIDER:
                 // nothing to do
                 break;
-            case VIEW_TYPE_WORK_TAB_FOOTER:
-                WorkModeSwitch workModeToggle = holder.itemView.findViewById(R.id.work_mode_toggle);
-                workModeToggle.refresh();
-                TextView managedByLabel = holder.itemView.findViewById(R.id.managed_by_label);
-                boolean anyProfileQuietModeEnabled = UserCache.INSTANCE.get(
-                        managedByLabel.getContext()).isAnyProfileQuietModeEnabled();
-                managedByLabel.setText(anyProfileQuietModeEnabled
-                        ? R.string.work_mode_off_label : R.string.work_mode_on_label);
-                break;
         }
         if (mBindViewCallback != null) {
             mBindViewCallback.onBindView(holder);
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index a33fe4d..b501c82 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -15,14 +15,11 @@
  */
 package com.android.launcher3.allapps;
 
-import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
 
 import android.content.Context;
-import android.content.pm.PackageManager;
 
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LabelComparator;
@@ -117,13 +114,6 @@
             item.position = pos;
             return item;
         }
-
-        public static AdapterItem asWorkTabFooter(int pos) {
-            AdapterItem item = new AdapterItem();
-            item.viewType = AllAppsGridAdapter.VIEW_TYPE_WORK_TAB_FOOTER;
-            item.position = pos;
-            return item;
-        }
     }
 
     private final BaseDraggingActivity mLauncher;
@@ -390,18 +380,6 @@
                     break;
             }
         }
-
-        // Add the work profile footer if required.
-        if (shouldShowWorkFooter()) {
-            mAdapterItems.add(AdapterItem.asWorkTabFooter(position++));
-        }
-    }
-
-    private boolean shouldShowWorkFooter() {
-        return mIsWork && Utilities.ATLEAST_P &&
-                (hasShortcutsPermission(mLauncher)
-                        || mLauncher.checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
-                        == PackageManager.PERMISSION_GRANTED);
     }
 
     private List<AppInfo> getFiltersAppInfos() {
diff --git a/src/com/android/launcher3/graphics/BitmapCreationCheck.java b/src/com/android/launcher3/graphics/BitmapCreationCheck.java
new file mode 100644
index 0000000..e63e542
--- /dev/null
+++ b/src/com/android/launcher3/graphics/BitmapCreationCheck.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 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.graphics;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.Application;
+import android.app.Application.ActivityLifecycleCallbacks;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
+import android.view.ViewTreeObserver.OnDrawListener;
+
+import com.android.launcher3.Utilities;
+import com.android.launcher3.icons.GraphicsUtils;
+
+/**
+ * Utility class to check bitmap creation during draw pass.
+ */
+public class BitmapCreationCheck {
+
+    private static final String TAG = "BitmapCreationCheck";
+
+    public static final boolean ENABLED = false;
+
+    /**
+     * Starts tracking bitmap creations during {@link View#draw(Canvas)} calls
+     */
+    public static void startTracking(Context context) {
+        MyTracker tracker = new MyTracker();
+        ((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(tracker);
+        GraphicsUtils.sOnNewBitmapRunnable = tracker::onBitmapCreated;
+    }
+
+    @TargetApi(VERSION_CODES.Q)
+    private static class MyTracker
+            implements ActivityLifecycleCallbacks, OnAttachStateChangeListener {
+
+        private final ThreadLocal<Boolean> mCurrentThreadDrawing =
+                ThreadLocal.withInitial(() -> false);
+
+        @Override
+        public void onActivityCreated(Activity activity, Bundle bundle) {
+            activity.getWindow().getDecorView().addOnAttachStateChangeListener(this);
+        }
+
+        @Override
+        public void onActivityStarted(Activity activity) { }
+
+        @Override
+        public void onActivityResumed(Activity activity) { }
+
+        @Override
+        public void onActivityPaused(Activity activity) { }
+
+        @Override
+        public void onActivityStopped(Activity activity) { }
+
+        @Override
+        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
+
+        @Override
+        public void onActivityDestroyed(Activity activity) { }
+
+        @Override
+        public void onViewAttachedToWindow(View view) {
+            view.getViewTreeObserver().addOnDrawListener(new MyViewDrawListener(view.getHandler()));
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View view) { }
+
+        private class MyViewDrawListener implements OnDrawListener, Runnable {
+
+            private final Handler mHandler;
+
+            MyViewDrawListener(Handler handler) {
+                mHandler = handler;
+            }
+
+            @Override
+            public void onDraw() {
+                mCurrentThreadDrawing.set(true);
+                Utilities.postAsyncCallback(mHandler, this);
+            }
+
+            @Override
+            public void run() {
+                mCurrentThreadDrawing.set(false);
+            }
+        }
+
+        private void onBitmapCreated() {
+            if (mCurrentThreadDrawing.get()) {
+                Log.e(TAG, "Bitmap created during draw pass", new Exception());
+            }
+        }
+    }
+
+}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 0c9a28b..fa625ed 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -399,7 +399,8 @@
         Drawable drawable = null;
         Drawable badge = null;
         boolean supportsAdaptiveIcons = ADAPTIVE_ICON_WINDOW_ANIM.get()
-                && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
+                && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+                && !info.isDisabled(); // Use original icon for disabled icons.
         Drawable btvIcon = originalView instanceof BubbleTextView
                 ? ((BubbleTextView) originalView).getIcon() : null;
         if (info instanceof SystemShortcut) {
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
index c3186f6..b6c81ae 100644
--- a/src/com/android/launcher3/views/WorkEduView.java
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -52,8 +52,6 @@
     private static final int WORK_EDU_PERSONAL_APPS = 1;
     private static final int WORK_EDU_WORK_APPS = 2;
 
-    private static LauncherStateManager.StateListener sStateListener;
-
     private Rect mInsets = new Rect();
     private View mViewWrapper;
     private Button mProceedButton;
diff --git a/src/com/android/launcher3/views/WorkFooterContainer.java b/src/com/android/launcher3/views/WorkFooterContainer.java
index fb17b4f..f8add9a 100644
--- a/src/com/android/launcher3/views/WorkFooterContainer.java
+++ b/src/com/android/launcher3/views/WorkFooterContainer.java
@@ -15,32 +15,61 @@
  */
 package com.android.launcher3.views;
 
+import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
+
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.RelativeLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.WorkModeSwitch;
+import com.android.launcher3.pm.UserCache;
 
 /**
  * Container to show work footer in all-apps.
  */
-public class WorkFooterContainer extends RelativeLayout {
+public class WorkFooterContainer extends LinearLayout implements Insettable {
+    private Rect mInsets = new Rect();
+
+    private WorkModeSwitch mWorkModeSwitch;
+    private TextView mWorkModeLabel;
+
+    protected final ObjectAnimator mOpenCloseAnimator;
 
     public WorkFooterContainer(Context context) {
-        super(context);
+        this(context, null, 0);
     }
 
     public WorkFooterContainer(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
     public WorkFooterContainer(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
+        mOpenCloseAnimator = ObjectAnimator.ofPropertyValuesHolder(this);
     }
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
         updateTranslation();
+        this.setVisibility(shouldShowWorkFooter() ? VISIBLE : GONE);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mWorkModeSwitch = findViewById(R.id.work_mode_toggle);
+        mWorkModeLabel = findViewById(R.id.work_mode_label);
     }
 
     @Override
@@ -56,4 +85,44 @@
             setTranslationY(Math.max(0, availableBot - getBottom()));
         }
     }
+
+    @Override
+    public void setInsets(Rect insets) {
+        int bottomInset = insets.bottom - mInsets.bottom;
+        mInsets.set(insets);
+        setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+                getPaddingBottom() + bottomInset);
+    }
+
+    /**
+     * Animates in/out work profile toggle panel based on the tab user is on
+     */
+    public void setWorkTabVisible(boolean workTabVisible) {
+        if (!shouldShowWorkFooter()) return;
+
+        mOpenCloseAnimator.setValues(PropertyValuesHolder.ofFloat(ALPHA, workTabVisible ? 1 : 0));
+        mOpenCloseAnimator.start();
+    }
+
+    /**
+     * Refreshes views based on current work profile enabled status
+     */
+    public void refresh() {
+        if (!shouldShowWorkFooter()) return;
+        boolean anyProfileQuietModeEnabled = UserCache.INSTANCE.get(
+                getContext()).isAnyProfileQuietModeEnabled();
+
+        mWorkModeLabel.setText(anyProfileQuietModeEnabled
+                ? R.string.work_mode_off_label : R.string.work_mode_on_label);
+        mWorkModeLabel.setCompoundDrawablesWithIntrinsicBounds(
+                anyProfileQuietModeEnabled ? R.drawable.ic_corp_off : R.drawable.ic_corp, 0, 0, 0);
+        mWorkModeSwitch.refresh();
+    }
+
+    private boolean shouldShowWorkFooter() {
+        Launcher launcher = Launcher.getLauncher(getContext());
+        return Utilities.ATLEAST_P && (hasShortcutsPermission(launcher)
+                || launcher.checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
+                == PackageManager.PERMISSION_GRANTED);
+    }
 }