Merge "Show icon in PendingAppWidgetHostView immediately." into ub-launcher3-dorval-polish
diff --git a/res/drawable-xxhdpi/all_apps_alpha_mask.png b/res/drawable-xxhdpi/all_apps_alpha_mask.png
new file mode 100644
index 0000000..ed53ff9
--- /dev/null
+++ b/res/drawable-xxhdpi/all_apps_alpha_mask.png
Binary files differ
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 6c1b1d3..565728c 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -32,6 +32,8 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
+        <include layout="@layout/gradient_scrim" />
+
         <!-- The workspace contains 5 screens of cells -->
         <!-- DO NOT CHANGE THE ID -->
         <com.android.launcher3.Workspace
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 1fdf546..eccb824 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -33,6 +33,8 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
+        <include layout="@layout/gradient_scrim" />
+
         <!-- The workspace contains 5 screens of cells -->
         <!-- DO NOT CHANGE THE ID -->
         <com.android.launcher3.Workspace
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 9ef3394..7fad517 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -32,6 +32,8 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
+        <include layout="@layout/gradient_scrim" />
+
         <!-- The workspace contains 5 screens of cells -->
         <!-- DO NOT CHANGE THE ID -->
         <com.android.launcher3.Workspace
diff --git a/res/layout/gradient_scrim.xml b/res/layout/gradient_scrim.xml
new file mode 100644
index 0000000..02c39eb
--- /dev/null
+++ b/res/layout/gradient_scrim.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <com.android.launcher3.graphics.RadialGradientView
+        android:id="@+id/gradient_bg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone"
+        app:layout_ignoreInsets="true"/>
+
+    <com.android.launcher3.graphics.ScrimView
+        android:id="@+id/scrim_bg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone"
+        app:layout_ignoreInsets="true"/>
+</merge>
\ No newline at end of file
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 128d956..ab82c98 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -72,7 +72,9 @@
         mBackgroundColor = ColorUtils.setAlphaComponent(
                 Themes.getAttrColor(context, android.R.attr.colorPrimary), 0);
         mBackground = new ColorDrawable(mBackgroundColor);
-        setBackground(mBackground);
+        if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            setBackground(mBackground);
+        }
     }
 
     public CellLayout getLayout() {
@@ -179,6 +181,10 @@
     }
 
     public void updateColor(ExtractedColors extractedColors, boolean animate) {
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            // not hotseat visible
+            return;
+        }
         if (!mHasVerticalHotseat) {
             int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX);
             if (mBackgroundColorAnimator != null) {
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 7b3bded..f088d11 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -19,6 +19,8 @@
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
+import android.graphics.Rect;
+import android.os.Bundle;
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -58,12 +60,16 @@
      */
     public static boolean startDetailsActivityForInfo(
             ItemInfo info, Launcher launcher, DropTargetResultCallback callback) {
+        return startDetailsActivityForInfo(info, launcher, callback, null, null);
+    }
+
+    public static boolean startDetailsActivityForInfo(ItemInfo info, Launcher launcher,
+            DropTargetResultCallback callback, Rect sourceBounds, Bundle opts) {
         if (info instanceof PromiseAppInfo) {
             PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
             launcher.startActivity(promiseAppInfo.getMarketIntent());
             return true;
         }
-
         boolean result = false;
         ComponentName componentName = null;
         if (info instanceof AppInfo) {
@@ -78,7 +84,7 @@
         if (componentName != null) {
             try {
                 LauncherAppsCompat.getInstance(launcher)
-                        .showAppDetailsForProfile(componentName, info.user);
+                        .showAppDetailsForProfile(componentName, info.user, sourceBounds, opts);
                 result = true;
             } catch (SecurityException | ActivityNotFoundException e) {
                 Toast.makeText(launcher, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3a50bd1..0d1e9e1 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -466,7 +466,9 @@
     @Override
     public void onExtractedColorsChanged() {
         loadExtractedColorsAndColorItems();
-
+        if (mAllAppsController != null) {
+            mAllAppsController.onExtractedColorsChanged();
+        }
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onExtractedColorsChanged();
         }
@@ -2682,7 +2684,7 @@
     }
 
     @TargetApi(Build.VERSION_CODES.M)
-    private Bundle getActivityLaunchOptions(View v) {
+    public Bundle getActivityLaunchOptions(View v) {
         if (Utilities.ATLEAST_MARSHMALLOW) {
             int left = 0, top = 0;
             int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
@@ -2708,7 +2710,7 @@
         return null;
     }
 
-    private Rect getViewBounds(View v) {
+    public Rect getViewBounds(View v) {
         int[] pos = new int[2];
         v.getLocationOnScreen(pos);
         return new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight());
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index ca789d4..09fb953 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -125,6 +125,7 @@
         // always available in the main process.
         FileLog.setDir(getContext().getApplicationContext().getFilesDir());
         IconShapeOverride.apply(getContext());
+        SessionCommitReceiver.applyDefaultUserPrefs(getContext());
         return true;
     }
 
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 69695ae..61bcc17 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -23,8 +24,15 @@
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -35,26 +43,32 @@
 /**
  * BroadcastReceiver to handle session commit intent.
  */
+@TargetApi(Build.VERSION_CODES.O)
 public class SessionCommitReceiver extends BroadcastReceiver {
 
-    private static final long SESSION_IGNORE_DURATION = 3 * 60 * 60 * 1000; // 3 hours
+    private static final String TAG = "SessionCommitReceiver";
+
+    // The content provider for the add to home screen setting. It should be of the format:
+    // <package name>.addtohomescreen
+    private static final String MARKER_PROVIDER_PREFIX = ".addtohomescreen";
 
     // Preference key for automatically adding icon to homescreen.
     public static final String ADD_ICON_PREFERENCE_KEY = "pref_add_icon_to_home";
-
-    private static final String KEY_FIRST_TIME = "first_session_broadcast_time";
+    public static final String ADD_ICON_PREFERENCE_INITIALIZED_KEY =
+            "pref_add_icon_to_home_initialized";
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        if (!isEnabled(context)) {
+        if (!isEnabled(context) || !Utilities.isAtLeastO()) {
             // User has decided to not add icons on homescreen.
             return;
         }
 
         SessionInfo info = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
         UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
-        // TODO: Verify install reason
-        if (TextUtils.isEmpty(info.getAppPackageName())) {
+
+        if (TextUtils.isEmpty(info.getAppPackageName()) ||
+                info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
             return;
         }
 
@@ -63,17 +77,6 @@
             return;
         }
 
-        // STOPSHIP: Remove this workaround when we start getting proper install reason
-        SharedPreferences prefs = context
-                .getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0);
-        long now = System.currentTimeMillis();
-        long firstTime = prefs.getLong(KEY_FIRST_TIME, now);
-        prefs.edit().putLong(KEY_FIRST_TIME, firstTime).apply();
-        if ((now - firstTime) < SESSION_IGNORE_DURATION) {
-            Log.d("SessionCommitReceiver", "Temporarily ignoring session broadcast");
-            return;
-        }
-
         List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
                 .getActivityList(info.getAppPackageName(), user);
         if (activities == null || activities.isEmpty()) {
@@ -86,4 +89,68 @@
     public static boolean isEnabled(Context context) {
         return Utilities.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true);
     }
+
+    public static void applyDefaultUserPrefs(final Context context) {
+        if (!Utilities.isAtLeastO()) {
+            return;
+        }
+        SharedPreferences prefs = Utilities.getPrefs(context);
+        if (prefs.getAll().isEmpty()) {
+            // This logic assumes that the code is the first thing that is executed (before any
+            // shared preference is written).
+            // TODO: Move this logic to DB upgrade once we have proper support for db downgrade
+            // If it is a fresh start, just apply the default value. We use prefs.isEmpty() to infer
+            // a fresh start as put preferences always contain some values corresponding to current
+            // grid.
+            prefs.edit().putBoolean(ADD_ICON_PREFERENCE_KEY, true).apply();
+        } else if (!prefs.contains(ADD_ICON_PREFERENCE_INITIALIZED_KEY)) {
+            new PrefInitTask(context).executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
+        }
+    }
+
+    private static class PrefInitTask extends AsyncTask<Void, Void, Void> {
+        private final Context mContext;
+
+        PrefInitTask(Context context) {
+            mContext = context;
+        }
+
+        @Override
+        protected Void doInBackground(Void... voids) {
+            boolean addIconToHomeScreenEnabled = readValueFromMarketApp();
+            Utilities.getPrefs(mContext).edit()
+                    .putBoolean(ADD_ICON_PREFERENCE_KEY, addIconToHomeScreenEnabled)
+                    .putBoolean(ADD_ICON_PREFERENCE_INITIALIZED_KEY, true)
+                    .apply();
+            return null;
+        }
+
+        public boolean readValueFromMarketApp() {
+            // Get the marget package
+            ResolveInfo ri = mContext.getPackageManager().resolveActivity(
+                    new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET),
+                    PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_SYSTEM_ONLY);
+            if (ri == null) {
+                return true;
+            }
+
+            Cursor c = null;
+            try {
+                c = mContext.getContentResolver().query(
+                        Uri.parse("content://" + ri.activityInfo.packageName
+                                + MARKER_PROVIDER_PREFIX),
+                        null, null, null, null);
+                if (c.moveToNext()) {
+                    return c.getInt(c.getColumnIndexOrThrow(Settings.NameValueTable.VALUE)) != 0;
+                }
+            } catch (Exception e) {
+                Log.d(TAG, "Error reading add to homescreen preference", e);
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
+            }
+            return true;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 776ec2f..54e7dd2 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -28,6 +28,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -645,4 +646,28 @@
         hashSet.add(elem);
         return hashSet;
     }
+
+    /**
+     * @return creates a new alpha mask bitmap out of an existing bitmap
+     */
+    public static Bitmap convertToAlphaMask(Bitmap b, float applyAlpha) {
+        Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8);
+        Canvas c = new Canvas(a);
+        Paint paint = new Paint();
+        paint.setAlpha((int) (255f * applyAlpha));
+        c.drawBitmap(b, 0f, 0f, paint);
+        return a;
+    }
+
+    /**
+     * @return a new white 1x1 bitmap with ALPHA_8
+     */
+    public static Bitmap createOnePixBitmap() {
+        Bitmap a = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+        Canvas c = new Canvas(a);
+        Paint paint = new Paint();
+        paint.setColor(Color.WHITE);
+        c.drawPaint(paint);
+        return a;
+    }
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index c525cd4..f66995f 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -27,7 +27,6 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.support.annotation.Nullable;
-import android.support.v4.graphics.ColorUtils;
 import android.util.Log;
 import android.util.LongSparseArray;
 
@@ -388,10 +387,10 @@
             drawable.setBounds(x, 0, x + previewWidth, previewHeight);
             drawable.draw(c);
         } else {
-            final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-            RectF boxRect = drawBoxWithShadow(c, p, previewWidth, previewHeight);
+            RectF boxRect = drawBoxWithShadow(c, previewWidth, previewHeight);
 
             // Draw horizontal and vertical lines to represent individual columns.
+            final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
             p.setStyle(Paint.Style.STROKE);
             p.setStrokeWidth(mContext.getResources()
                     .getDimension(R.dimen.widget_preview_cell_divider_width));
@@ -431,7 +430,7 @@
         return preview;
     }
 
-    private RectF drawBoxWithShadow(Canvas c, Paint p, int width, int height) {
+    private RectF drawBoxWithShadow(Canvas c, int width, int height) {
         Resources res = mContext.getResources();
         float shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur);
         float keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance);
@@ -439,19 +438,7 @@
 
         RectF bounds = new RectF(shadowBlur, shadowBlur,
                 width - shadowBlur, height - shadowBlur - keyShadowDistance);
-        p.setColor(Color.WHITE);
-
-        // Key shadow
-        p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
-                ShadowGenerator.KEY_SHADOW_ALPHA << 24);
-        c.drawRoundRect(bounds, corner, corner, p);
-
-        // Ambient shadow
-        p.setShadowLayer(shadowBlur, 0, 0,
-                ColorUtils.setAlphaComponent(Color.BLACK, ShadowGenerator.AMBIENT_SHADOW_ALPHA));
-        c.drawRoundRect(bounds, corner, corner, p);
-
-        p.clearShadowLayer();
+        ShadowGenerator.drawShadow(c, bounds, Color.WHITE, shadowBlur, keyShadowDistance, corner);
         return bounds;
     }
 
@@ -478,8 +465,7 @@
             c.setBitmap(preview);
             c.drawColor(0, PorterDuff.Mode.CLEAR);
         }
-        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        RectF boxRect = drawBoxWithShadow(c, p, size, size);
+        RectF boxRect = drawBoxWithShadow(c, size, size);
 
         Bitmap icon = LauncherIcons.createScaledBitmapWithoutShadow(
                 mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext, Build.VERSION_CODES.O);
@@ -487,7 +473,8 @@
 
         boxRect.set(0, 0, iconSize, iconSize);
         boxRect.offset(padding, padding);
-        c.drawBitmap(icon, src, boxRect, p);
+        c.drawBitmap(icon, src, boxRect,
+                new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
         c.setBitmap(null);
         return preview;
     }
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index af67631..7be8e8f 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -492,7 +492,8 @@
             ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
             navBarBgLp.height = insets.bottom;
             navBarBg.setLayoutParams(navBarBgLp);
-            navBarBg.setVisibility(View.VISIBLE);
+            navBarBg.setVisibility(FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
+                    ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 30ed180..121ce4c 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -22,6 +22,10 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dynamicui.ExtractedColors;
+import com.android.launcher3.graphics.RadialGradientView;
+import com.android.launcher3.graphics.ScrimView;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.Themes;
@@ -91,6 +95,8 @@
     // Used in discovery bounce animation to provide the transition without workspace changing.
     private boolean mIsTranslateWithoutWorkspace = false;
     private AnimatorSet mDiscoBounceAnimation;
+    private RadialGradientView mGradientView;
+    private ScrimView mScrimView;
 
     public AllAppsTransitionController(Launcher l) {
         mLauncher = l;
@@ -247,7 +253,9 @@
             if (!mLauncher.isAllAppsVisible()) {
                 mLauncher.tryAndUpdatePredictedApps();
                 mAppsView.setVisibility(View.VISIBLE);
-                mAppsView.setRevealDrawableColor(mHotseatBackgroundColor);
+                if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                    mAppsView.setRevealDrawableColor(mHotseatBackgroundColor);
+                }
             }
         }
     }
@@ -263,6 +271,36 @@
         mLauncher.activateLightSystemBars(forceLight, true /* statusBar */, true /* navBar */);
     }
 
+    private void updateAllAppsBg(float progress) {
+        // gradient
+        if (mGradientView == null) {
+            mGradientView = (RadialGradientView) mLauncher.findViewById(R.id.gradient_bg);
+            mGradientView.setVisibility(View.VISIBLE);
+            onExtractedColorsChanged();
+        }
+        mGradientView.setProgress(progress);
+
+        // scrim
+        if (mScrimView == null) {
+            mScrimView = (ScrimView) mLauncher.findViewById(R.id.scrim_bg);
+            mScrimView.setVisibility(View.VISIBLE);
+        }
+        mScrimView.setProgress(progress);
+    }
+
+    public void onExtractedColorsChanged() {
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            if (mGradientView != null) {
+                int color1 = mLauncher.getExtractedColors()
+                        .getColor(ExtractedColors.ALLAPPS_GRADIENT_MAIN_INDEX);
+                int color2 = mLauncher.getExtractedColors()
+                        .getColor(ExtractedColors.ALLAPPS_GRADIENT_SECONDARY_INDEX);
+                mGradientView.onExtractedColorsChanged(color1, color2);
+                mGradientView.requestLayout();
+            }
+        }
+    }
+
     /**
      * @param progress       value between 0 and 1, 0 shows all apps and 1 shows workspace
      */
@@ -280,7 +318,12 @@
         int bgAlpha = Color.alpha((int) mEvaluator.evaluate(alpha,
                 mHotseatBackgroundColor, mAllAppsBackgroundColor));
 
-        mAppsView.setRevealDrawableColor(ColorUtils.setAlphaComponent(color, bgAlpha));
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            updateAllAppsBg(alpha);
+        } else {
+            mAppsView.setRevealDrawableColor(ColorUtils.setAlphaComponent(color, bgAlpha));
+        }
+
         mAppsView.getContentView().setAlpha(alpha);
         mAppsView.setTranslationY(shiftCurrent);
 
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 01d0e17..472cfc9 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -78,7 +78,8 @@
             Rect sourceBounds, Bundle opts);
     public abstract ApplicationInfo getApplicationInfo(
             String packageName, int flags, UserHandle user);
-    public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user);
+    public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user,
+            Rect sourceBounds, Bundle opts);
     public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
     public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
     public abstract boolean isPackageEnabledForProfile(String packageName, UserHandle user);
@@ -142,4 +143,8 @@
             return null;
         }
     }
+
+    public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
+        showAppDetailsForProfile(component, user, null, null);
+    }
 }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 58683db..647c315 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -95,8 +95,9 @@
     }
 
     @Override
-    public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
-        mLauncherApps.startAppDetailsActivity(component, user, null, null);
+    public void showAppDetailsForProfile(ComponentName component, UserHandle user,
+            Rect sourceBounds, Bundle opts) {
+        mLauncherApps.startAppDetailsActivity(component, user, sourceBounds, opts);
     }
 
     @Override
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index 9379a72..f6b02aa 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -63,8 +63,11 @@
             // We can't extract colors from live wallpapers, so just use the default color always.
             extractedColors.updateHotseatPalette(null);
 
-            if (FeatureFlags.QSB_IN_HOTSEAT) {
+            if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
                 extractedColors.updateWallpaperThemePalette(null);
+                if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                    extractedColors.updateAllAppsGradientPalette(null);
+                }
             }
         } else {
             // We extract colors for the hotseat and status bar separately,
@@ -75,8 +78,12 @@
                 extractedColors.updateStatusBarPalette(getStatusBarPalette());
             }
 
-            if (FeatureFlags.QSB_IN_HOTSEAT) {
-                extractedColors.updateWallpaperThemePalette(getWallpaperPalette());
+            if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                Palette wallpaperPalette = getWallpaperPalette();
+                extractedColors.updateWallpaperThemePalette(wallpaperPalette);
+                if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                    extractedColors.updateAllAppsGradientPalette(wallpaperPalette);
+                }
             }
         }
 
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index 2e52a0b..3c4aba1 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.support.annotation.Nullable;
 import android.support.v4.graphics.ColorUtils;
 import android.support.v7.graphics.Palette;
 import android.util.Log;
@@ -42,12 +43,24 @@
     public static final int HOTSEAT_INDEX = 1;
     public static final int STATUS_BAR_INDEX = 2;
     public static final int WALLPAPER_VIBRANT_INDEX = 3;
+    public static final int ALLAPPS_GRADIENT_MAIN_INDEX = 4;
+    public static final int ALLAPPS_GRADIENT_SECONDARY_INDEX = 5;
 
     private static final int VERSION;
     private static final int[] DEFAULT_VALUES;
 
     static {
-        if (FeatureFlags.QSB_IN_HOTSEAT) {
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            VERSION = 3;
+            DEFAULT_VALUES = new int[] {
+                    VERSION,            // VERSION_INDEX
+                    0x40FFFFFF,         // HOTSEAT_INDEX: White with 25% alpha
+                    DEFAULT_DARK,       // STATUS_BAR_INDEX
+                    0xFFCCCCCC,         // WALLPAPER_VIBRANT_INDEX
+                    0xFF000000,         // ALLAPPS_GRADIENT_MAIN_INDEX
+                    0xFF000000          // ALLAPPS_GRADIENT_SECONDARY_INDEX
+            };
+        } else if (FeatureFlags.QSB_IN_HOTSEAT) {
             VERSION = 2;
             DEFAULT_VALUES = new int[] {
                     VERSION,            // VERSION_INDEX
@@ -142,9 +155,20 @@
                 DEFAULT_LIGHT : DEFAULT_DARK);
     }
 
-    public void updateWallpaperThemePalette(Palette wallpaperPalette) {
+    public void updateWallpaperThemePalette(@Nullable Palette wallpaperPalette) {
         int defaultColor = DEFAULT_VALUES[WALLPAPER_VIBRANT_INDEX];
         setColorAtIndex(WALLPAPER_VIBRANT_INDEX, wallpaperPalette == null
                 ? defaultColor : wallpaperPalette.getVibrantColor(defaultColor));
     }
+
+    public void updateAllAppsGradientPalette(@Nullable Palette wallpaperPalette) {
+        // TODO b/37089857 will be modified to take the system extracted colors into account
+        int idx;
+        idx = ALLAPPS_GRADIENT_MAIN_INDEX;
+        setColorAtIndex(idx, wallpaperPalette == null
+                ? DEFAULT_VALUES[idx] : wallpaperPalette.getDarkVibrantColor(DEFAULT_VALUES[idx]));
+        idx = ALLAPPS_GRADIENT_SECONDARY_INDEX;
+        setColorAtIndex(idx, wallpaperPalette == null
+                ? DEFAULT_VALUES[idx] : wallpaperPalette.getVibrantColor(DEFAULT_VALUES[idx]));
+    }
 }
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 746a639..53521f2 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -265,7 +265,7 @@
             final int top = (textureHeight-height) / 2;
 
             sOldBounds.set(icon.getBounds());
-            if (icon instanceof AdaptiveIconDrawable) {
+            if (Utilities.isAtLeastO() && icon instanceof AdaptiveIconDrawable) {
                 int offset = Math.min(left, top);
                 int size = Math.max(width, height);
                 icon.setBounds(offset, offset, offset + size, offset + size);
diff --git a/src/com/android/launcher3/graphics/RadialGradientView.java b/src/com/android/launcher3/graphics/RadialGradientView.java
new file mode 100644
index 0000000..cf6851c
--- /dev/null
+++ b/src/com/android/launcher3/graphics/RadialGradientView.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2017 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.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.DecelerateInterpolator;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+/**
+ * Draws a translucent radial gradient background from an initial state with progress 0.0 to a
+ * final state with progress 1.0;
+ */
+public class RadialGradientView extends View {
+
+    public static final int DEFAULT_COLOR_1 = Color.WHITE;
+    public static final int DEFAULT_COLOR_2 = Color.BLACK;
+
+    private static Bitmap sFinalGradientMask;
+    private static Bitmap sAlphaGradientMask;
+
+    // TODO needs to be cleaned up once design finalizes
+    static class Config {
+        // dimens
+        final float gradientCenterX = 0.5f;
+        final float gradientCenterY = 1.05f;
+        final float gradientHeadStartFactor = 0.35f;
+        final float gradientAlphaMaskLengthDp = 700;
+        // interpolation
+        final boolean useGradientAlphaDecel = false;
+        final float decelFactorForGradientAlpha = 2f;
+        // colors
+        final float finalGradientAlpha = 0.75f;
+        int color1 = DEFAULT_COLOR_1;
+        int color2 = DEFAULT_COLOR_2;
+    }
+
+    private final RectF mAlphaMaskRect = new RectF();
+    private final RectF mFinalMaskRect = new RectF();
+    private final Paint mPaint = new Paint();
+    private final Config mConfig = new Config();
+    private final DecelerateInterpolator mDecelInterpolator;
+    private float mProgress;
+    private int mWidth;
+    private int mHeight;
+    private final int mMaskHeight;
+    private final Context mAppContext;
+
+    public RadialGradientView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        this.mAppContext = context.getApplicationContext();
+        this.mDecelInterpolator = new DecelerateInterpolator(mConfig.decelFactorForGradientAlpha);
+        this.mMaskHeight = Utilities.pxFromDp(mConfig.gradientAlphaMaskLengthDp,
+                mAppContext.getResources().getDisplayMetrics());
+
+        if (sFinalGradientMask == null) {
+            sFinalGradientMask = Utilities.convertToAlphaMask(
+                    Utilities.createOnePixBitmap(), mConfig.finalGradientAlpha);
+        }
+        if (sAlphaGradientMask == null) {
+            Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(context.getResources(),
+                    R.drawable.all_apps_alpha_mask);
+            sAlphaGradientMask = Utilities.convertToAlphaMask(
+                    alphaMaskFromResource, mConfig.finalGradientAlpha);
+        }
+    }
+
+    public void onExtractedColorsChanged(int color1, int color2) {
+        mConfig.color1 = color1;
+        mConfig.color2 = color2;
+        if (mWidth + mHeight > 0) {
+            createRadialShader();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        this.mWidth = getMeasuredWidth();
+        this.mHeight = getMeasuredHeight();
+        if (mWidth + mHeight > 0) {
+            createRadialShader();
+        }
+    }
+
+    // only being called when colors change
+    private void createRadialShader() {
+        float radius = Math.max(mHeight, mWidth) * mConfig.gradientCenterY;
+
+        float posScreenBottom = (radius - mHeight) / radius; // center lives below screen
+        RadialGradient shader = new RadialGradient(
+                mWidth * mConfig.gradientCenterX,
+                mHeight * mConfig.gradientCenterY,
+                radius,
+                new int[] {mConfig.color1, mConfig.color1, mConfig.color2},
+                new float[] {0f, posScreenBottom, 1f},
+                Shader.TileMode.CLAMP);
+        mPaint.setShader(shader);
+    }
+
+    public void setProgress(float progress) {
+        this.mProgress = progress;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        float head = mConfig.gradientHeadStartFactor;
+        float linearProgress = head + (mProgress * (1f - head));
+        float adjustProgress = mConfig.useGradientAlphaDecel
+                ? mDecelInterpolator.getInterpolation(linearProgress)
+                : linearProgress;
+        float startMaskY = (1f - adjustProgress) * mHeight - mMaskHeight * adjustProgress;
+
+        mAlphaMaskRect.set(0, startMaskY, mWidth, startMaskY + mMaskHeight);
+        mFinalMaskRect.set(0, startMaskY + mMaskHeight, mWidth, mHeight);
+        canvas.drawBitmap(sAlphaGradientMask, null, mAlphaMaskRect, mPaint);
+        canvas.drawBitmap(sFinalGradientMask, null, mFinalMaskRect, mPaint);
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/graphics/ScrimView.java b/src/com/android/launcher3/graphics/ScrimView.java
new file mode 100644
index 0000000..521fbed
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ScrimView.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 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.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.support.v4.graphics.ColorUtils;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+public class ScrimView extends View {
+
+    // Config
+    private static final int MASK_HEIGHT_DP = 600;
+    private static final float MASK_START_LENGTH_FACTOR = 0.4f;
+    private static final float FINAL_ALPHA = 0.87f;
+    private static final int SCRIM_COLOR = ColorUtils.setAlphaComponent(
+            Color.WHITE, (int) (FINAL_ALPHA * 255));
+
+    private static Bitmap sFinalScrimMask;
+    private static Bitmap sAlphaScrimMask;
+
+    private final int mMaskHeight;
+    private int mVisibleHeight;
+    private final int mHeadStart;
+
+    private final RectF mAlphaMaskRect = new RectF();
+    private final RectF mFinalMaskRect = new RectF();
+    private final Paint mPaint = new Paint();
+    private float mProgress;
+
+    public ScrimView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mMaskHeight = Utilities.pxFromDp(MASK_HEIGHT_DP, getResources().getDisplayMetrics());
+        mHeadStart = (int) (mMaskHeight * MASK_START_LENGTH_FACTOR);
+        mPaint.setColor(SCRIM_COLOR);
+
+        if (sFinalScrimMask == null) {
+            sFinalScrimMask = Utilities.convertToAlphaMask(
+                    Utilities.createOnePixBitmap(), FINAL_ALPHA);
+        }
+        if (sAlphaScrimMask == null) {
+            Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(getResources(),
+                    R.drawable.all_apps_alpha_mask);
+            sAlphaScrimMask = Utilities.convertToAlphaMask(alphaMaskFromResource, FINAL_ALPHA);
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        mVisibleHeight = MeasureSpec.getSize(heightMeasureSpec);
+        int fullHeight = mVisibleHeight * 2 + mMaskHeight;
+        setMeasuredDimension(width, fullHeight);
+        setProgress(mProgress);
+    }
+
+    public void setProgress(float progress) {
+        mProgress = progress;
+        float initialY = mVisibleHeight - mHeadStart;
+        float fullTranslationY = mMaskHeight + initialY + mVisibleHeight;
+        float translationY = initialY - progress * fullTranslationY;
+        setTranslationY(translationY);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        mAlphaMaskRect.set(0, 0, getWidth(), mMaskHeight);
+        mFinalMaskRect.set(0, mMaskHeight, getWidth(), getHeight());
+        canvas.drawBitmap(sAlphaScrimMask, null, mAlphaMaskRect, mPaint);
+        canvas.drawBitmap(sFinalScrimMask, null, mFinalMaskRect, mPaint);
+    }
+
+}
diff --git a/src/com/android/launcher3/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java
index 469fe34..695015d 100644
--- a/src/com/android/launcher3/graphics/ShadowGenerator.java
+++ b/src/com/android/launcher3/graphics/ShadowGenerator.java
@@ -22,8 +22,10 @@
 import android.graphics.BlurMaskFilter;
 import android.graphics.BlurMaskFilter.Blur;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.RectF;
+import android.support.v4.graphics.ColorUtils;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.util.Preconditions;
@@ -39,9 +41,9 @@
 
     // Percent of actual icon size
     private static final float KEY_SHADOW_DISTANCE = 1f/48;
-    public static final int KEY_SHADOW_ALPHA = 61;
+    private static final int KEY_SHADOW_ALPHA = 61;
 
-    public static final int AMBIENT_SHADOW_ALPHA = 30;
+    private static final int AMBIENT_SHADOW_ALPHA = 30;
 
     private static final Object LOCK = new Object();
     // Singleton object guarded by {@link #LOCK}
@@ -84,45 +86,45 @@
     }
 
     public static Bitmap createPillWithShadow(int rectColor, int width, int height) {
-
         float shadowRadius = height * 1f / 32;
         float shadowYOffset = height * 1f / 16;
+        return createPillWithShadow(rectColor, width, height, shadowRadius, shadowYOffset,
+                new RectF());
+    }
 
+    public static Bitmap createPillWithShadow(int rectColor, int width, int height,
+            float shadowRadius, float shadowYOffset, RectF outRect) {
         int radius = height / 2;
 
-        Canvas canvas = new Canvas();
-        Paint blurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        blurPaint.setMaskFilter(new BlurMaskFilter(shadowRadius, Blur.NORMAL));
-
         int centerX = Math.round(width / 2 + shadowRadius);
         int centerY = Math.round(radius + shadowRadius + shadowYOffset);
         int center = Math.max(centerX, centerY);
         int size = center * 2;
         Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888);
-        canvas.setBitmap(result);
 
-        int left = center - width / 2;
-        int top = center - height / 2;
-        int right = center + width / 2;
-        int bottom = center + height / 2;
+        outRect.set(0, 0, width, height);
+        outRect.offsetTo(center - width / 2, center - height / 2);
 
-        // Draw ambient shadow, center aligned within size
-        blurPaint.setAlpha(AMBIENT_SHADOW_ALPHA);
-        canvas.drawRoundRect(left, top, right, bottom, radius, radius, blurPaint);
-
-        // Draw key shadow, bottom aligned within size
-        blurPaint.setAlpha(KEY_SHADOW_ALPHA);
-        canvas.drawRoundRect(left, top + shadowYOffset, right, bottom + shadowYOffset,
-                radius, radius, blurPaint);
-
-        // Draw the circle
-        Paint drawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        drawPaint.setColor(rectColor);
-        canvas.drawRoundRect(left, top, right, bottom, radius, radius, drawPaint);
-
+        drawShadow(new Canvas(result), outRect, rectColor, shadowRadius, shadowYOffset, radius);
         return result;
     }
 
+    public static void drawShadow(Canvas c, RectF bounds, int color,
+            float shadowBlur, float keyShadowDistance, float radius) {
+        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+        p.setColor(color);
+
+        // Key shadow
+        p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
+                ColorUtils.setAlphaComponent(Color.BLACK, KEY_SHADOW_ALPHA));
+        c.drawRoundRect(bounds, radius, radius, p);
+
+        // Ambient shadow
+        p.setShadowLayer(shadowBlur, 0, 0,
+                ColorUtils.setAlphaComponent(Color.BLACK, AMBIENT_SHADOW_ALPHA));
+        c.drawRoundRect(bounds, radius, radius, p);
+    }
+
     public static ShadowGenerator getInstance(Context context) {
         Preconditions.assertNonUiThread();
         synchronized (LOCK) {
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 6747540..a52d1d4 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -1,7 +1,9 @@
 package com.android.launcher3.popup;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.view.View;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -80,7 +82,9 @@
             return new View.OnClickListener() {
                 @Override
                 public void onClick(View view) {
-                    InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, null);
+                    Rect sourceBounds = launcher.getViewBounds(view);
+                    Bundle opts = launcher.getActivityLaunchOptions(view);
+                    InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, null, sourceBounds, opts);
                 }
             };
         }
diff --git a/src_flags/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java
index 159f125..c0184fa 100644
--- a/src_flags/com/android/launcher3/config/FeatureFlags.java
+++ b/src_flags/com/android/launcher3/config/FeatureFlags.java
@@ -38,6 +38,8 @@
     public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = true;
     // When enabled the promise icon is visible in all apps while installation an app.
     public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = true;
+    // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps
+    public static boolean LAUNCHER3_GRADIENT_ALL_APPS = false;
 
     // Feature flag to enable moving the QSB on the 0th screen of the workspace.
     public static final boolean QSB_ON_FIRST_SCREEN = true;