Merge "Set disabled state when getting new icon from DrawableFactory." into ub-launcher3-master
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index d5859a7..0e45791 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 3ba0662..a5af173 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3;
 
-import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
 import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
 import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
 import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
@@ -51,6 +50,8 @@
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.graphics.DrawableFactory;
+import com.android.launcher3.shortcuts.DeepShortcutTextView;
+import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.quickstep.RecentsAnimationInterpolator;
 import com.android.quickstep.RecentsAnimationInterpolator.TaskWindowBounds;
 import com.android.quickstep.RecentsView;
@@ -79,7 +80,7 @@
             "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
 
     private static final int RECENTS_LAUNCH_DURATION = 336;
-    private static final int LAUNCHER_RESUME_START_DELAY = 150;
+    private static final int LAUNCHER_RESUME_START_DELAY = 100;
     private static final int CLOSING_TRANSITION_DURATION_MS = 350;
 
     // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
@@ -260,6 +261,7 @@
         int launchedTaskIndex = recentsView.indexOfChild(v);
         int centerTaskIndex = recentsView.getCurrentPage();
         boolean launchingCenterTask = launchedTaskIndex == centerTaskIndex;
+        boolean isRtl = recentsView.isRtl();
         if (launchingCenterTask) {
             if (launchedTaskIndex - 1 >= recentsView.getFirstTaskIndex()) {
                 TaskView adjacentPage1 = (TaskView) recentsView.getPageAt(launchedTaskIndex - 1);
@@ -268,7 +270,7 @@
                                 new PropertyListBuilder()
                                         .scale(adjacentPage1.getScaleX() * mRecentsScale)
                                         .translationY(mRecentsTransY)
-                                        .translationX(mIsRtl ? mRecentsTransX : -mRecentsTransX)
+                                        .translationX(isRtl ? mRecentsTransX : -mRecentsTransX)
                                         .build());
                 launcherAnimator.play(adjacentTask1ScaleAndTranslate);
             }
@@ -279,7 +281,7 @@
                                 new PropertyListBuilder()
                                         .scale(adjacentTask2.getScaleX() * mRecentsScale)
                                         .translationY(mRecentsTransY)
-                                        .translationX(mIsRtl ? -mRecentsTransX : mRecentsTransX)
+                                        .translationX(isRtl ? -mRecentsTransX : mRecentsTransX)
                                         .build());
                 launcherAnimator.play(adjacentTask2ScaleAndTranslate);
             }
@@ -291,7 +293,7 @@
                     LauncherAnimUtils.ofPropertyValuesHolder(centerTask,
                             new PropertyListBuilder()
                                     .scale(v.getScaleX())
-                                    .translationX(mIsRtl ? -translationX : translationX)
+                                    .translationX(isRtl ? -translationX : translationX)
                                     .build());
             launcherAnimator.play(centerTaskParallaxToRight);
             int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - launchedTaskIndex);
@@ -303,7 +305,7 @@
                         LauncherAnimUtils.ofPropertyValuesHolder(otherAdjacentTask,
                                 new PropertyListBuilder()
                                         .translationX(otherAdjacentTask.getTranslationX()
-                                                + (mIsRtl ? -translationX : translationX))
+                                                + (isRtl ? -translationX : translationX))
                                         .build());
                 launcherAnimator.play(otherAdjacentTaskParallaxToRight);
             }
@@ -324,9 +326,6 @@
         launcherAnimator.play(recenterWorkspace);
         CellLayout currentWorkspacePage = (CellLayout) workspace.getPageAt(
                 workspace.getCurrentPage());
-        Animator hideWorkspaceScrim = ObjectAnimator.ofInt(
-                currentWorkspacePage.getScrimBackground(), DRAWABLE_ALPHA, 0);
-        launcherAnimator.play(hideWorkspaceScrim);
 
         launcherAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
         launcherAnimator.setDuration(RECENTS_LAUNCH_DURATION);
@@ -497,7 +496,7 @@
      * @return Animator that controls the icon used to launch the target.
      */
     private AnimatorSet getIconAnimator(View v) {
-        boolean isBubbleTextView = v instanceof BubbleTextView;
+        final boolean isBubbleTextView = v instanceof BubbleTextView;
         mFloatingView = new View(mLauncher);
         if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) {
             // Create a copy of the app icon
@@ -507,14 +506,24 @@
 
         // Position the floating view exactly on top of the original
         Rect rect = new Rect();
-        mDragLayer.getDescendantRectRelativeToSelf(v, rect);
-        int viewLocationStart = mIsRtl
+        final boolean isDeepShortcutTextView = v instanceof DeepShortcutTextView
+                && v.getParent() != null && v.getParent() instanceof DeepShortcutView;
+        if (isDeepShortcutTextView) {
+            // Deep shortcut views have their icon drawn in a sibling view.
+            DeepShortcutView view = (DeepShortcutView) v.getParent();
+            mDragLayer.getDescendantRectRelativeToSelf(view.getIconView(), rect);
+        } else {
+            mDragLayer.getDescendantRectRelativeToSelf(v, rect);
+        }
+        final int viewLocationStart = mIsRtl
                 ? mDeviceProfile.widthPx - rect.right
                 : rect.left;
-        int viewLocationTop = rect.top;
+        final int viewLocationTop = rect.top;
 
-        if (isBubbleTextView) {
+        if (isBubbleTextView && !isDeepShortcutTextView) {
             ((BubbleTextView) v).getIconBounds(rect);
+        } else {
+            rect.set(0, 0, rect.width(), rect.height());
         }
         LayoutParams lp = new LayoutParams(rect.width(), rect.height());
         lp.ignoreInsets = true;
@@ -748,7 +757,7 @@
         Matrix matrix = new Matrix();
         float height = mLauncher.getDeviceProfile().heightPx;
         float width = mLauncher.getDeviceProfile().widthPx;
-        float endX = (Utilities.isRtl(mLauncher.getResources()) ? -width : width) * 1.16f;
+        float endX = (mLauncher.<RecentsView>getOverviewPanel().isRtl() ? -width : width) * 1.16f;
 
         ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
         closingAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 9ba2308..613968e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -26,7 +26,6 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.quickstep.RecentsView;
@@ -111,7 +110,7 @@
                 scale * (halfWidth - ws.getPaddingLeft() - insets.left - childWidth / 2);
         float translationX = pageRect.centerX() - childCenter;
 
-        if (Utilities.isRtl(launcher.getResources())) {
+        if (launcher.<RecentsView>getOverviewPanel().isRtl()) {
             translationX -= offsetX / scale;
         } else {
             translationX += offsetX / scale;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 7d371e9..80ecb92 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -75,7 +75,7 @@
     public void setStateWithAnimation(final LauncherState toState,
             AnimatorSetBuilder builder, AnimationConfig config) {
         boolean settingEnabled = Utilities.getPrefs(mLauncher)
-            .getBoolean("pref_scroll_to_first_task", false);
+            .getBoolean("pref_scroll_to_first_task_default_true", true);
         mIsRecentsScrollingToFirstTask = mLauncher.isInState(NORMAL) && toState == OVERVIEW
                 && settingEnabled;
         // TODO: Instead of animating the workspace translationX, move the contents
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index ec0716c..9e07b49 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -23,6 +23,8 @@
 
 import android.animation.LayoutTransition;
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
@@ -62,7 +64,7 @@
 /**
  * A list of recent tasks.
  */
-public class RecentsView extends PagedView implements Insettable {
+public class RecentsView extends PagedView implements Insettable, OnSharedPreferenceChangeListener {
 
     private static final Rect sTempStableInsets = new Rect();
 
@@ -70,6 +72,8 @@
     public static final int SCROLL_TYPE_TASK = 1;
     public static final int SCROLL_TYPE_WORKSPACE = 2;
 
+    private static final String PREF_FLIP_RECENTS = "pref_flip_recents";
+
     private final Launcher mLauncher;
     private QuickScrubController mQuickScrubController;
     private final ScrollState mScrollState = new ScrollState();
@@ -130,7 +134,23 @@
         mQuickScrubController = new QuickScrubController(mLauncher, this);
         mModel = RecentsModel.getInstance(context);
 
-        mScrollState.isRtl = mIsRtl;
+        onSharedPreferenceChanged(Utilities.getPrefs(context), PREF_FLIP_RECENTS);
+    }
+
+    @Override
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+        if (s.equals(PREF_FLIP_RECENTS)) {
+            mIsRtl = Utilities.isRtl(getResources());
+            if (sharedPreferences.getBoolean(PREF_FLIP_RECENTS, false)) {
+                mIsRtl = !mIsRtl;
+            }
+            setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
+            mScrollState.isRtl = mIsRtl;
+        }
+    }
+
+    public boolean isRtl() {
+        return mIsRtl;
     }
 
     public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData) {
@@ -172,12 +192,14 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         updateTaskStackListenerState();
+        Utilities.getPrefs(getContext()).registerOnSharedPreferenceChangeListener(this);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         updateTaskStackListenerState();
+        Utilities.getPrefs(getContext()).unregisterOnSharedPreferenceChangeListener(this);
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index 75d8619..e172291 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -19,13 +19,18 @@
 import android.app.ActivityOptions;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewTreeObserver.OnPreDrawListener;
 
+import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
@@ -34,9 +39,15 @@
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
+import com.android.systemui.shared.recents.view.RecentsTransition;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.function.Consumer;
 
 /**
@@ -86,9 +97,10 @@
         }
     }
 
-    public static class SplitScreen extends TaskSystemShortcut {
+    public static class SplitScreen extends TaskSystemShortcut implements OnPreDrawListener {
 
         private Handler mHandler;
+        private TaskView mTaskView;
 
         public SplitScreen() {
             super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
@@ -104,22 +116,55 @@
             if (!task.isDockable) {
                 return null;
             }
+            mTaskView = taskView;
             return (v -> {
-                final ActivityOptions options = ActivityOptionsCompat.makeSplitScreenOptions(true);
-                final Consumer<Boolean> resultCallback = success -> {
-                    if (success) {
-                        launcher.<RecentsView>getOverviewPanel().removeView(taskView);
-                    }
-                };
-                ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(
-                        task.key, options, resultCallback, mHandler);
+                AbstractFloatingView.closeOpenViews(launcher, true,
+                        AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
 
-                // TODO improve transition; see:
-                // DockedFirstAnimationFrameEvent
-                // RecentsTransitionHelper#composeDockAnimationSpec
-                // WindowManagerWrapper#overridePendingAppTransitionMultiThumbFuture
+                if (ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key.id,
+                        ActivityOptionsCompat.makeSplitScreenOptions(true))) {
+                    ISystemUiProxy sysUiProxy = RecentsModel.getInstance(launcher).getSystemUiProxy();
+                    try {
+                        sysUiProxy.onSplitScreenInvoked();
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
+                        return;
+                    }
+
+                    final Runnable animStartedListener = () -> {
+                        mTaskView.getViewTreeObserver().addOnPreDrawListener(SplitScreen.this);
+                        launcher.<RecentsView>getOverviewPanel().removeView(taskView);
+                    };
+
+                    final int[] position = new int[2];
+                    taskView.getLocationOnScreen(position);
+                    final int width = (int) (taskView.getWidth() * taskView.getScaleX());
+                    final int height = (int) (taskView.getHeight() * taskView.getScaleY());
+                    final Rect taskBounds = new Rect(position[0], position[1],
+                            position[0] + width, position[1] + height);
+
+                    Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
+                            taskBounds.width(), taskBounds.height(), taskView, 1f, Color.BLACK);
+                    AppTransitionAnimationSpecsFuture future =
+                            new AppTransitionAnimationSpecsFuture(mHandler) {
+                        @Override
+                        public List<AppTransitionAnimationSpecCompat> composeSpecs() {
+                            return Collections.singletonList(new AppTransitionAnimationSpecCompat(
+                                    task.key.id, thumbnail, taskBounds));
+                        }
+                    };
+                    WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
+                            future, animStartedListener, mHandler, true /* scaleUp */);
+                }
             });
         }
+
+        @Override
+        public boolean onPreDraw() {
+            mTaskView.getViewTreeObserver().removeOnPreDrawListener(this);
+            WindowManagerWrapper.getInstance().endProlongedAnimations();
+            return true;
+        }
     }
 
     public static class Pin extends TaskSystemShortcut {
diff --git a/res/drawable/round_rect_primary.xml b/res/drawable/round_rect_primary.xml
index 9f8f4da..16310f8 100644
--- a/res/drawable/round_rect_primary.xml
+++ b/res/drawable/round_rect_primary.xml
@@ -17,5 +17,5 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
     <solid android:color="?android:attr/colorPrimary" />
-    <corners android:radius="8dp" />
+    <corners android:radius="@dimen/bg_round_rect_radius" />
 </shape>
diff --git a/res/drawable/top_round_rect_primary.xml b/res/drawable/top_round_rect_primary.xml
new file mode 100644
index 0000000..1caaa02
--- /dev/null
+++ b/res/drawable/top_round_rect_primary.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorPrimary" />
+    <corners
+        android:topLeftRadius="@dimen/bg_round_rect_radius"
+        android:topRightRadius="@dimen/bg_round_rect_radius"
+        android:bottomLeftRadius="0dp"
+        android:bottomRightRadius="0dp"
+        />
+</shape>
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index e8c6961..6bf9048 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -20,7 +20,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingTop="28dp"
-    android:background="?android:attr/colorPrimary"
+    android:background="@drawable/top_round_rect_primary"
     android:elevation="@dimen/deep_shortcuts_elevation"
     android:layout_gravity="bottom"
     android:theme="?attr/widgetsTheme">
diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml
index 1535299..20eca9f 100644
--- a/res/layout/widgets_full_sheet.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -25,7 +25,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
 
-    <FrameLayout
+    <com.android.launcher3.views.TopRoundedCornerView
         android:id="@+id/container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -60,5 +60,5 @@
             android:layout_gravity="bottom"
             android:background="?attr/allAppsNavBarScrimColor"
             android:focusable="false"  />
-    </FrameLayout>
+    </com.android.launcher3.views.TopRoundedCornerView>
 </com.android.launcher3.widget.WidgetsFullSheet>
\ No newline at end of file
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 55bfef6..5ac53a8 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -408,6 +408,11 @@
         if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
             mUserEventDispatcher = null;
             initDeviceProfile(mDeviceProfile.inv);
+            FileLog.d(TAG, "Config changed, my orientation=" +
+                    getResources().getConfiguration().orientation +
+                    ", new orientation=" + newConfig.orientation +
+                    ", old orientation=" + mOldConfig.orientation +
+                    ", isTransposed=" + mDeviceProfile.isVerticalBarLayout());
             dispatchDeviceProfileChanged();
 
             getRootView().dispatchInsets();
@@ -2234,6 +2239,7 @@
         // Clear the workspace because it's going to be rebound
         mWorkspace.clearDropTargets();
         mWorkspace.removeAllWorkspaceScreens();
+        mAppWidgetHost.clearViews();
 
         if (mHotseat != null) {
             mHotseat.resetLayout();
@@ -2752,18 +2758,20 @@
                     writer.println(prefix + "    " + tag.toString());
                 }
             }
-
-            try {
-                FileLog.flushAll(writer);
-            } catch (Exception e) {
-                // Ignore
-            }
         }
 
         writer.println(prefix + "Misc:");
         writer.print(prefix + "\tmWorkspaceLoading=" + mWorkspaceLoading);
         writer.print(" mPendingRequestArgs=" + mPendingRequestArgs);
         writer.println(" mPendingActivityResult=" + mPendingActivityResult);
+        writer.println(" deviceProfile isTransposed=" + getDeviceProfile().isVerticalBarLayout());
+        writer.println(" orientation=" + getResources().getConfiguration().orientation);
+
+        try {
+            FileLog.flushAll(writer);
+        } catch (Exception e) {
+            // Ignore
+        }
 
         mModel.dumpState(prefix, fd, writer, args);
 
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 7bc7139..56671a1 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -236,7 +236,7 @@
     }
 
     @Override
-    protected void clearViews() {
+    public void clearViews() {
         super.clearViews();
         mViews.clear();
     }
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 138ea0f..acad901 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -56,10 +56,10 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.DbDowngradeHelper;
+import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.provider.LauncherDbUtils;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.provider.RestoreDbTask;
-import com.android.launcher3.util.ManagedProfileHeuristic;
 import com.android.launcher3.util.NoLocaleSqliteContext;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Thunk;
@@ -320,6 +320,11 @@
 
     @Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
+        if (ModelWriter.DEBUG_DELETE) {
+            String args = selectionArgs == null ? null : TextUtils.join(",", selectionArgs);
+            FileLog.d(TAG, "Delete uri=" + uri + ", selection=" + selection
+                    + ", selectionArgs=" + args, new Exception());
+        }
         createDbIfNotExists();
         SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
 
@@ -623,10 +628,6 @@
 
             // Set the flag for empty DB
             Utilities.getPrefs(mContext).edit().putBoolean(EMPTY_DATABASE_CREATED, true).commit();
-
-            // When a new DB is created, remove all previously stored managed profile information.
-            ManagedProfileHeuristic.processAllUsers(Collections.<UserHandle>emptyList(),
-                    mContext);
         }
 
         public long getDefaultUserSerial() {
@@ -790,7 +791,7 @@
                 case 23:
                     // No-op
                 case 24:
-                    ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mContext);
+                    // No-op
                 case 25:
                     convertShortcutsToLauncherActivities(db);
                 case 26:
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 4be32b2..ca8039c 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -64,9 +64,6 @@
     private static final boolean DEBUG = false;
     protected static final int INVALID_PAGE = -1;
 
-    // the min drag distance for a fling to register, to prevent random page shifts
-    private static final int MIN_LENGTH_FOR_FLING = 25;
-
     public static final int PAGE_SNAP_ANIMATION_DURATION = 750;
     public static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
 
@@ -182,7 +179,7 @@
     private static final Rect sTmpRect = new Rect();
 
     protected final Rect mInsets = new Rect();
-    protected final boolean mIsRtl;
+    protected boolean mIsRtl;
 
     // Similar to the platform implementation of isLayoutValid();
     protected boolean mIsLayoutValid;
@@ -1312,9 +1309,7 @@
                         SIGNIFICANT_MOVE_THRESHOLD;
 
                 mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
-
-                boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
-                        shouldFlingForVelocity(velocityX);
+                boolean isFling = mTotalMotionX > mTouchSlop && shouldFlingForVelocity(velocityX);
 
                 if (!mFreeScroll) {
                     // In the case that the page is moved far to one direction and then is flung
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index edb7ff5..b0da6b9 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -67,11 +67,9 @@
         SessionInfo info = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
         UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
 
-        if (Process.myUserHandle().equals(user)) {
-            if (TextUtils.isEmpty(info.getAppPackageName()) ||
-                    info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
-                return;
-            }
+        if (TextUtils.isEmpty(info.getAppPackageName()) ||
+                info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
+            return;
         }
 
         queueAppIconAddition(context, info.getAppPackageName(), user);
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index 62055dc..03e3861 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -58,7 +58,6 @@
     public abstract long getSerialNumberForUser(UserHandle user);
     public abstract UserHandle getUserForSerialNumber(long serialNumber);
     public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user);
-    public abstract long getUserCreationTime(UserHandle user);
     public abstract boolean isQuietModeEnabled(UserHandle user);
     public abstract boolean isUserUnlocked(UserHandle user);
 
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index e57786d..1ff6981 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -23,7 +23,6 @@
 import android.os.UserManager;
 import android.util.ArrayMap;
 import com.android.launcher3.util.LongArrayMap;
-import com.android.launcher3.util.ManagedProfileHeuristic;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -127,15 +126,5 @@
         }
         return mPm.getUserBadgedLabel(label, user);
     }
-
-    @Override
-    public long getUserCreationTime(UserHandle user) {
-        SharedPreferences prefs = ManagedProfileHeuristic.prefs(mContext);
-        String key = USER_CREATION_TIME_KEY + getSerialNumberForUser(user);
-        if (!prefs.contains(key)) {
-            prefs.edit().putLong(key, System.currentTimeMillis()).apply();
-        }
-        return prefs.getLong(key, 0);
-    }
 }
 
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVM.java b/src/com/android/launcher3/compat/UserManagerCompatVM.java
index 75c1877..cf74b37 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVM.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVM.java
@@ -27,9 +27,4 @@
     UserManagerCompatVM(Context context) {
         super(context);
     }
-
-    @Override
-    public long getUserCreationTime(UserHandle user) {
-        return mUserManager.getUserCreationTime(user);
-    }
 }
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index a33a039..fefe07d 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -17,10 +17,7 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.LauncherActivityInfo;
-import android.os.Process;
 import android.os.UserHandle;
-import android.util.ArrayMap;
 import android.util.LongSparseArray;
 import android.util.Pair;
 import com.android.launcher3.AllAppsList;
@@ -37,7 +34,6 @@
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.GridOccupancy;
-import com.android.launcher3.util.ManagedProfileHeuristic.UserFolderInfo;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -64,7 +60,6 @@
 
         final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
         final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<>();
-        ArrayMap<UserHandle, UserFolderInfo> userFolderMap = new ArrayMap<>();
 
         // Get the list of workspace screens.  We need to append to this list and
         // can not use sBgWorkspaceScreens because loadWorkspace() may not have been
@@ -87,21 +82,6 @@
                     if (item instanceof AppInfo) {
                         item = ((AppInfo) item).makeShortcut();
                     }
-
-                    if (!Process.myUserHandle().equals(item.user)) {
-                        // Check if this belongs to a work folder.
-                        if (!(entry.second instanceof LauncherActivityInfo)) {
-                            continue;
-                        }
-
-                        UserFolderInfo userFolderInfo = userFolderMap.get(item.user);
-                        if (userFolderInfo == null) {
-                            userFolderInfo = new UserFolderInfo(context, item.user, dataModel);
-                            userFolderMap.put(item.user, userFolderInfo);
-                        }
-                        item = userFolderInfo.convertToWorkspaceItem(
-                                (ShortcutInfo) item, (LauncherActivityInfo) entry.second);
-                    }
                 }
                 if (item != null) {
                     filteredItems.add(item);
@@ -160,10 +140,6 @@
                 }
             });
         }
-
-        for (UserFolderInfo userFolderInfo : userFolderMap.values()) {
-            userFolderInfo.applyPendingState(getModelWriter());
-        }
     }
 
     protected void updateScreens(Context context, ArrayList<Long> workspaceScreens) {
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 00dd3aa..c615050 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -62,7 +62,6 @@
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.LooperIdleLock;
-import com.android.launcher3.util.ManagedProfileHeuristic;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.Provider;
@@ -812,8 +811,6 @@
                 // This builds the icon bitmaps.
                 mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
             }
-
-            ManagedProfileHeuristic.onAllAppsLoaded(mApp.getContext(), apps, user);
         }
 
         if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 032ed78..40e0f49 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -32,6 +32,7 @@
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.LauncherSettings.Settings;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LooperExecutor;
@@ -46,6 +47,7 @@
 public class ModelWriter {
 
     private static final String TAG = "ModelWriter";
+    public static final boolean DEBUG_DELETE = true;
 
     private final Context mContext;
     private final BgDataModel mBgDataModel;
@@ -243,14 +245,21 @@
      * Removes the specified items from the database
      */
     public void deleteItemsFromDatabase(final Iterable<? extends ItemInfo> items) {
-        mWorkerExecutor.execute(new Runnable() {
-            public void run() {
-                for (ItemInfo item : items) {
-                    final Uri uri = Favorites.getContentUri(item.id);
-                    mContext.getContentResolver().delete(uri, null, null);
+        if (DEBUG_DELETE) {
+            // Log it on the colling thread to get the proper stack trace
+            FileLog.d(TAG, "Starting item deletion", new Exception());
+            for (ItemInfo item : items) {
+                FileLog.d(TAG, "deleting item " + item);
+            }
+            FileLog.d(TAG, "Finished deleting items");
+        }
 
-                    mBgDataModel.removeItem(mContext, item);
-                }
+        mWorkerExecutor.execute(() -> {
+            for (ItemInfo item : items) {
+                final Uri uri = Favorites.getContentUri(item.id);
+                mContext.getContentResolver().delete(uri, null, null);
+
+                mBgDataModel.removeItem(mContext, item);
             }
         });
     }
@@ -259,17 +268,20 @@
      * Remove the specified folder and all its contents from the database.
      */
     public void deleteFolderAndContentsFromDatabase(final FolderInfo info) {
-        mWorkerExecutor.execute(new Runnable() {
-            public void run() {
-                ContentResolver cr = mContext.getContentResolver();
-                cr.delete(LauncherSettings.Favorites.CONTENT_URI,
-                        LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
-                mBgDataModel.removeItem(mContext, info.contents);
-                info.contents.clear();
+        if (DEBUG_DELETE) {
+            // Log it on the colling thread to get the proper stack trace
+            FileLog.d(TAG, "Deleting folder " + info, new Exception());
+        }
 
-                cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
-                mBgDataModel.removeItem(mContext, info);
-            }
+        mWorkerExecutor.execute(() -> {
+            ContentResolver cr = mContext.getContentResolver();
+            cr.delete(LauncherSettings.Favorites.CONTENT_URI,
+                    LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
+            mBgDataModel.removeItem(mContext, info.contents);
+            info.contents.clear();
+
+            cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
+            mBgDataModel.removeItem(mContext, info);
         });
     }
 
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
deleted file mode 100644
index 009aee7..0000000
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2015 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.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.LauncherActivityInfo;
-import android.os.Handler;
-import android.os.Process;
-import android.os.UserHandle;
-
-import com.android.launcher3.FolderInfo;
-import com.android.launcher3.InstallShortcutReceiver;
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.LauncherFiles;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.MainThreadExecutor;
-import com.android.launcher3.R;
-import com.android.launcher3.SessionCommitReceiver;
-import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.model.ModelWriter;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Handles addition of app shortcuts for managed profiles.
- * Methods of class should only be called on {@link LauncherModel#sWorkerThread}.
- */
-public class ManagedProfileHeuristic {
-
-    private static final String USER_FOLDER_ID_PREFIX = "user_folder_";
-
-    /**
-     * Duration (in milliseconds) for which app shortcuts will be added to work folder.
-     */
-    private static final long AUTO_ADD_TO_FOLDER_DURATION = 8 * 60 * 60 * 1000;
-
-    public static void onAllAppsLoaded(final Context context,
-            List<LauncherActivityInfo> apps, UserHandle user) {
-        if (Process.myUserHandle().equals(user)) {
-            return;
-        }
-
-        UserFolderInfo ufi = new UserFolderInfo(context, user, null);
-        // We only handle folder creation once. Later icon additions are handled using package
-        // or session events.
-        if (ufi.folderAlreadyCreated) {
-            return;
-        }
-
-        if (Utilities.ATLEAST_OREO && !SessionCommitReceiver.isEnabled(context)) {
-            // Just mark the folder id preference to avoid new folder creation later.
-            ufi.prefs.edit().putLong(ufi.folderIdKey, ItemInfo.NO_ID).apply();
-            return;
-        }
-
-        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_BULK_ADD);
-        for (LauncherActivityInfo app : apps) {
-            // Queue all items which should go in the work folder.
-            if (app.getFirstInstallTime() < ufi.addIconToFolderTime) {
-                InstallShortcutReceiver.queueActivityInfo(app, context);
-            }
-        }
-        // Post the queue update on next frame, so that the loader gets finished.
-        new Handler(LauncherModel.getWorkerLooper()).post(new Runnable() {
-            @Override
-            public void run() {
-                InstallShortcutReceiver.disableAndFlushInstallQueue(
-                        InstallShortcutReceiver.FLAG_BULK_ADD, context);
-            }
-        });
-    }
-
-
-    /**
-     * Utility class to help workspace icon addition.
-     */
-    public static class UserFolderInfo {
-
-        final ArrayList<ShortcutInfo> pendingShortcuts = new ArrayList<>();
-
-        final UserHandle user;
-
-        final long userSerial;
-        // Time until which icons will be added to folder instead.
-        final long addIconToFolderTime;
-
-        final String folderIdKey;
-        final SharedPreferences prefs;
-
-        final boolean folderAlreadyCreated;
-        final FolderInfo folderInfo;
-
-        boolean folderPendingAddition;
-
-        public UserFolderInfo(Context context, UserHandle user, BgDataModel dataModel) {
-            this.user = user;
-
-            UserManagerCompat um = UserManagerCompat.getInstance(context);
-            userSerial = um.getSerialNumberForUser(user);
-            addIconToFolderTime = um.getUserCreationTime(user) + AUTO_ADD_TO_FOLDER_DURATION;
-
-            folderIdKey = USER_FOLDER_ID_PREFIX + userSerial;
-            prefs = prefs(context);
-
-            folderAlreadyCreated = prefs.contains(folderIdKey);
-            if (dataModel != null) {
-                if (folderAlreadyCreated) {
-                    long folderId = prefs.getLong(folderIdKey, ItemInfo.NO_ID);
-                    folderInfo = dataModel.folders.get(folderId);
-                } else {
-                    folderInfo = new FolderInfo();
-                    folderInfo.title = context.getText(R.string.work_folder_name);
-                    folderInfo.setOption(FolderInfo.FLAG_WORK_FOLDER, true, null);
-                    folderPendingAddition = true;
-                }
-            } else {
-                folderInfo = null;
-            }
-        }
-
-        /**
-         * Returns the ItemInfo which should be added to the workspace. In case the the provided
-         * {@link ShortcutInfo} or a wrapped {@link FolderInfo} or null.
-         */
-        public ItemInfo convertToWorkspaceItem(
-                ShortcutInfo shortcut, LauncherActivityInfo activityInfo) {
-            if (activityInfo.getFirstInstallTime() >= addIconToFolderTime) {
-                return shortcut;
-            }
-
-            if (folderAlreadyCreated) {
-                if (folderInfo == null) {
-                    // Work folder was deleted by user, add icon to home screen.
-                    return shortcut;
-                } else {
-                    // Add item to work folder instead. Nothing needs to be added
-                    // on the homescreen.
-                    pendingShortcuts.add(shortcut);
-                    return null;
-                }
-            }
-
-            pendingShortcuts.add(shortcut);
-            folderInfo.add(shortcut, false);
-            if (folderPendingAddition) {
-                folderPendingAddition = false;
-                return folderInfo;
-            } else {
-                // WorkFolder already requested to be added. Nothing new needs to be added.
-                return null;
-            }
-        }
-
-        public void applyPendingState(ModelWriter writer) {
-            if (folderInfo == null) {
-                return;
-            }
-
-            int startingRank = 0;
-            if (folderAlreadyCreated) {
-                startingRank = folderInfo.contents.size();
-            }
-
-            for (ShortcutInfo info : pendingShortcuts) {
-                info.rank = startingRank++;
-                writer.addItemToDatabase(info, folderInfo.id, 0, 0, 0);
-            }
-
-            if (folderAlreadyCreated) {
-                // FolderInfo could already be bound. We need to add shortcuts on the UI thread.
-                new MainThreadExecutor().execute(new Runnable() {
-
-                    @Override
-                    public void run() {
-                        folderInfo.prepareAutoUpdate();
-                        for (ShortcutInfo info : pendingShortcuts) {
-                            folderInfo.add(info, false);
-                        }
-                    }
-                });
-            } else {
-                prefs.edit().putLong(folderIdKey, folderInfo.id).apply();
-            }
-        }
-    }
-
-    /**
-     * Verifies that entries corresponding to {@param users} exist and removes all invalid entries.
-     */
-    public static void processAllUsers(List<UserHandle> users, Context context) {
-        UserManagerCompat userManager = UserManagerCompat.getInstance(context);
-        HashSet<String> validKeys = new HashSet<>();
-        for (UserHandle user : users) {
-            validKeys.add(USER_FOLDER_ID_PREFIX + userManager.getSerialNumberForUser(user));
-        }
-
-        SharedPreferences prefs = prefs(context);
-        SharedPreferences.Editor editor = prefs.edit();
-        for (String key : prefs.getAll().keySet()) {
-            if (!validKeys.contains(key)) {
-                editor.remove(key);
-            }
-        }
-        editor.apply();
-    }
-
-    /**
-     * For each user, if a work folder has not been created, mark it such that the folder will
-     * never get created.
-     */
-    public static void markExistingUsersForNoFolderCreation(Context context) {
-        UserManagerCompat userManager = UserManagerCompat.getInstance(context);
-        UserHandle myUser = Process.myUserHandle();
-
-        SharedPreferences prefs = null;
-        for (UserHandle user : userManager.getUserProfiles()) {
-            if (myUser.equals(user)) {
-                continue;
-            }
-            if (prefs == null) {
-                prefs = prefs(context);
-            }
-            String folderIdKey = USER_FOLDER_ID_PREFIX + userManager.getSerialNumberForUser(user);
-            if (!prefs.contains(folderIdKey)) {
-                prefs.edit().putLong(folderIdKey, ItemInfo.NO_ID).apply();
-            }
-        }
-    }
-
-    public static SharedPreferences prefs(Context context) {
-        return context.getSharedPreferences(
-                LauncherFiles.MANAGED_USER_PREFERENCES_KEY, Context.MODE_PRIVATE);
-    }
-}
diff --git a/src/com/android/launcher3/views/TopRoundedCornerView.java b/src/com/android/launcher3/views/TopRoundedCornerView.java
new file mode 100644
index 0000000..ba223c4
--- /dev/null
+++ b/src/com/android/launcher3/views/TopRoundedCornerView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import com.android.launcher3.R;
+
+/**
+ * View with top rounded corners.
+ */
+public class TopRoundedCornerView extends FrameLayout {
+
+    private final RectF mRect = new RectF();
+    private final Path mClipPath = new Path();
+    private float[] mRadii;
+
+    public TopRoundedCornerView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        int radius = getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
+        mRadii = new float[] {radius, radius, radius, radius, 0, 0, 0, 0};
+    }
+
+    public TopRoundedCornerView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        canvas.save();
+        canvas.clipPath(mClipPath);
+        super.draw(canvas);
+        canvas.restore();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        mRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
+        mClipPath.reset();
+        mClipPath.addRoundRect(mRect, mRadii, Path.Direction.CW);
+    }
+}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 0b1474a..9d74218 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -488,13 +488,14 @@
         // Only reinflate when the final configuration is same as the required configuration
         if (mReinflateOnConfigChange && isSameOrientation()) {
             mReinflateOnConfigChange = false;
-            if (isAttachedToWindow()) {
-                reInflate();
-            }
+            reInflate();
         }
     }
 
     public void reInflate() {
+        if (!isAttachedToWindow()) {
+            return;
+        }
         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
         // Remove and rebind the current widget (which was inflated in the wrong
         // orientation), but don't delete it from the database
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index d62a909..e461afc 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -115,6 +115,7 @@
             mGradientView.setVisibility(View.INVISIBLE);
             widthUsed = 0;
         } else {
+            mGradientView.setVisibility(View.VISIBLE);
             Rect padding = mLauncher.getDeviceProfile().workspacePadding;
             widthUsed = Math.max(padding.left + padding.right,
                     2 * (mInsets.left + mInsets.right));
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 1be33d2..9e55127 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -15,6 +15,9 @@
  */
 package com.android.launcher3.ui;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
 import android.app.Instrumentation;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -34,7 +37,6 @@
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
 import android.view.MotionEvent;
-
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.LauncherSettings;
@@ -46,17 +48,11 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.testcomponent.AppWidgetNoConfig;
 import com.android.launcher3.testcomponent.AppWidgetWithConfig;
-import com.android.launcher3.util.ManagedProfileHeuristic;
-
-import org.junit.Before;
-
 import java.util.Locale;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import org.junit.Before;
 
 /**
  * Base class for all instrumentation tests providing various utility methods.
@@ -221,7 +217,6 @@
             mMainThreadExecutor.execute(new Runnable() {
                 @Override
                 public void run() {
-                    ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext);
                     LauncherAppState.getInstance(mTargetContext).getModel().forceReload();
                 }
             });