Merge "Adding padding to the folder content" into ub-launcher3-burnaby
diff --git a/WallpaperPicker/src/com/android/gallery3d/exif/ExifInterface.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifInterface.java
index a1cf0fc..9247e87 100644
--- a/WallpaperPicker/src/com/android/gallery3d/exif/ExifInterface.java
+++ b/WallpaperPicker/src/com/android/gallery3d/exif/ExifInterface.java
@@ -1247,7 +1247,7 @@
         if (l == null || l.length <= 0) {
             return null;
         }
-        return new Long(l[0]);
+        return Long.valueOf(l[0]);
     }
 
     /**
@@ -1266,7 +1266,7 @@
         if (l == null || l.length <= 0) {
             return null;
         }
-        return new Integer(l[0]);
+        return Integer.valueOf(l[0]);
     }
 
     /**
@@ -1285,7 +1285,7 @@
         if (l == null || l.length <= 0) {
             return null;
         }
-        return new Byte(l[0]);
+        return Byte.valueOf(l[0]);
     }
 
     /**
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 142a9cb..affad0f 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -190,7 +190,7 @@
                     }
                 });
             } catch (SecurityException securityException) {
-                if (isDestroyed()) {
+                if (isActivityDestroyed()) {
                     // Temporarily granted permissions are revoked when the activity
                     // finishes, potentially resulting in a SecurityException here.
                     // Even though {@link #isDestroyed} might also return true in different
@@ -221,6 +221,12 @@
         return false;
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    protected boolean isActivityDestroyed() {
+        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
+                && isDestroyed();
+    }
+
     @Thunk void addReusableBitmap(TileSource src) {
         synchronized (mReusableBitmaps) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 9332091..1ba5b4b 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -665,7 +665,7 @@
     }
 
     @Thunk void initializeScrollForRtl() {
-        if (mWallpaperScrollContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+        if (Utilities.isRtl(getResources())) {
             final ViewTreeObserver observer = mWallpaperScrollContainer.getViewTreeObserver();
             observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                 public void onGlobalLayout() {
@@ -838,7 +838,7 @@
                     int rotation = BitmapUtils.getRotationFromExif(context, uri);
                     return createThumbnail(defaultSize, context, uri, null, null, 0, rotation, false);
                 } catch (SecurityException securityException) {
-                    if (isDestroyed()) {
+                    if (isActivityDestroyed()) {
                         // Temporarily granted permissions are revoked when the activity
                         // finishes, potentially resulting in a SecurityException here.
                         // Even though {@link #isDestroyed} might also return true in different
diff --git a/res/drawable-hdpi/apps_customize_bg.png b/res/drawable-hdpi/apps_customize_bg.png
deleted file mode 100644
index 2847467..0000000
--- a/res/drawable-hdpi/apps_customize_bg.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/home_press.9.png b/res/drawable-hdpi/home_press.9.png
deleted file mode 100644
index ef07011..0000000
--- a/res/drawable-hdpi/home_press.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_all_apps_holo_dark.png b/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
deleted file mode 100644
index 1dc02d5..0000000
--- a/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/on_boarding_welcome.png b/res/drawable-hdpi/on_boarding_welcome.png
deleted file mode 100644
index 852a0cb..0000000
--- a/res/drawable-hdpi/on_boarding_welcome.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/paged_view_indicator.9.png b/res/drawable-hdpi/paged_view_indicator.9.png
deleted file mode 100644
index 5b47f44..0000000
--- a/res/drawable-hdpi/paged_view_indicator.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/portal_container_holo.9.png b/res/drawable-hdpi/portal_container_holo.9.png
deleted file mode 100644
index ba8a4a8..0000000
--- a/res/drawable-hdpi/portal_container_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quantum_panel.9.png b/res/drawable-hdpi/quantum_panel.9.png
deleted file mode 100644
index b4ac9c0..0000000
--- a/res/drawable-hdpi/quantum_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quantum_panel_bitmap.9.png b/res/drawable-hdpi/quantum_panel_bitmap.9.png
new file mode 100644
index 0000000..c331929
--- /dev/null
+++ b/res/drawable-hdpi/quantum_panel_bitmap.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quantum_panel_dark.9.png b/res/drawable-hdpi/quantum_panel_dark.9.png
deleted file mode 100644
index abaf230..0000000
--- a/res/drawable-hdpi/quantum_panel_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-hdpi/quantum_panel_dark_bitmap.9.png
new file mode 100644
index 0000000..0145d36
--- /dev/null
+++ b/res/drawable-hdpi/quantum_panel_dark_bitmap.9.png
Binary files differ
diff --git a/res/drawable-mdpi/apps_customize_bg.png b/res/drawable-mdpi/apps_customize_bg.png
deleted file mode 100644
index 2847467..0000000
--- a/res/drawable-mdpi/apps_customize_bg.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/home_press.9.png b/res/drawable-mdpi/home_press.9.png
deleted file mode 100644
index 679a1f6..0000000
--- a/res/drawable-mdpi/home_press.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_all_apps_holo_dark.png b/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
deleted file mode 100644
index 84fa594..0000000
--- a/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_setting_icn.png b/res/drawable-mdpi/ic_setting_icn.png
deleted file mode 100644
index 5c32c54..0000000
--- a/res/drawable-mdpi/ic_setting_icn.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/on_boarding_welcome.png b/res/drawable-mdpi/on_boarding_welcome.png
deleted file mode 100644
index 1d12e83..0000000
--- a/res/drawable-mdpi/on_boarding_welcome.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/paged_view_indicator.9.png b/res/drawable-mdpi/paged_view_indicator.9.png
deleted file mode 100644
index 647b60f..0000000
--- a/res/drawable-mdpi/paged_view_indicator.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/portal_container_holo.9.png b/res/drawable-mdpi/portal_container_holo.9.png
deleted file mode 100644
index 1e4afae..0000000
--- a/res/drawable-mdpi/portal_container_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quantum_panel.9.png b/res/drawable-mdpi/quantum_panel.9.png
deleted file mode 100644
index c5a6eb7..0000000
--- a/res/drawable-mdpi/quantum_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quantum_panel_bitmap.9.png b/res/drawable-mdpi/quantum_panel_bitmap.9.png
new file mode 100644
index 0000000..86be568
--- /dev/null
+++ b/res/drawable-mdpi/quantum_panel_bitmap.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quantum_panel_dark.9.png b/res/drawable-mdpi/quantum_panel_dark.9.png
deleted file mode 100644
index 7728a72..0000000
--- a/res/drawable-mdpi/quantum_panel_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-mdpi/quantum_panel_dark_bitmap.9.png
new file mode 100644
index 0000000..70429b9
--- /dev/null
+++ b/res/drawable-mdpi/quantum_panel_dark_bitmap.9.png
Binary files differ
diff --git a/res/drawable/apps_reveal_bg.xml b/res/drawable-v21/quantum_panel.xml
similarity index 65%
copy from res/drawable/apps_reveal_bg.xml
copy to res/drawable-v21/quantum_panel.xml
index 07505a5..d1c0783 100644
--- a/res/drawable/apps_reveal_bg.xml
+++ b/res/drawable-v21/quantum_panel.xml
@@ -14,8 +14,9 @@
      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="#ffffff" />
-    <corners android:radius="2dp" />
-</shape>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/quantum_panel_shape"
+    android:insetBottom="@dimen/quantum_panel_outer_padding"
+    android:insetLeft="@dimen/quantum_panel_outer_padding"
+    android:insetRight="@dimen/quantum_panel_outer_padding"
+    android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/drawable/apps_reveal_bg.xml b/res/drawable-v21/quantum_panel_dark.xml
similarity index 64%
copy from res/drawable/apps_reveal_bg.xml
copy to res/drawable-v21/quantum_panel_dark.xml
index 07505a5..405ad51 100644
--- a/res/drawable/apps_reveal_bg.xml
+++ b/res/drawable-v21/quantum_panel_dark.xml
@@ -14,8 +14,9 @@
      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="#ffffff" />
-    <corners android:radius="2dp" />
-</shape>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/quantum_panel_shape_dark"
+    android:insetBottom="@dimen/quantum_panel_outer_padding"
+    android:insetLeft="@dimen/quantum_panel_outer_padding"
+    android:insetRight="@dimen/quantum_panel_outer_padding"
+    android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/drawable-xhdpi/apps_customize_bg.png b/res/drawable-xhdpi/apps_customize_bg.png
deleted file mode 100644
index a51cc11..0000000
--- a/res/drawable-xhdpi/apps_customize_bg.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/home_press.9.png b/res/drawable-xhdpi/home_press.9.png
deleted file mode 100644
index d9abfd3..0000000
--- a/res/drawable-xhdpi/home_press.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png b/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
deleted file mode 100644
index 81228d4..0000000
--- a/res/drawable-xhdpi/ic_home_all_apps_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/on_boarding_welcome.png b/res/drawable-xhdpi/on_boarding_welcome.png
deleted file mode 100644
index 8c101e0..0000000
--- a/res/drawable-xhdpi/on_boarding_welcome.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/paged_view_indicator.9.png b/res/drawable-xhdpi/paged_view_indicator.9.png
deleted file mode 100644
index fb8a228..0000000
--- a/res/drawable-xhdpi/paged_view_indicator.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/portal_container_holo.9.png b/res/drawable-xhdpi/portal_container_holo.9.png
deleted file mode 100644
index cedbdc4..0000000
--- a/res/drawable-xhdpi/portal_container_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/quantum_panel.9.png b/res/drawable-xhdpi/quantum_panel.9.png
deleted file mode 100644
index 1797ad5..0000000
--- a/res/drawable-xhdpi/quantum_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/quantum_panel_bitmap.9.png b/res/drawable-xhdpi/quantum_panel_bitmap.9.png
new file mode 100644
index 0000000..13bdf09
--- /dev/null
+++ b/res/drawable-xhdpi/quantum_panel_bitmap.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/quantum_panel_dark.9.png b/res/drawable-xhdpi/quantum_panel_dark.9.png
deleted file mode 100644
index 4c1868b..0000000
--- a/res/drawable-xhdpi/quantum_panel_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-xhdpi/quantum_panel_dark_bitmap.9.png
new file mode 100644
index 0000000..ac2e423
--- /dev/null
+++ b/res/drawable-xhdpi/quantum_panel_dark_bitmap.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/apps_customize_bg.png b/res/drawable-xxhdpi/apps_customize_bg.png
deleted file mode 100644
index a51cc11..0000000
--- a/res/drawable-xxhdpi/apps_customize_bg.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/arrow_dashed.png b/res/drawable-xxhdpi/arrow_dashed.png
deleted file mode 100644
index b64f4d0..0000000
--- a/res/drawable-xxhdpi/arrow_dashed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/default_widget_preview_holo.9.png b/res/drawable-xxhdpi/default_widget_preview_holo.9.png
deleted file mode 100644
index 0f62097..0000000
--- a/res/drawable-xxhdpi/default_widget_preview_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/hotseat_bg_panel.9.png b/res/drawable-xxhdpi/hotseat_bg_panel.9.png
deleted file mode 100644
index 40fc076..0000000
--- a/res/drawable-xxhdpi/hotseat_bg_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/hotseat_scrubber_holo.9.png b/res/drawable-xxhdpi/hotseat_scrubber_holo.9.png
deleted file mode 100644
index 8a77536..0000000
--- a/res/drawable-xxhdpi/hotseat_scrubber_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/hotseat_track_holo.9.png b/res/drawable-xxhdpi/hotseat_track_holo.9.png
deleted file mode 100644
index dd2216f..0000000
--- a/res/drawable-xxhdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_all_apps_holo_dark.png b/res/drawable-xxhdpi/ic_home_all_apps_holo_dark.png
deleted file mode 100644
index 0b8e88c..0000000
--- a/res/drawable-xxhdpi/ic_home_all_apps_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_google_logo_normal_holo.png b/res/drawable-xxhdpi/ic_home_google_logo_normal_holo.png
deleted file mode 100644
index a47b2ba..0000000
--- a/res/drawable-xxhdpi/ic_home_google_logo_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_google_logo_pressed_holo.png b/res/drawable-xxhdpi/ic_home_google_logo_pressed_holo.png
deleted file mode 100644
index 75625d1..0000000
--- a/res/drawable-xxhdpi/ic_home_google_logo_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_search_pressed_holo.png b/res/drawable-xxhdpi/ic_home_search_pressed_holo.png
deleted file mode 100644
index 800d994..0000000
--- a/res/drawable-xxhdpi/ic_home_search_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_voice_search_pressed_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_pressed_holo.png
deleted file mode 100644
index 27a5897..0000000
--- a/res/drawable-xxhdpi/ic_home_voice_search_pressed_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_qs_remote_display.png b/res/drawable-xxhdpi/ic_qs_remote_display.png
deleted file mode 100644
index 25ea9fa..0000000
--- a/res/drawable-xxhdpi/ic_qs_remote_display.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_qs_remote_display_connected.png b/res/drawable-xxhdpi/ic_qs_remote_display_connected.png
deleted file mode 100644
index 33a8d2d..0000000
--- a/res/drawable-xxhdpi/ic_qs_remote_display_connected.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/portal_container_holo.9.png b/res/drawable-xxhdpi/portal_container_holo.9.png
deleted file mode 100644
index 599a076..0000000
--- a/res/drawable-xxhdpi/portal_container_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/quantum_panel.9.png b/res/drawable-xxhdpi/quantum_panel.9.png
deleted file mode 100644
index d7ba874..0000000
--- a/res/drawable-xxhdpi/quantum_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/quantum_panel_bitmap.9.png b/res/drawable-xxhdpi/quantum_panel_bitmap.9.png
new file mode 100644
index 0000000..b44269e
--- /dev/null
+++ b/res/drawable-xxhdpi/quantum_panel_bitmap.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/quantum_panel_dark.9.png b/res/drawable-xxhdpi/quantum_panel_dark.9.png
deleted file mode 100644
index 17ba0f1..0000000
--- a/res/drawable-xxhdpi/quantum_panel_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-xxhdpi/quantum_panel_dark_bitmap.9.png
new file mode 100644
index 0000000..7979cf7
--- /dev/null
+++ b/res/drawable-xxhdpi/quantum_panel_dark_bitmap.9.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/quantum_panel_bitmap.9.png b/res/drawable-xxxhdpi/quantum_panel_bitmap.9.png
new file mode 100644
index 0000000..bc887fe
--- /dev/null
+++ b/res/drawable-xxxhdpi/quantum_panel_bitmap.9.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/quantum_panel_dark_bitmap.9.png b/res/drawable-xxxhdpi/quantum_panel_dark_bitmap.9.png
new file mode 100644
index 0000000..7cfd6e4
--- /dev/null
+++ b/res/drawable-xxxhdpi/quantum_panel_dark_bitmap.9.png
Binary files differ
diff --git a/res/drawable/apps_list_search_bg.xml b/res/drawable/apps_list_search_bg.xml
index 63c4d55..9bb6d81 100644
--- a/res/drawable/apps_list_search_bg.xml
+++ b/res/drawable/apps_list_search_bg.xml
@@ -16,7 +16,7 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="#ffffff" />
+    <solid android:color="@color/quantum_panel_bg_color" />
     <corners
         android:bottomLeftRadius="2dp"
         android:bottomRightRadius="2dp" />
diff --git a/res/drawable/apps_search_bg.xml b/res/drawable/apps_search_bg.xml
index 405e844..57eb582 100644
--- a/res/drawable/apps_search_bg.xml
+++ b/res/drawable/apps_search_bg.xml
@@ -16,7 +16,7 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="#ffffff" />
+    <solid android:color="@color/quantum_panel_bg_color" />
     <corners
         android:topLeftRadius="2dp"
         android:topRightRadius="2dp" />
diff --git a/res/drawable/apps_reveal_bg.xml b/res/drawable/quantum_panel.xml
similarity index 78%
copy from res/drawable/apps_reveal_bg.xml
copy to res/drawable/quantum_panel.xml
index 07505a5..1f4fb71 100644
--- a/res/drawable/apps_reveal_bg.xml
+++ b/res/drawable/quantum_panel.xml
@@ -14,8 +14,5 @@
      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="#ffffff" />
-    <corners android:radius="2dp" />
-</shape>
\ No newline at end of file
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/quantum_panel_bitmap" />
diff --git a/res/drawable/apps_reveal_bg.xml b/res/drawable/quantum_panel_dark.xml
similarity index 78%
rename from res/drawable/apps_reveal_bg.xml
rename to res/drawable/quantum_panel_dark.xml
index 07505a5..6642e78 100644
--- a/res/drawable/apps_reveal_bg.xml
+++ b/res/drawable/quantum_panel_dark.xml
@@ -14,8 +14,5 @@
      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="#ffffff" />
-    <corners android:radius="2dp" />
-</shape>
\ No newline at end of file
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/quantum_panel_dark_bitmap" />
diff --git a/res/drawable/apps_list_bg.xml b/res/drawable/quantum_panel_shape.xml
similarity index 92%
copy from res/drawable/apps_list_bg.xml
copy to res/drawable/quantum_panel_shape.xml
index 0e56684..1083615 100644
--- a/res/drawable/apps_list_bg.xml
+++ b/res/drawable/quantum_panel_shape.xml
@@ -16,7 +16,7 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="#ffffff" />
+    <solid android:color="@color/quantum_panel_bg_color" />
     <corners
         android:radius="2dp" />
 </shape>
\ No newline at end of file
diff --git a/res/drawable/apps_list_bg.xml b/res/drawable/quantum_panel_shape_dark.xml
similarity index 92%
rename from res/drawable/apps_list_bg.xml
rename to res/drawable/quantum_panel_shape_dark.xml
index 0e56684..c3821c4 100644
--- a/res/drawable/apps_list_bg.xml
+++ b/res/drawable/quantum_panel_shape_dark.xml
@@ -16,7 +16,7 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="#ffffff" />
+    <solid android:color="@color/quantum_panel_bg_color_dark" />
     <corners
         android:radius="2dp" />
 </shape>
\ No newline at end of file
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index d5dd91a..f0f7bbb 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -18,7 +18,6 @@
 <com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
-
     android:id="@+id/launcher"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/res/layout-land/migration_cling.xml b/res/layout-land/migration_cling.xml
index db93da8..269c1ae 100644
--- a/res/layout-land/migration_cling.xml
+++ b/res/layout-land/migration_cling.xml
@@ -46,6 +46,7 @@
         android:layout_width="@dimen/cling_migration_content_width"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/cling_migration_content_margin"
+        android:layout_marginRight="@dimen/cling_migration_content_margin"
         android:orientation="vertical"
         android:paddingLeft="24dp"
         android:paddingRight="24dp" >
diff --git a/res/layout-port/migration_cling.xml b/res/layout-port/migration_cling.xml
index 81689d3..3f696a2 100644
--- a/res/layout-port/migration_cling.xml
+++ b/res/layout-port/migration_cling.xml
@@ -48,6 +48,7 @@
             android:layout_height="wrap_content"
             android:layout_below="@+id/ic_cling_migration"
             android:layout_marginStart="@dimen/cling_migration_content_margin"
+            android:layout_marginLeft="@dimen/cling_migration_content_margin"
             android:orientation="vertical"
             android:paddingLeft="24dp"
             android:paddingRight="24dp" >
diff --git a/res/layout/apps_customize_progressbar.xml b/res/layout/apps_customize_progressbar.xml
deleted file mode 100644
index 6aa9099..0000000
--- a/res/layout/apps_customize_progressbar.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<ProgressBar
-   xmlns:android="http://schemas.android.com/apk/res/android"
-   style="?android:attr/progressBarStyleLarge"
-   android:id="@+id/apps_customize_progress_bar"
-   android:layout_width="wrap_content"
-   android:layout_height="wrap_content"
-   android:layout_gravity="center" />
diff --git a/res/layout/apps_list_view.xml b/res/layout/apps_list_view.xml
index ef20323..03ba646 100644
--- a/res/layout/apps_list_view.xml
+++ b/res/layout/apps_list_view.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!--
+     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.
@@ -13,82 +14,91 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/apps_list"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:elevation="15dp"
-    android:visibility="gone"
-    android:focusableInTouchMode="true">
+    android:focusableInTouchMode="true"
+    android:visibility="gone" >
+
     <com.android.launcher3.AppsContainerRecyclerView
         android:id="@+id/apps_list_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_marginTop="@dimen/apps_search_bar_height"
         android:layout_gravity="center_horizontal|top"
+        android:layout_marginTop="@dimen/apps_search_bar_height"
         android:clipToPadding="false"
-        android:focusable="true"
-        android:descendantFocusability="afterDescendants" />
+        android:descendantFocusability="afterDescendants"
+        android:focusable="true" />
+
     <LinearLayout
         android:id="@+id/prediction_bar"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="@dimen/apps_search_bar_height"
         android:orientation="horizontal"
-        android:visibility="invisible">
+        android:visibility="invisible" >
     </LinearLayout>
 
     <!-- We always want the search bar on top, so it goes last. -->
+
     <FrameLayout
         android:id="@+id/header"
         android:layout_width="match_parent"
         android:layout_height="@dimen/apps_search_bar_height"
-        android:background="@drawable/apps_search_bg">
+        android:background="@drawable/apps_search_bg" >
+
         <LinearLayout
             android:id="@+id/app_search_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
-            android:visibility="invisible">
+            android:visibility="invisible" >
+
             <ImageView
                 android:id="@+id/dismiss_search_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="start|center_vertical"
+                android:layout_marginLeft="4dp"
                 android:layout_marginStart="4dp"
-                android:paddingTop="13dp"
-                android:paddingBottom="13dp"
                 android:contentDescription="@string/all_apps_button_label"
+                android:paddingBottom="13dp"
+                android:paddingTop="13dp"
                 android:src="@drawable/ic_arrow_back_grey" />
+
             <com.android.launcher3.AppsContainerSearchEditTextView
                 android:id="@+id/app_search_box"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:paddingTop="16dp"
+                android:background="@android:color/transparent"
+                android:focusableInTouchMode="true"
+                android:gravity="fill_horizontal"
+                android:hint="@string/apps_view_search_bar_hint"
+                android:imeOptions="actionDone|flagNoExtractUi"
+                android:maxLines="1"
                 android:paddingBottom="16dp"
                 android:paddingLeft="8dp"
-                android:hint="@string/apps_view_search_bar_hint"
-                android:maxLines="1"
-                android:singleLine="true"
+                android:paddingTop="16dp"
                 android:scrollHorizontally="true"
-                android:gravity="fill_horizontal"
-                android:textSize="16sp"
+                android:singleLine="true"
                 android:textColor="#4c4c4c"
                 android:textColorHint="#9c9c9c"
-                android:imeOptions="actionDone|flagNoExtractUi"
-                android:focusableInTouchMode="true"
-                android:background="@android:color/transparent" />
+                android:textSize="16sp" />
         </LinearLayout>
+
         <ImageView
             android:id="@+id/search_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="end|center_vertical"
             android:layout_marginEnd="6dp"
-            android:paddingTop="13dp"
-            android:paddingBottom="13dp"
+            android:layout_marginRight="6dp"
             android:contentDescription="@string/apps_view_search_bar_hint"
+            android:paddingBottom="13dp"
+            android:paddingTop="13dp"
             android:src="@drawable/ic_search_grey" />
     </FrameLayout>
+
 </FrameLayout>
\ No newline at end of file
diff --git a/res/layout/search_drop_target_bar.xml b/res/layout/search_drop_target_bar.xml
index 69f42bb..b0435aa 100644
--- a/res/layout/search_drop_target_bar.xml
+++ b/res/layout/search_drop_target_bar.xml
@@ -36,6 +36,7 @@
             <com.android.launcher3.DeleteDropTarget
                 android:id="@+id/delete_target_text"
                 style="@style/DropTargetButton"
+                android:drawableLeft="@drawable/remove_target_selector"
                 android:drawableStart="@drawable/remove_target_selector"
                 android:text="@string/delete_target_label" />
         </FrameLayout>
@@ -49,6 +50,7 @@
             <com.android.launcher3.InfoDropTarget
                 android:id="@+id/info_target_text"
                 style="@style/DropTargetButton"
+                android:drawableLeft="@drawable/info_target_selector"
                 android:drawableStart="@drawable/info_target_selector"
                 android:text="@string/info_target_label" />
         </FrameLayout>
@@ -62,6 +64,7 @@
             <com.android.launcher3.UninstallDropTarget
                 android:id="@+id/uninstall_target_text"
                 style="@style/DropTargetButton"
+                android:drawableLeft="@drawable/uninstall_target_selector"
                 android:drawableStart="@drawable/uninstall_target_selector"
                 android:text="@string/delete_target_uninstall_label" />
         </FrameLayout>
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index ac5a88c..67b69ca 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -14,11 +14,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <com.android.launcher3.Folder xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
+    android:background="@drawable/quantum_panel"
     android:elevation="5dp"
     android:orientation="vertical" >
 
diff --git a/res/layout/widget_cell.xml b/res/layout/widget_cell.xml
index a85f0aa..500cf10 100644
--- a/res/layout/widget_cell.xml
+++ b/res/layout/widget_cell.xml
@@ -44,7 +44,7 @@
             android:ellipsize="end"
             android:fadingEdge="horizontal"
             android:textColor="@color/widgets_view_item_text_color"
-            android:textSize="16sp"
+            android:textSize="14sp"
             android:textAlignment="viewStart"
             android:fontFamily="sans-serif-condensed"
             android:shadowRadius="2.0"
@@ -61,7 +61,7 @@
             android:layout_weight="0"
             android:gravity="start"
             android:textColor="@color/widgets_view_item_text_color"
-            android:textSize="16sp"
+            android:textSize="14sp"
             android:textAlignment="viewStart"
             android:fontFamily="sans-serif-condensed"
             android:shadowRadius="2.0"
diff --git a/res/layout/widgets_list_row_view.xml b/res/layout/widgets_list_row_view.xml
index 2cbdb5c..dc1bcce 100644
--- a/res/layout/widgets_list_row_view.xml
+++ b/res/layout/widgets_list_row_view.xml
@@ -41,7 +41,7 @@
         android:paddingTop="@dimen/widget_section_vertical_padding"
         android:singleLine="true"
         android:textColor="@color/widgets_view_section_text_color"
-        android:textSize="20sp"
+        android:textSize="16sp"
         launcher:customShadows="false"
         launcher:deferShadowGeneration="true"
         launcher:iconDisplay="widget_section"
@@ -58,6 +58,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/widget_row_padding"
+            android:layout_marginLeft="@dimen/widget_row_padding"
             android:orientation="horizontal"
             android:divider="@drawable/widgets_row_divider"
             android:showDividers="middle"
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml
index 5cdf560..b91ca26 100644
--- a/res/layout/widgets_view.xml
+++ b/res/layout/widgets_view.xml
@@ -30,15 +30,17 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_gravity="center"
-        android:visibility="invisible"
-        android:focusable="false" />
+        android:elevation="15dp"
+        android:focusable="false"
+        android:visibility="invisible" />
 
     <LinearLayout
         android:id="@+id/widgets_content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:clipChildren="false"
-        android:orientation="vertical">
+        android:elevation="15dp"
+        android:orientation="vertical" >
 
         <com.android.launcher3.widget.WidgetsContainerRecyclerView
                 android:id="@+id/widgets_list_view"
diff --git a/res/mipmap-xxhdpi/on_boarding_welcome.png b/res/mipmap-xxhdpi/on_boarding_welcome.png
deleted file mode 100644
index 7b11dea..0000000
--- a/res/mipmap-xxhdpi/on_boarding_welcome.png
+++ /dev/null
Binary files differ
diff --git a/res/values-land/config.xml b/res/values-land/config.xml
deleted file mode 100644
index 31115c9..0000000
--- a/res/values-land/config.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<resources>
-<!-- Workspace -->
-    <!-- Whether or not the drop targets drop down as opposed to fade in -->
-    <bool name="config_useDropTargetDownTransition">false</bool>
-</resources>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index 8a255c9..c5a76d5 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -28,7 +28,7 @@
     </style>
 
     <!-- This style applies to the drop target when it is shown in the sidebar -->
-    <style name="DropTargetButton" parent="DropTargetButton.Base">
+    <style name="DropTargetButton" parent="DropTargetButtonBase">
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center</item>
         <item name="android:drawablePadding">0dp</item>
diff --git a/res/values-port/dimens.xml b/res/values-port/dimens.xml
deleted file mode 100644
index c20f57b..0000000
--- a/res/values-port/dimens.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<resources>
-<!-- AppsCustomize -->
-    <integer name="apps_customize_widget_cell_count_x">2</integer>
-    <integer name="apps_customize_widget_cell_count_y">3</integer>
-</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 4a869e5..c366ef3 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -23,11 +23,6 @@
     <dimen name="apps_view_section_text_size">26sp</dimen>
     <dimen name="apps_icon_top_bottom_padding">12dp</dimen>
 
-<!-- AppsCustomize -->
-    <dimen name="widget_preview_label_margin_top">8dp</dimen>
-    <dimen name="widget_preview_label_margin_left">@dimen/widget_preview_label_horizontal_padding</dimen>
-    <dimen name="widget_preview_label_margin_right">@dimen/widget_preview_label_horizontal_padding</dimen>
-
 <!-- Cling -->
     <dimen name="cling_migration_logo_height">400dp</dimen>
     <dimen name="cling_migration_logo_width">274dp</dimen>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index cbc1e29..e8b706e 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -27,7 +27,7 @@
         <item name="android:layout_height">match_parent</item>
     </style>
 
-    <style name="DropTargetButton" parent="DropTargetButton.Base">
+    <style name="DropTargetButton" parent="DropTargetButtonBase">
         <item name="android:paddingLeft">60dp</item>
         <item name="android:paddingRight">60dp</item>
         <item name="android:shadowColor">#393939</item>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 0c3714b..0ba55f3 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -25,7 +25,6 @@
     <color name="info_target_hover_tint">#DA009688</color>
     <color name="cling_scrim_background">#80000000</color>
 
-    <color name="bubble_dark_background">#20000000</color>
     <color name="focused_background">#80c6c5c5</color>
 
     <color name="appwidget_error_color">#FCCC</color>
@@ -33,7 +32,9 @@
     <color name="workspace_icon_text_color">#FFF</color>
 
     <color name="quantum_panel_text_color">#FF666666</color>
-    <color name="quantum_panel_text_shadow_color">#FFC4C4C4</color>
+    <color name="quantum_panel_bg_color">#FFF5F5F5</color>
+    <color name="quantum_panel_bg_color_dark">#FF243036</color>
+
     <color name="outline_color">#FFFFFFFF</color>
     <color name="widget_text_panel">#FF374248</color>
 
@@ -41,7 +42,7 @@
     <color name="apps_view_scrollbar_thumb_color">#009688</color>
     <color name="apps_view_section_text_color">#009688</color>
 
-    <!-- Widgetss view -->
+    <!-- Widgets view -->
     <color name="widgets_view_section_text_color">#FFFFFF</color>
     <color name="widgets_view_item_text_color">#C4C4C4</color>
     <color name="widgets_cell_color">#263238</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 84ccef1..b6e633c 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -38,7 +38,6 @@
     <integer name="config_appsCustomizeRevealTime">220</integer>
     <integer name="config_appsCustomizeWorkspaceShrinkTime">300</integer>
 
-    <integer name="config_appsCustomizeConcealTime">250</integer>
     <integer name="config_appsCustomizeItemsAlphaStagger">60</integer>
 
     <!-- This constant stores the ratio of the all apps button drawable which
@@ -47,13 +46,6 @@
 
     <integer name="config_workspaceDefaultScreen">0</integer>
 
-    <!-- Tab transition animation duration -->
-    <integer name="config_tabTransitionDuration">250</integer>
-
-    <!-- The slope, in percent, of the drag movement needed to drag an item out of
-         AppsCustomize (y / x * 100%)  -->
-    <integer name="config_appsCustomizeDragSlopeThreshold">150</integer>
-
 <!-- Workspace -->
     <!-- The duration (in ms) of the fade animation on the object outlines, used when
          we are dragging objects around on the home screen. -->
@@ -75,10 +67,6 @@
     <!-- The distance at which the animation should take the max duration -->
     <integer name="config_dropAnimMaxDist">800</integer>
 
-    <!-- Properties controlling the workspace fade-out during dragging -->
-    <integer name="config_dragFadeOutAlpha">80</integer>
-    <integer name="config_dragFadeOutDuration">250</integer>
-
 <!-- Hotseat -->
     <bool name="hotseat_transpose_layout_with_orientation">true</bool>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 1a92545..5e1f3de 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -48,7 +48,6 @@
 
 <!-- Apps view -->
     <dimen name="apps_container_width">0dp</dimen>
-    <dimen name="apps_container_height">0dp</dimen>
     <dimen name="apps_container_inset">8dp</dimen>
     <dimen name="apps_grid_view_start_margin">56dp</dimen>
     <dimen name="apps_grid_section_y_offset">8dp</dimen>
@@ -67,12 +66,15 @@
 
 <!-- AllApps/Customize/AppsCustomize -->
     <dimen name="app_icon_size">48dp</dimen>
-    <dimen name="apps_customize_horizontal_padding">0dp</dimen>
 
     <!-- Drag padding to add to the bottom of drop targets -->
     <dimen name="drop_target_drag_padding">14dp</dimen>
     <dimen name="drop_target_text_size">14sp</dimen>
 
+    <dimen name="all_apps_header_max_elevation">4dp</dimen>
+    <dimen name="all_apps_header_scroll_to_elevation">16dp</dimen>
+    <dimen name="all_apps_header_shadow_height">6dp</dimen>
+
 <!-- Dragging -->
     <!-- the area at the edge of the screen that makes the workspace go left
          or right while you're dragging. -->
@@ -88,8 +90,6 @@
 
 <!-- Widget tray -->
     <dimen name="widget_container_inset">8dp</dimen>
-    <dimen name="widget_preview_size">130dp</dimen>
-    <dimen name="widget_preview_padding_top">8dp</dimen>
     <dimen name="widget_preview_label_vertical_padding">8dp</dimen>
     <dimen name="widget_preview_label_horizontal_padding">8dp</dimen>
     <dimen name="widget_preview_horizontal_padding">8dp</dimen>
@@ -99,8 +99,6 @@
     <dimen name="widget_section_vertical_padding">8dp</dimen>
     <dimen name="widget_section_horizontal_padding">16dp</dimen>
 
-    <!-- Equation: widget_preview_size + 2 * widget_preview_padding_horizontal -->
-    <dimen name="widget_preview_container_width">146dp</dimen>
     <dimen name="widget_row_padding">8dp</dimen>
     <dimen name="widget_row_divider">2dp</dimen>
 
@@ -109,13 +107,16 @@
     <dimen name="shortcut_preview_padding_right">0dp</dimen>
     <dimen name="shortcut_preview_padding_top">0dp</dimen>
 
+<!-- Theme -->
+    <dimen name="quantum_panel_outer_padding">4dp</dimen>
+
 <!-- Folders -->
     <!-- The amount that the preview contents are inset from the preview background -->
     <dimen name="folder_preview_padding">4dp</dimen>
     <dimen name="folder_name_padding">10dp</dimen>
-    <dimen name="folder_shadow_padding">8dp</dimen>
 
 <!-- Sizes for managed profile badges -->
     <dimen name="profile_badge_size">24dp</dimen>
     <dimen name="profile_badge_margin">4dp</dimen>
+    <dimen name="profile_badge_minimum_top">2dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5962584..51ad51f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -32,8 +32,6 @@
 
     <!-- Application name -->
     <string name="application_name">Launcher3</string>
-    <!-- Accessibility-facing application name -->
-    <string name="home">Home</string>
     <!-- Default folder name -->
     <string name="folder_name"></string>
     <!-- Work folder name -->
@@ -120,9 +118,6 @@
     <!-- Accessibility -->
     <skip />
 
-    <!-- The format string for Workspace descriptions [CHAR_LIMIT=none] -->
-    <string name="workspace_description_format">Home screen %1$d</string>
-
     <!-- The format string for default page scroll text [CHAR_LIMIT=none] -->
     <string name="default_scroll_format">Page %1$d of %2$d</string>
     <!-- The format string for Workspace page scroll text [CHAR_LIMIT=none] -->
@@ -145,8 +140,6 @@
     <string name="workspace_cling_longpress_description">Touch &amp; hold background to customize</string>
     <!-- The description of the button to dismiss the cling [CHAR_LIMIT=30] -->
     <string name="workspace_cling_longpress_dismiss">GOT IT</string>
-    <!-- The text on the button to dismiss a cling [CHAR_LIMIT=30] -->
-    <string name="cling_dismiss">OK</string>
 
     <!-- Folder accessibility -->
     <!-- The format string for when a folder is opened, speaks the dimensions -->
@@ -173,19 +166,9 @@
     <!-- Text for settings button -->
     <string name="settings_button_text">Settings</string>
 
-    <!-- Label on an icon that references an uninstalled package, that is going to be installed at some point. [CHAR_LIMIT=15] -->
-    <string name="package_state_enqueued">Waiting</string>
-    <!-- Label on an icon that references an uninstalled package, that is currently being downloaded. [CHAR_LIMIT=15] -->
-    <string name="package_state_downloading">Downloading</string>
-    <!-- Label on an icon that references an uninstalled package, that is currently being installed. [CHAR_LIMIT=15] -->
-    <string name="package_state_installing">Installing</string>
     <!-- Label on an icon that references an uninstalled package, for which we have no information about when it might be installed. [CHAR_LIMIT=15] -->
     <string name="package_state_unknown">Unknown</string>
-    <!-- Label on an icon that references an uninstalled package, for which restore from market has failed. [CHAR_LIMIT=15] -->
-    <string name="package_state_error">Not restored</string>
 
-    <!-- Button for abandoned promises dialog, that removes all abandoned promise icons. -->
-    <string name="abandoned_clean_all">Remove All</string>
     <!-- Button for abandoned promises dialog, to removes this abandoned promise icon. -->
     <string name="abandoned_clean_this">Remove</string>
     <!-- Button for abandoned promise dialog, to search in the market for the missing package. -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 78cc083..f95debe 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -54,7 +54,7 @@
         <item name="android:layout_height">match_parent</item>
     </style>
 
-    <style name="DropTargetButton.Base">
+    <style name="DropTargetButtonBase">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:layout_gravity">center</item>
@@ -72,7 +72,7 @@
         <item name="android:shadowRadius">4.0</item>
     </style>
 
-    <style name="DropTargetButton" parent="DropTargetButton.Base"></style>
+    <style name="DropTargetButton" parent="DropTargetButtonBase" />
 
     <style name="PreloadIcon">
         <item name="background">@drawable/virtual_preload</item>
diff --git a/res/xml/update_workspace.xml b/res/xml/update_workspace.xml
deleted file mode 100644
index 38442b9..0000000
--- a/res/xml/update_workspace.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-    <!-- Update the db with new hotseat items.  Note that we reference the browser's original
-         package name. -->
-    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
-    <favorite
-        launcher:packageName="com.android.dialer"
-        launcher:className="com.android.dialer.DialtactsActivity"
-        launcher:container="-101"
-        launcher:screen="0"
-        launcher:x="0"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.android.contacts"
-        launcher:className="com.android.contacts.activities.PeopleActivity"
-        launcher:container="-101"
-        launcher:screen="1"
-        launcher:x="1"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.android.mms"
-        launcher:className="com.android.mms.ui.ConversationList"
-        launcher:container="-101"
-        launcher:screen="3"
-        launcher:x="3"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.android.browser"
-        launcher:className="com.android.browser.BrowserActivity"
-        launcher:container="-101"
-        launcher:screen="4"
-        launcher:x="4"
-        launcher:y="0" />
-</favorites>
diff --git a/src/com/android/launcher3/AppsContainerRecyclerView.java b/src/com/android/launcher3/AppsContainerRecyclerView.java
index 3952923..5b1da4b 100644
--- a/src/com/android/launcher3/AppsContainerRecyclerView.java
+++ b/src/com/android/launcher3/AppsContainerRecyclerView.java
@@ -61,6 +61,8 @@
 
     private Drawable mScrollbar;
     private Drawable mFastScrollerBg;
+    private Rect mTmpFastScrollerInvalidateRect = new Rect();
+    private Rect mFastScrollerBounds = new Rect();
     private Rect mVerticalScrollbarBounds = new Rect();
     private boolean mDraggingFastScroller;
     private String mFastScrollSectionName;
@@ -120,6 +122,24 @@
         mApps = apps;
     }
 
+    @Override
+    public void setAdapter(Adapter adapter) {
+        // Register a change listener to update the scroll position state whenever the data set
+        // changes.
+        adapter.registerAdapterDataObserver(new AdapterDataObserver() {
+            @Override
+            public void onChanged() {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        refreshCurScrollPosition();
+                    }
+                });
+            }
+        });
+        super.setAdapter(adapter);
+    }
+
     /**
      * Sets the number of apps per row in this recycler view.
      */
@@ -128,9 +148,7 @@
         mNumPredictedAppsPerRow = numPredictedAppsPerRow;
     }
 
-    @Override
-    public void setBackground(Drawable background) {
-        super.setBackground(background);
+    public void updateBackgroundPadding(Drawable background) {
         background.getPadding(mBackgroundPadding);
     }
 
@@ -146,7 +164,7 @@
      */
     public void setFastScrollerAlpha(float alpha) {
         mFastScrollAlpha = alpha;
-        invalidateFastScroller();
+        invalidateFastScroller(mFastScrollerBounds);
     }
 
     /**
@@ -236,7 +254,13 @@
                     float boundedY = (float) Math.max(top, Math.min(bottom, y));
                     mFastScrollSectionName = scrollToPositionAtProgress((boundedY - top) /
                             (bottom - top));
-                    invalidateFastScroller();
+
+                    // Combine the old and new fast scroller bounds to create the full invalidate
+                    // rect
+                    mTmpFastScrollerInvalidateRect.set(mFastScrollerBounds);
+                    updateFastScrollerBounds();
+                    mTmpFastScrollerInvalidateRect.union(mFastScrollerBounds);
+                    invalidateFastScroller(mTmpFastScrollerInvalidateRect);
                 }
                 break;
             case MotionEvent.ACTION_UP:
@@ -272,25 +296,9 @@
      */
     private void drawFastScrollerPopup(Canvas canvas) {
         if (mFastScrollAlpha > 0f && !mFastScrollSectionName.isEmpty()) {
-            int x;
-            int y;
-            boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
-                    LAYOUT_DIRECTION_RTL);
-
-            // Calculate the position for the fast scroller popup
-            Rect bgBounds = mFastScrollerBg.getBounds();
-            if (isRtl) {
-                x = mBackgroundPadding.left + getScrollBarSize();
-            } else {
-                x = getWidth() - getPaddingRight() - getScrollBarSize() - bgBounds.width();
-            }
-            y = mLastY - (int) (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * bgBounds.height());
-            y = Math.max(getPaddingTop(), Math.min(y, getHeight() - getPaddingBottom() -
-                    bgBounds.height()));
-
             // Draw the fast scroller popup
             int restoreCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
-            canvas.translate(x, y);
+            canvas.translate(mFastScrollerBounds.left, mFastScrollerBounds.top);
             mFastScrollerBg.setAlpha((int) (mFastScrollAlpha * 255));
             mFastScrollerBg.draw(canvas);
             mFastScrollTextPaint.setAlpha((int) (mFastScrollAlpha * 255));
@@ -298,8 +306,9 @@
                     mFastScrollSectionName.length(), mFastScrollTextBounds);
             float textWidth = mFastScrollTextPaint.measureText(mFastScrollSectionName);
             canvas.drawText(mFastScrollSectionName,
-                    (bgBounds.width() - textWidth) / 2,
-                    bgBounds.height() - (bgBounds.height() - mFastScrollTextBounds.height()) / 2,
+                    (mFastScrollerBounds.width() - textWidth) / 2,
+                    mFastScrollerBounds.height() -
+                            (mFastScrollerBounds.height() - mFastScrollTextBounds.height()) / 2,
                     mFastScrollTextPaint);
             canvas.restoreToCount(restoreCount);
         }
@@ -322,9 +331,8 @@
     /**
      * Invalidates the fast scroller popup.
      */
-    private void invalidateFastScroller() {
-        invalidate(getWidth() - mBackgroundPadding.right - getScrollBarSize() -
-                mFastScrollerBg.getIntrinsicWidth(), 0, getWidth(), getHeight());
+    private void invalidateFastScroller(Rect bounds) {
+        invalidate(bounds.left, bounds.top, bounds.right, bounds.bottom);
     }
 
     /**
@@ -344,7 +352,7 @@
 
         // If there is a prediction bar, then capture the appropriate area for the prediction bar
         float predictionBarFraction = 0f;
-        if (mPredictionBarHeight > 0) {
+        if (!mApps.getPredictedApps().isEmpty()) {
             predictionBarFraction = (float) mNumPredictedAppsPerRow / mApps.getSize();
             if (touchFraction <= predictionBarFraction) {
                 // Scroll to the top of the view, where the prediction bar is
@@ -369,13 +377,7 @@
         }
 
         // We need to workaround the RecyclerView to get the right scroll position
-        List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
-        getCurScrollState(mScrollPosState, items);
-        if (mScrollPosState.rowIndex != -1) {
-            int scrollY = getPaddingTop() + (mScrollPosState.rowIndex * mScrollPosState.rowHeight) +
-                    mPredictionBarHeight - mScrollPosState.rowTopOffset;
-            updateScrollY(scrollY);
-        }
+        refreshCurScrollPosition();
 
         // Scroll to the view at the position, anchored at the top of the screen. We call the scroll
         // method on the LayoutManager directly since it is not exposed by RecyclerView.
@@ -385,7 +387,7 @@
     }
 
     /**
-     * Returns the bounds for the scrollbar.
+     * Updates the bounds for the scrollbar.
      */
     private void updateVerticalScrollbarBounds() {
         List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
@@ -399,13 +401,13 @@
         // Find the index and height of the first visible row (all rows have the same height)
         int x;
         int y;
-        boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
-                LAYOUT_DIRECTION_RTL);
+        int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
+        boolean isRtl = Utilities.isRtl(getResources());
         int rowCount = getNumRows();
         getCurScrollState(mScrollPosState, items);
         if (mScrollPosState.rowIndex != -1) {
             int height = getHeight() - getPaddingTop() - getPaddingBottom();
-            int totalScrollHeight = rowCount * mScrollPosState.rowHeight + mPredictionBarHeight;
+            int totalScrollHeight = rowCount * mScrollPosState.rowHeight + predictionBarHeight;
             if (totalScrollHeight > height) {
                 int scrollbarHeight = Math.max(mScrollbarMinHeight,
                         (int) (height / ((float) totalScrollHeight / height)));
@@ -421,7 +423,7 @@
                 // that the user has already scrolled and then map that to the scroll bar bounds
                 int availableY = totalScrollHeight - height;
                 int availableScrollY = height - scrollbarHeight;
-                y = (mScrollPosState.rowIndex * mScrollPosState.rowHeight) + mPredictionBarHeight
+                y = (mScrollPosState.rowIndex * mScrollPosState.rowHeight) + predictionBarHeight
                         - mScrollPosState.rowTopOffset;
                 y = getPaddingTop() +
                         (int) (((float) (getPaddingTop() + y) / availableY) * availableScrollY);
@@ -434,6 +436,31 @@
     }
 
     /**
+     * Updates the bounds for the fast scroller.
+     */
+    private void updateFastScrollerBounds() {
+        if (mFastScrollAlpha > 0f && !mFastScrollSectionName.isEmpty()) {
+            int x;
+            int y;
+            boolean isRtl = Utilities.isRtl(getResources());
+
+            // Calculate the position for the fast scroller popup
+            Rect bgBounds = mFastScrollerBg.getBounds();
+            if (isRtl) {
+                x = mBackgroundPadding.left + getScrollBarSize();
+            } else {
+                x = getWidth() - getPaddingRight() - getScrollBarSize() - bgBounds.width();
+            }
+            y = mLastY - (int) (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * bgBounds.height());
+            y = Math.max(getPaddingTop(), Math.min(y, getHeight() - getPaddingBottom() -
+                    bgBounds.height()));
+            mFastScrollerBounds.set(x, y, x + bgBounds.width(), y + bgBounds.height());
+        } else {
+            mFastScrollerBounds.setEmpty();
+        }
+    }
+
+    /**
      * Returns the row index for a app index in the list.
      */
     private int findRowForAppIndex(int index) {
@@ -465,6 +492,20 @@
     }
 
     /**
+     * Forces a refresh of the scroll position to any scroll listener.
+     */
+    private void refreshCurScrollPosition() {
+        List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
+        getCurScrollState(mScrollPosState, items);
+        if (mScrollPosState.rowIndex != -1) {
+            int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
+            int scrollY = getPaddingTop() + (mScrollPosState.rowIndex * mScrollPosState.rowHeight) +
+                    predictionBarHeight - mScrollPosState.rowTopOffset;
+            updateScrollY(scrollY);
+        }
+    }
+
+    /**
      * Returns the current scroll state.
      */
     private void getCurScrollState(ScrollPositionState stateOut,
@@ -472,6 +513,12 @@
         stateOut.rowIndex = -1;
         stateOut.rowTopOffset = -1;
         stateOut.rowHeight = -1;
+
+        // Return early if there are no items
+        if (items.isEmpty()) {
+            return;
+        }
+
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index 692c23f..7c1aee2 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -15,12 +15,16 @@
  */
 package com.android.launcher3;
 
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.InsetDrawable;
+import android.os.Build;
 import android.support.v7.widget.RecyclerView;
 import android.text.Editable;
 import android.text.TextWatcher;
@@ -34,8 +38,8 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
 import android.widget.TextView;
+
 import com.android.launcher3.util.Thunk;
 
 import java.util.List;
@@ -55,9 +59,7 @@
     private static final boolean ALLOW_SINGLE_APP_LAUNCH = true;
     private static final boolean DYNAMIC_HEADER_ELEVATION = true;
     private static final boolean DISMISS_SEARCH_ON_BACK = true;
-    private static final float HEADER_ELEVATION_DP = 4;
-    // How far the user has to scroll in order to reach the full elevation
-    private static final float HEADER_SCROLL_TO_ELEVATION_DP = 16;
+
     private static final int FADE_IN_DURATION = 175;
     private static final int FADE_OUT_DURATION = 100;
     private static final int SEARCH_TRANSLATION_X_DP = 18;
@@ -80,10 +82,16 @@
     private View mDismissSearchButtonView;
     private AppsContainerSearchEditTextView mSearchBarEditView;
 
+    private HeaderElevationController mElevationController;
+
     private int mNumAppsPerRow;
     private int mNumPredictedAppsPerRow;
-    private Point mLastTouchDownPos = new Point(-1, -1);
-    private Point mLastTouchPos = new Point();
+    // This coordinate is relative to this container view
+    private final Point mBoundsCheckLastTouchDownPos = new Point(-1, -1);
+    // This coordinate is relative to its parent
+    private final Point mIconLastTouchPos = new Point();
+    // This coordinate is used to proxy click and long-click events to the prediction bar icons
+    private final Point mPredictionIconTouchDownPos = new Point();
     private int mContentMarginStart;
     // Normal container insets
     private int mContainerInset;
@@ -91,6 +99,9 @@
     // RecyclerView scroll position
     @Thunk int mRecyclerViewScrollY;
 
+    private CheckLongPressHelper mPredictionIconCheckForLongPress;
+    private View mPredictionIconUnderTouch;
+
     public AppsContainerView(Context context) {
         this(context, null);
     }
@@ -164,6 +175,7 @@
      */
     public void hideHeaderBar() {
         mHeaderView.setVisibility(View.GONE);
+        mElevationController.disable();
         onUpdateBackgrounds();
         onUpdatePaddings();
     }
@@ -191,8 +203,7 @@
 
     @Override
     protected void onFinishInflate() {
-        boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
-                LAYOUT_DIRECTION_RTL);
+        boolean isRtl = Utilities.isRtl(getResources());
         mAdapter.setRtl(isRtl);
 
         // Work around the search box getting first focus and showing the cursor by
@@ -210,9 +221,13 @@
         // Fix the header view elevation if not dynamically calculating it
         mHeaderView = findViewById(R.id.header);
         mHeaderView.setOnClickListener(this);
-        if (Utilities.isLmpOrAbove() && !DYNAMIC_HEADER_ELEVATION) {
-            mHeaderView.setElevation(DynamicGrid.pxFromDp(HEADER_ELEVATION_DP,
-                getContext().getResources().getDisplayMetrics()));
+
+        mElevationController = Utilities.isLmpOrAbove() ?
+                new HeaderElevationControllerVL(mHeaderView) :
+                    new HeaderElevationControllerV16(mHeaderView);
+        if (!DYNAMIC_HEADER_ELEVATION) {
+            mElevationController.onScroll(getResources()
+                    .getDimensionPixelSize(R.dimen.all_apps_header_scroll_to_elevation));
         }
 
         // Fix the prediction bar size
@@ -283,9 +298,6 @@
                 // Otherwise, inflate a new icon
                 icon = (BubbleTextView) mLayoutInflater.inflate(
                         R.layout.apps_prediction_bar_icon_view, mPredictionBarView, false);
-                icon.setOnTouchListener(this);
-                icon.setOnClickListener(mLauncher);
-                icon.setOnLongClickListener(this);
                 icon.setFocusable(true);
                 mPredictionBarView.addView(icon);
             }
@@ -325,11 +337,14 @@
      */
     @Override
     protected void onUpdatePaddings() {
-        boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
-                LAYOUT_DIRECTION_RTL);
+        boolean isRtl = Utilities.isRtl(getResources());
         boolean hasSearchBar = (mSearchBarEditView != null) &&
                 (mSearchBarEditView.getVisibility() == View.VISIBLE);
 
+        // Set the background on the container, but let the recyclerView extend the full screen,
+        // so that the fast-scroller works on the edge as well.
+        mContentView.setPadding(0, 0, 0, 0);
+
         if (mFixedBounds.isEmpty()) {
             // If there are no fixed bounds, then use the default padding and insets
             setPadding(mInsets.left, mContainerInset + mInsets.top, mInsets.right,
@@ -372,18 +387,16 @@
     @Override
     protected void onUpdateBackgrounds() {
         int inset = mFixedBounds.isEmpty() ? mContainerInset : mFixedBoundsContainerInset;
-        boolean hasSearchBar = (mSearchBarEditView != null) &&
-                (mSearchBarEditView.getVisibility() == View.VISIBLE);
 
         // Update the background of the reveal view and list to be inset with the fixed bound
         // insets instead of the default insets
-        mAppsRecyclerView.setBackground(new InsetDrawable(
-                getContext().getResources().getDrawable(
-                        hasSearchBar ? R.drawable.apps_list_search_bg : R.drawable.apps_list_bg),
-                inset, 0, inset, 0));
-        getRevealView().setBackground(new InsetDrawable(
-                getContext().getResources().getDrawable(R.drawable.apps_reveal_bg),
-                inset, 0, inset, 0));
+        // TODO: Use quantum_panel instead of quantum_panel_shape.
+        InsetDrawable background = new InsetDrawable(
+                getContext().getResources().getDrawable(R.drawable.quantum_panel_shape),
+                inset, 0, inset, 0);
+        mContentView.setBackground(background);
+        mAppsRecyclerView.updateBackgroundPadding(background);
+        getRevealView().setBackground(background.getConstantState().newDrawable());
     }
 
     @Override
@@ -391,17 +404,19 @@
         return handleTouchEvent(ev);
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         return handleTouchEvent(ev);
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouch(View v, MotionEvent ev) {
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
             case MotionEvent.ACTION_MOVE:
-                mLastTouchPos.set((int) ev.getX(), (int) ev.getY());
+                mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
                 break;
         }
         return false;
@@ -427,7 +442,7 @@
         if (!mLauncher.isDraggingEnabled()) return false;
 
         // Start the drag
-        mLauncher.getWorkspace().beginDragShared(v, mLastTouchPos, this, false);
+        mLauncher.getWorkspace().beginDragShared(v, mIconLastTouchPos, this, false);
         // Enter spring loaded mode
         mLauncher.enterSpringLoadedDragMode();
 
@@ -609,23 +624,25 @@
     /**
      * Updates the container when the recycler view is scrolled.
      */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     private void onRecyclerViewScrolled() {
-        if (DYNAMIC_HEADER_ELEVATION && Utilities.isLmpOrAbove()) {
-            int elevation = DynamicGrid.pxFromDp(HEADER_ELEVATION_DP,
-                    getContext().getResources().getDisplayMetrics());
-            int scrollToElevation = DynamicGrid.pxFromDp(HEADER_SCROLL_TO_ELEVATION_DP,
-                    getContext().getResources().getDisplayMetrics());
-            float elevationPct = (float) Math.min(mRecyclerViewScrollY, scrollToElevation) /
-                    scrollToElevation;
-            float newElevation = elevation * elevationPct;
-            if (Float.compare(mHeaderView.getElevation(), newElevation) != 0) {
-                mHeaderView.setElevation(newElevation);
-            }
+        if (DYNAMIC_HEADER_ELEVATION) {
+            mElevationController.onScroll(mRecyclerViewScrollY);
         }
 
         mPredictionBarView.setTranslationY(-mRecyclerViewScrollY + mAppsRecyclerView.getPaddingTop());
     }
 
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        // If we were waiting for long-click, cancel the request once a child has started handling
+        // the scrolling
+        if (mPredictionIconCheckForLongPress != null) {
+            mPredictionIconCheckForLongPress.cancelLongPress();
+        }
+        super.requestDisallowInterceptTouchEvent(disallowIntercept);
+    }
+
     /**
      * Handles the touch events to dismiss all apps when clicking outside the bounds of the
      * recycler view.
@@ -633,31 +650,44 @@
     private boolean handleTouchEvent(MotionEvent ev) {
         LauncherAppState app = LauncherAppState.getInstance();
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        int x = (int) ev.getX();
+        int y = (int) ev.getY();
 
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
+                // We workaround the fact that the recycler view needs the touches for the scroll
+                // and we want to intercept it for clicks in the prediction bar by handling clicks
+                // and long clicks in the prediction bar ourselves.
+                mPredictionIconTouchDownPos.set(x, y);
+                mPredictionIconUnderTouch = findPredictedAppAtCoordinate(x, y);
+                if (mPredictionIconUnderTouch != null) {
+                    mPredictionIconCheckForLongPress =
+                            new CheckLongPressHelper(mPredictionIconUnderTouch, this);
+                    mPredictionIconCheckForLongPress.postCheckForLongPress();
+                }
+
                 if (!mFixedBounds.isEmpty()) {
                     // Outset the fixed bounds and check if the touch is outside all apps
                     Rect tmpRect = new Rect(mFixedBounds);
                     tmpRect.inset(-grid.allAppsIconSizePx / 2, 0);
                     if (ev.getX() < tmpRect.left || ev.getX() > tmpRect.right) {
-                        mLastTouchDownPos.set((int) ev.getX(), (int) ev.getY());
+                        mBoundsCheckLastTouchDownPos.set(x, y);
                         return true;
                     }
                 } else {
                     // Check if the touch is outside all apps
                     if (ev.getX() < getPaddingLeft() ||
                             ev.getX() > (getWidth() - getPaddingRight())) {
-                        mLastTouchDownPos.set((int) ev.getX(), (int) ev.getY());
+                        mBoundsCheckLastTouchDownPos.set(x, y);
                         return true;
                     }
                 }
                 break;
             case MotionEvent.ACTION_UP:
-                if (mLastTouchDownPos.x > -1) {
+                if (mBoundsCheckLastTouchDownPos.x > -1) {
                     ViewConfiguration viewConfig = ViewConfiguration.get(getContext());
-                    float dx = ev.getX() - mLastTouchDownPos.x;
-                    float dy = ev.getY() - mLastTouchDownPos.y;
+                    float dx = ev.getX() - mBoundsCheckLastTouchDownPos.x;
+                    float dy = ev.getY() - mBoundsCheckLastTouchDownPos.y;
                     float distance = (float) Math.hypot(dx, dy);
                     if (distance < viewConfig.getScaledTouchSlop()) {
                         // The background was clicked, so just go home
@@ -666,15 +696,49 @@
                         return true;
                     }
                 }
+
+                // Trigger the click on the prediction bar icon if that's where we touched
+                if (mPredictionIconUnderTouch != null &&
+                        !mPredictionIconCheckForLongPress.hasPerformedLongPress()) {
+                    mLauncher.onClick(mPredictionIconUnderTouch);
+                }
+
                 // Fall through
             case MotionEvent.ACTION_CANCEL:
-                mLastTouchDownPos.set(-1, -1);
+                mBoundsCheckLastTouchDownPos.set(-1, -1);
+                mPredictionIconTouchDownPos.set(-1, -1);
+
+                // On touch up/cancel, cancel the long press on the prediction bar icon if it has
+                // not yet been performed
+                if (mPredictionIconCheckForLongPress != null) {
+                    mPredictionIconCheckForLongPress.cancelLongPress();
+                    mPredictionIconCheckForLongPress = null;
+                }
+                mPredictionIconUnderTouch = null;
+
                 break;
         }
         return false;
     }
 
     /**
+     * Returns the predicted app in the prediction bar given a set of local coordinates.
+     */
+    private View findPredictedAppAtCoordinate(int x, int y) {
+        int[] coord = {x, y};
+        Rect hitRect = new Rect();
+        Utilities.mapCoordInSelfToDescendent(mPredictionBarView, this, coord);
+        for (int i = 0; i < mPredictionBarView.getChildCount(); i++) {
+            View child = mPredictionBarView.getChildAt(i);
+            child.getHitRect(hitRect);
+            if (hitRect.contains(coord[0], coord[1])) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Shows the search field.
      */
     private void showSearchField() {
@@ -773,4 +837,79 @@
     private InputMethodManager getInputMethodManager() {
         return (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
     }
+
+    private static interface HeaderElevationController {
+
+        public void onScroll(int scrollY);
+
+        public void disable();
+    }
+
+    private static final class HeaderElevationControllerV16 implements HeaderElevationController {
+
+        private final View mShadow;
+
+        private final float mScrollToElevation;
+
+        public HeaderElevationControllerV16(View header) {
+            Resources res = header.getContext().getResources();
+            mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation);
+
+            mShadow = new View(header.getContext());
+            mShadow.setBackground(new GradientDrawable(
+                    GradientDrawable.Orientation.TOP_BOTTOM, new int[] {0x44000000, 0x00000000}));
+            mShadow.setAlpha(0);
+
+            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                    LayoutParams.MATCH_PARENT,
+                    res.getDimensionPixelSize(R.dimen.all_apps_header_shadow_height));
+            lp.topMargin = ((FrameLayout.LayoutParams) header.getLayoutParams()).height;
+
+            ((ViewGroup) header.getParent()).addView(mShadow, lp);
+        }
+
+        @Override
+        public void onScroll(int scrollY) {
+            float elevationPct = (float) Math.min(scrollY, mScrollToElevation) /
+                    mScrollToElevation;
+            mShadow.setAlpha(elevationPct);
+        }
+
+        @Override
+        public void disable() {
+            ViewGroup parent = (ViewGroup) mShadow.getParent();
+            if (parent != null) {
+                parent.removeView(mShadow);
+            }
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    private static final class HeaderElevationControllerVL implements HeaderElevationController {
+
+        private final View mHeader;
+        private final float mMaxElevation;
+        private final float mScrollToElevation;
+
+        public HeaderElevationControllerVL(View header) {
+            mHeader = header;
+
+            Resources res = header.getContext().getResources();
+            mMaxElevation = res.getDimension(R.dimen.all_apps_header_max_elevation);
+            mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation);
+        }
+
+        @Override
+        public void onScroll(int scrollY) {
+            float elevationPct = (float) Math.min(scrollY, mScrollToElevation) /
+                    mScrollToElevation;
+            float newElevation = mMaxElevation * elevationPct;
+            if (Float.compare(mHeader.getElevation(), newElevation) != 0) {
+                mHeader.setElevation(newElevation);
+            }
+        }
+
+        @Override
+        public void disable() { }
+    }
 }
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index d32c919..bbcd893 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -25,6 +26,7 @@
 import android.graphics.Canvas;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.util.SparseArray;
 import android.util.TypedValue;
@@ -444,15 +446,20 @@
     /**
      * Sets the icon for this view based on the layout direction.
      */
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     private Drawable setIcon(Drawable icon, int iconSize) {
         mIcon = icon;
         if (iconSize != -1) {
             mIcon.setBounds(0, 0, iconSize, iconSize);
         }
         if (mLayoutHorizontal) {
-            setCompoundDrawablesRelative(mIcon, null, null, null);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                setCompoundDrawablesRelative(mIcon, null, null, null);
+            } else {
+                setCompoundDrawables(mIcon, null, null, null);
+            }
         } else {
-            setCompoundDrawablesRelative(null, mIcon, null, null);
+            setCompoundDrawables(null, mIcon, null, null);
         }
         return icon;
     }
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 683c511..b8214d1 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -83,6 +83,7 @@
         }
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     protected void setDrawable(int resId) {
         // Get the hover color
         mDrawable = (TransitionDrawable) getCurrentDrawable();
@@ -90,7 +91,11 @@
         if (mDrawable == null) {
             // TODO: investigate why this is ever happening. Presently only on one known device.
             mDrawable = (TransitionDrawable) getResources().getDrawable(resId);
-            setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
+            } else {
+                setCompoundDrawablesWithIntrinsicBounds(mDrawable, null, null, null);
+            }
         }
 
         if (null != mDrawable) {
@@ -107,7 +112,7 @@
     }
 
     protected Drawable getCurrentDrawable() {
-        Drawable[] drawables = getCompoundDrawablesRelative();
+        Drawable[] drawables = getCompoundDrawables();
         for (int i = 0; i < drawables.length; ++i) {
             if (drawables[i] != null) {
                 return drawables[i];
@@ -241,10 +246,6 @@
         outRect.offsetTo(coords[0], coords[1]);
     }
 
-    private boolean isRtl() {
-        return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
-    }
-
     protected Rect getIconRect(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight) {
         DragLayer dragLayer = mLauncher.getDragLayer();
 
@@ -258,7 +259,7 @@
         final int left;
         final int right;
 
-        if (isRtl()) {
+        if (Utilities.isRtl(getResources())) {
             right = to.right - getPaddingRight();
             left = right - width;
         } else {
diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java
index 10ca6a3..381b678 100644
--- a/src/com/android/launcher3/CheckLongPressHelper.java
+++ b/src/com/android/launcher3/CheckLongPressHelper.java
@@ -22,6 +22,7 @@
 
 public class CheckLongPressHelper {
     @Thunk View mView;
+    @Thunk View.OnLongClickListener mListener;
     @Thunk boolean mHasPerformedLongPress;
     private CheckForLongPress mPendingCheckForLongPress;
 
@@ -29,7 +30,13 @@
         public void run() {
             if ((mView.getParent() != null) && mView.hasWindowFocus()
                     && !mHasPerformedLongPress) {
-                if (mView.performLongClick()) {
+                boolean handled;
+                if (mListener != null) {
+                    handled = mListener.onLongClick(mView);
+                } else {
+                    handled = mView.performLongClick();
+                }
+                if (handled) {
                     mView.setPressed(false);
                     mHasPerformedLongPress = true;
                 }
@@ -41,6 +48,11 @@
         mView = v;
     }
 
+    public CheckLongPressHelper(View v, View.OnLongClickListener listener) {
+        mView = v;
+        mListener = listener;
+    }
+
     public void postCheckForLongPress() {
         mHasPerformedLongPress = false;
 
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index dc6de07..ad0afd9 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -443,7 +443,7 @@
         int availableAppsWidthPx = (containerWidth > 0) ? containerWidth : availableWidthPx;
         int numAppsCols = (availableAppsWidthPx - appsViewLeftMarginPx) /
                 (allAppsCellWidthPx + 2 * allAppsCellPaddingPx);
-        int numPredictiveAppCols = isPhone() ? numColumns : numAppsCols;
+        int numPredictiveAppCols = isPhone() ? 4 : numAppsCols;
         if ((numAppsCols != appsViewNumCols) ||
                 (numPredictiveAppCols != appsViewNumPredictiveCols)) {
             appsViewNumCols = numAppsCols;
@@ -459,11 +459,7 @@
         isLandscape = (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE);
         isTablet = resources.getBoolean(R.bool.is_tablet);
         isLargeTablet = resources.getBoolean(R.bool.is_large_tablet);
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            isLayoutRtl = (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
-        } else {
-            isLayoutRtl = false;
-        }
+        isLayoutRtl = Utilities.isRtl(resources);
         widthPx = wPx;
         heightPx = hPx;
         availableWidthPx = awPx;
diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java
index 5fea9d8..f5c29ae 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -71,6 +71,7 @@
     // temporaries to avoid gc thrash
     private Rect mRectTemp = new Rect();
     private final int[] mCoordinatesTemp = new int[2];
+    private final boolean mIsRtl;
 
     /** Whether or not we're dragging. */
     private boolean mDragging;
@@ -157,6 +158,7 @@
         float density = r.getDisplayMetrics().density;
         mFlingToDeleteThresholdVelocity =
                 (int) (r.getInteger(R.integer.config_flingToDeleteMinVelocity) * density);
+        mIsRtl = Utilities.isRtl(r);
     }
 
     public boolean dragging() {
@@ -548,9 +550,8 @@
         final int slop = ViewConfiguration.get(mLauncher).getScaledWindowTouchSlop();
         final int delay = mDistanceSinceScroll < slop ? RESCROLL_DELAY : SCROLL_DELAY;
         final DragLayer dragLayer = mLauncher.getDragLayer();
-        final boolean isRtl = (dragLayer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
-        final int forwardDirection = isRtl ? SCROLL_RIGHT : SCROLL_LEFT;
-        final int backwardsDirection = isRtl ? SCROLL_LEFT : SCROLL_RIGHT;
+        final int forwardDirection = mIsRtl ? SCROLL_RIGHT : SCROLL_LEFT;
+        final int backwardsDirection = mIsRtl ? SCROLL_LEFT : SCROLL_RIGHT;
 
         if (x < mScrollZone) {
             if (mScrollState == SCROLL_OUTSIDE_ZONE) {
diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java
index 2efdb06..e25e615 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
@@ -46,6 +47,10 @@
  * A ViewGroup that coordinates dragging across its descendants
  */
 public class DragLayer extends InsettableFrameLayout {
+
+    // Scrim color without any alpha component.
+    private static final int SCRIM_COLOR = Color.BLACK & 0x00FFFFFF;
+
     @Thunk DragController mDragController;
     private int[] mTmpXY = new int[2];
 
@@ -55,6 +60,7 @@
     // Variables relating to resizing widgets
     private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
             new ArrayList<AppWidgetResizeFrame>();
+    private final boolean mIsRtl;
     private AppWidgetResizeFrame mCurrentResizeFrame;
 
     // Variables relating to animation of views after drop
@@ -78,7 +84,6 @@
     private int mChildCountOnLastUpdate = -1;
 
     // Darkening scrim
-    private Drawable mBackground;
     private float mBackgroundAlpha = 0;
 
     // Related to adjacent page hints
@@ -109,7 +114,7 @@
         mRightHoverDrawable = res.getDrawable(R.drawable.page_hover_right);
         mLeftHoverDrawableActive = res.getDrawable(R.drawable.page_hover_left_active);
         mRightHoverDrawableActive = res.getDrawable(R.drawable.page_hover_right_active);
-        mBackground = res.getDrawable(R.drawable.apps_customize_bg);
+        mIsRtl = Utilities.isRtl(res);
     }
 
     public void setup(Launcher launcher, DragController controller) {
@@ -917,21 +922,12 @@
         invalidate();
     }
 
-    /**
-     * Note: this is a reimplementation of View.isLayoutRtl() since that is currently hidden api.
-     */
-    private boolean isLayoutRtl() {
-        return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
-    }
-
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        // Draw the background gradient below children.
-        if (mBackground != null && mBackgroundAlpha > 0.0f) {
+        // Draw the background below children.
+        if (mBackgroundAlpha > 0.0f) {
             int alpha = (int) (mBackgroundAlpha * 255);
-            mBackground.setAlpha(alpha);
-            mBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
-            mBackground.draw(canvas);
+            canvas.drawColor((alpha << 24) | SCRIM_COLOR);
         }
 
         super.dispatchDraw(canvas);
@@ -946,9 +942,8 @@
                     childRect);
 
             int page = workspace.getNextPage();
-            final boolean isRtl = isLayoutRtl();
-            CellLayout leftPage = (CellLayout) workspace.getChildAt(isRtl ? page + 1 : page - 1);
-            CellLayout rightPage = (CellLayout) workspace.getChildAt(isRtl ? page - 1 : page + 1);
+            CellLayout leftPage = (CellLayout) workspace.getChildAt(mIsRtl ? page + 1 : page - 1);
+            CellLayout rightPage = (CellLayout) workspace.getChildAt(mIsRtl ? page - 1 : page + 1);
 
             if (leftPage != null && leftPage.isDragTarget()) {
                 Drawable left = mInScrollArea && leftPage.getIsDragOverlapping() ?
diff --git a/src/com/android/launcher3/DragView.java b/src/com/android/launcher3/DragView.java
index 3eec3d9..120299e 100644
--- a/src/com/android/launcher3/DragView.java
+++ b/src/com/android/launcher3/DragView.java
@@ -76,6 +76,7 @@
      * @param registrationX The x coordinate of the registration point.
      * @param registrationY The y coordinate of the registration point.
      */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY,
             int left, int top, int width, int height, final float initialScale) {
         super(launcher);
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 377e8ee..131633c 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -21,13 +21,13 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
+import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.drawable.InsetDrawable;
 import android.os.Build;
 import android.text.InputType;
 import android.text.Selection;
@@ -49,7 +49,6 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-
 import com.android.launcher3.CellLayout.CellInfo;
 import com.android.launcher3.DragController.DragListener;
 import com.android.launcher3.FolderInfo.FolderListener;
@@ -57,7 +56,6 @@
 import com.android.launcher3.UninstallDropTarget.UninstallSource;
 import com.android.launcher3.Workspace.ItemOperator;
 import com.android.launcher3.util.Thunk;
-
 import java.util.ArrayList;
 import java.util.Collections;
 
@@ -183,15 +181,6 @@
         // name is complete, we have something to focus on, thus hiding the cursor and giving
         // reliable behavior when clicking the text field (since it will always gain focus on click).
         setFocusableInTouchMode(true);
-
-        if (Utilities.isLmpOrAbove()) {
-            int padding = getResources().getDimensionPixelSize(R.dimen.folder_shadow_padding);
-            setBackground(new InsetDrawable(
-                    getResources().getDrawable(R.drawable.apps_list_bg),
-                    padding, padding, padding, padding));
-        } else {
-            setBackgroundResource(R.drawable.quantum_panel);
-        }
     }
 
     @Override
@@ -340,6 +329,7 @@
     /**
      * We need to handle touch events to prevent them from falling through to the workspace below.
      */
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         return true;
@@ -416,8 +406,9 @@
      *
      * @return A new UserFolder.
      */
-    static Folder fromXml(Context context) {
-        return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
+    static Folder fromXml(Launcher launcher) {
+        return (Folder) LayoutInflater.from(launcher).inflate(R.layout.user_folder,
+                launcher.getDragLayer(), false);
     }
 
     /**
@@ -708,10 +699,10 @@
         boolean isOutsideLeftEdge = x < cellOverlap;
         boolean isOutsideRightEdge = x > (getWidth() - cellOverlap);
 
-        if (currentPage > 0 && (mContent.rtlLayout ? isOutsideRightEdge : isOutsideLeftEdge)) {
+        if (currentPage > 0 && (mContent.mIsRtl ? isOutsideRightEdge : isOutsideLeftEdge)) {
             showScrollHint(DragController.SCROLL_LEFT, d);
         } else if (currentPage < (mContent.getPageCount() - 1)
-                && (mContent.rtlLayout ? isOutsideLeftEdge : isOutsideRightEdge)) {
+                && (mContent.mIsRtl ? isOutsideLeftEdge : isOutsideRightEdge)) {
             showScrollHint(DragController.SCROLL_RIGHT, d);
         } else {
             mOnScrollHintAlarm.cancelAlarm();
diff --git a/src/com/android/launcher3/FolderPagedView.java b/src/com/android/launcher3/FolderPagedView.java
index 125de3f..de30b60 100644
--- a/src/com/android/launcher3/FolderPagedView.java
+++ b/src/com/android/launcher3/FolderPagedView.java
@@ -55,7 +55,7 @@
 
     private static final int[] sTempPosArray = new int[2];
 
-    public final boolean rtlLayout;
+    public final boolean mIsRtl;
 
     private final LayoutInflater mInflater;
     private final IconCache mIconCache;
@@ -89,7 +89,7 @@
         mInflater = LayoutInflater.from(context);
         mIconCache = app.getIconCache();
 
-        rtlLayout = getResources().getConfiguration().getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        mIsRtl = Utilities.isRtl(getResources());
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
     }
 
@@ -441,7 +441,7 @@
      * Scrolls the current view by a fraction
      */
     public void showScrollHint(int direction) {
-        float fraction = (direction == DragController.SCROLL_LEFT) ^ rtlLayout
+        float fraction = (direction == DragController.SCROLL_LEFT) ^ mIsRtl
                 ? -SCROLL_HINT_FRACTION : SCROLL_HINT_FRACTION;
         int hint = (int) (fraction * getWidth());
         int scroll = getScrollForPage(getNextPage()) + hint;
@@ -598,7 +598,7 @@
                         }
                     };
                     v.animate()
-                        .translationXBy((direction > 0 ^ rtlLayout) ? -v.getWidth() : v.getWidth())
+                        .translationXBy((direction > 0 ^ mIsRtl) ? -v.getWidth() : v.getWidth())
                         .setDuration(REORDER_ANIMATION_DURATION)
                         .setStartDelay(0)
                         .withEndAction(endAction);
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index f1ff48d..f3383cc 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -16,8 +16,10 @@
 
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
+import android.os.Build;
 import android.provider.Settings;
 import android.util.AttributeSet;
 
@@ -68,10 +70,18 @@
         return source.supportsAppInfoDropTarget() && supportsDrop(getContext(), info);
     }
 
+    @SuppressWarnings("deprecation")
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public static boolean supportsDrop(Context context, Object info) {
-        return (Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) &&
-                (info instanceof AppInfo || info instanceof PendingAddItemInfo);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            return (Settings.Global.getInt(context.getContentResolver(),
+                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) &&
+                    (info instanceof AppInfo || info instanceof PendingAddItemInfo);
+        } else {
+            return (Settings.Secure.getInt(context.getContentResolver(),
+                    Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) &&
+                    (info instanceof AppInfo || info instanceof PendingAddItemInfo);
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8603a35..72472b9 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -22,6 +22,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -64,7 +65,6 @@
 import android.os.Message;
 import android.os.StrictMode;
 import android.os.SystemClock;
-import android.preference.PreferenceManager;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
@@ -2582,6 +2582,7 @@
         }
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     public boolean onTouch(View v, MotionEvent event) {
         return false;
     }
@@ -2850,6 +2851,7 @@
     public View.OnTouchListener getHapticFeedbackTouchListener() {
         if (mHapticFeedbackTouchListener == null) {
             mHapticFeedbackTouchListener = new View.OnTouchListener() {
+                @SuppressLint("ClickableViewAccessibility")
                 @Override
                 public boolean onTouch(View v, MotionEvent event) {
                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index be295f8..6ff7666 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -21,10 +21,11 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.os.Build;
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.ViewTreeObserver;
-
 import java.util.HashSet;
 import java.util.WeakHashMap;
 
@@ -128,6 +129,7 @@
         return anim;
     }
 
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public static Animator createCircularReveal(View view, int centerX,
             int centerY, float startRadius, float endRadius) {
         Animator anim = ViewAnimationUtils.createCircularReveal(view, centerX,
diff --git a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
index af680f2..e19bc95 100644
--- a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
@@ -1,10 +1,12 @@
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Parcel;
 
 /**
@@ -32,6 +34,7 @@
         info.writeToParcel(p, 0);
         p.setDataPosition(0);
         LauncherAppWidgetProviderInfo lawpi = new LauncherAppWidgetProviderInfo(p);
+        p.recycle();
 
         int[] minResizeSpan = Launcher.getMinSpanForWidget(context, lawpi);
         int[] span = Launcher.getSpanForWidget(context, lawpi);
@@ -64,6 +67,7 @@
         minSpanY = widget.getMinSpanY();
     }
 
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public String getLabel(PackageManager packageManager) {
         if (isCustomWidget) {
             return Utilities.trim(label);
@@ -71,6 +75,7 @@
         return super.loadLabel(packageManager);
     }
 
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public Drawable getIcon(Context context, IconCache cache) {
         if (isCustomWidget) {
             return cache.getFullResIcon(provider.getPackageName(), icon);
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index a2c56a9..63d3ebc 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -20,10 +20,12 @@
 import android.accounts.AccountManager;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
+import android.annotation.TargetApi;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -34,7 +36,6 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityManager;
-
 import com.android.launcher3.util.Thunk;
 
 class LauncherClings implements OnClickListener {
@@ -212,6 +213,7 @@
     }
 
     /** Returns whether the clings are enabled or should be shown */
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
     private boolean areClingsEnabled() {
         if (DISABLE_CLINGS) {
             return false;
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index f9f5ae1..8bc8988 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -52,6 +52,7 @@
 import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.util.ManagedProfileHeuristic;
 import com.android.launcher3.util.Thunk;
 
 import java.io.File;
@@ -64,7 +65,7 @@
     private static final String TAG = "Launcher.LauncherProvider";
     private static final boolean LOGD = false;
 
-    private static final int DATABASE_VERSION = 24;
+    private static final int DATABASE_VERSION = 25;
 
     static final String OLD_AUTHORITY = "com.android.launcher2.settings";
     static final String AUTHORITY = ProviderConfig.AUTHORITY;
@@ -475,6 +476,9 @@
             // Fresh and clean launcher DB.
             mMaxItemId = initializeMaxItemId(db);
             setFlagEmptyDbCreated();
+
+            // When a new DB is created, remove all previously stored managed profile information.
+            ManagedProfileHeuristic.processAllUsers(Collections.EMPTY_LIST, mContext);
         }
 
         private void addWorkspacesTable(SQLiteDatabase db) {
@@ -620,7 +624,9 @@
                 }
                 case 23:
                     convertShortcutsToLauncherActivities(db);
-                case 24: {
+                case 24:
+                    ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mContext);
+                case 25: {
                     // DB Upgraded successfully
                     return;
                 }
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 73ae51c..3243754 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -22,16 +22,17 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.content.res.Resources;
+import android.os.Build;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
-
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.widget.WidgetsContainerView;
-
 import java.util.HashMap;
 
 /**
@@ -227,6 +228,7 @@
     /**
      * Creates and starts a new animation to a particular overlay view.
      */
+    @SuppressLint("NewApi")
     private void startAnimationToOverlay(final Workspace.State toWorkspaceState, final View toView,
              final View contentView, final View revealView, final boolean animated,
              final boolean hideSearchBar, final PrivateTransitionCallbacks pCb) {
diff --git a/src/com/android/launcher3/MemoryTracker.java b/src/com/android/launcher3/MemoryTracker.java
index 2d37c80..067a50f 100644
--- a/src/com/android/launcher3/MemoryTracker.java
+++ b/src/com/android/launcher3/MemoryTracker.java
@@ -101,7 +101,7 @@
 
     public void startTrackingProcess(int pid, String name, long start) {
         synchronized (mLock) {
-            final Long lpid = new Long(pid);
+            final Long lpid = Long.valueOf(pid);
 
             if (mPids.contains(lpid)) return;
 
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e27ea64..554a975 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -221,6 +221,7 @@
     private static final Rect sTmpRect = new Rect();
 
     protected final Rect mInsets = new Rect();
+    protected final boolean mIsRtl;
 
     public interface PageSwitchListener {
         void onPageSwitch(View newPage, int newPageIndex);
@@ -248,6 +249,7 @@
         a.recycle();
 
         setHapticFeedbackEnabled(false);
+        mIsRtl = Utilities.isRtl(getResources());
         init();
     }
 
@@ -403,13 +405,6 @@
     }
 
     /**
-     * Note: this is a reimplementation of View.isLayoutRtl() since that is currently hidden api.
-     */
-    public boolean isLayoutRtl() {
-        return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
-    }
-
-    /**
      * Returns the index of the currently displayed page.
      */
     int getCurrentPage() {
@@ -586,16 +581,15 @@
             x = Math.max(x, mFreeScrollMinScrollX);
         }
 
-        final boolean isRtl = isLayoutRtl();
         mUnboundedScrollX = x;
 
-        boolean isXBeforeFirstPage = isRtl ? (x > mMaxScrollX) : (x < 0);
-        boolean isXAfterLastPage = isRtl ? (x < 0) : (x > mMaxScrollX);
+        boolean isXBeforeFirstPage = mIsRtl ? (x > mMaxScrollX) : (x < 0);
+        boolean isXAfterLastPage = mIsRtl ? (x < 0) : (x > mMaxScrollX);
         if (isXBeforeFirstPage) {
             super.scrollTo(0, y);
             if (mAllowOverScroll) {
                 mWasInOverscroll = true;
-                if (isRtl) {
+                if (mIsRtl) {
                     overScroll(x - mMaxScrollX);
                 } else {
                     overScroll(x);
@@ -605,7 +599,7 @@
             super.scrollTo(mMaxScrollX, y);
             if (mAllowOverScroll) {
                 mWasInOverscroll = true;
-                if (isRtl) {
+                if (mIsRtl) {
                     overScroll(x);
                 } else {
                     overScroll(x - mMaxScrollX);
@@ -701,15 +695,35 @@
             super(width, height);
         }
 
+        public LayoutParams(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
         public LayoutParams(ViewGroup.LayoutParams source) {
             super(source);
         }
     }
 
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
     protected LayoutParams generateDefaultLayoutParams() {
         return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
     }
 
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return new LayoutParams(p);
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams;
+    }
+
     public void addFullScreenPage(View page) {
         LayoutParams lp = generateDefaultLayoutParams();
         lp.isFullScreenPage = true;
@@ -844,11 +858,9 @@
         // Update the viewport offsets
         mViewport.offset(offsetX,  offsetY);
 
-        final boolean isRtl = isLayoutRtl();
-
-        final int startIndex = isRtl ? childCount - 1 : 0;
-        final int endIndex = isRtl ? -1 : childCount;
-        final int delta = isRtl ? -1 : 1;
+        final int startIndex = mIsRtl ? childCount - 1 : 0;
+        final int endIndex = mIsRtl ? -1 : childCount;
+        final int delta = mIsRtl ? -1 : 1;
 
         int verticalPadding = getPaddingTop() + getPaddingBottom();
 
@@ -952,7 +964,7 @@
     private void updateMaxScrollX() {
         int childCount = getChildCount();
         if (childCount > 0) {
-            final int index = isLayoutRtl() ? 0 : childCount - 1;
+            final int index = mIsRtl ? 0 : childCount - 1;
             mMaxScrollX = getScrollForPage(index);
         } else {
             mMaxScrollX = 0;
@@ -1262,7 +1274,7 @@
      * Return true if a tap at (x, y) should trigger a flip to the previous page.
      */
     protected boolean hitsPreviousPage(float x, float y) {
-        if (isLayoutRtl()) {
+        if (mIsRtl) {
             return (x > (getViewportOffsetX() + getViewportWidth() -
                     getPaddingRight() - mPageSpacing));
         }
@@ -1273,7 +1285,7 @@
      * Return true if a tap at (x, y) should trigger a flip to the next page.
      */
     protected boolean hitsNextPage(float x, float y) {
-        if (isLayoutRtl()) {
+        if (mIsRtl) {
             return (x < getViewportOffsetX() + getPaddingLeft() + mPageSpacing);
         }
         return  (x > (getViewportOffsetX() + getViewportWidth() -
@@ -1463,7 +1475,7 @@
         final int totalDistance;
 
         int adjacentPage = page + 1;
-        if ((delta < 0 && !isLayoutRtl()) || (delta > 0 && isLayoutRtl())) {
+        if ((delta < 0 && !mIsRtl) || (delta > 0 && mIsRtl)) {
             adjacentPage = page - 1;
         }
 
@@ -1498,7 +1510,7 @@
             int scrollOffset = 0;
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
             if (!lp.isFullScreenPage) {
-                scrollOffset = isLayoutRtl() ? getPaddingRight() : getPaddingLeft();
+                scrollOffset = mIsRtl ? getPaddingRight() : getPaddingLeft();
             }
 
             int baselineX = mPageScrolls[index] + scrollOffset + getViewportOffsetX();
@@ -1575,7 +1587,7 @@
 
     void updateFreescrollBounds() {
         getFreeScrollPageRange(mTempVisiblePagesRange);
-        if (isLayoutRtl()) {
+        if (mIsRtl) {
             mFreeScrollMinScrollX = getScrollForPage(mTempVisiblePagesRange[1]);
             mFreeScrollMaxScrollX = getScrollForPage(mTempVisiblePagesRange[0]);
         } else {
@@ -1814,9 +1826,8 @@
                     // We give flings precedence over large moves, which is why we short-circuit our
                     // test for a large move if a fling has been registered. That is, a large
                     // move to the left and fling to the right will register as a fling to the right.
-                    final boolean isRtl = isLayoutRtl();
-                    boolean isDeltaXLeft = isRtl ? deltaX > 0 : deltaX < 0;
-                    boolean isVelocityXLeft = isRtl ? velocityX > 0 : velocityX < 0;
+                    boolean isDeltaXLeft = mIsRtl ? deltaX > 0 : deltaX < 0;
+                    boolean isVelocityXLeft = mIsRtl ? velocityX > 0 : velocityX < 0;
                     if (((isSignificantMove && !isDeltaXLeft && !isFling) ||
                             (isFling && !isVelocityXLeft)) && mCurrentPage > 0) {
                         finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
@@ -1940,7 +1951,7 @@
                         hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
                     }
                     if (hscroll != 0 || vscroll != 0) {
-                        boolean isForwardScroll = isLayoutRtl() ? (hscroll < 0 || vscroll < 0)
+                        boolean isForwardScroll = mIsRtl ? (hscroll < 0 || vscroll < 0)
                                                          : (hscroll > 0 || vscroll > 0);
                         if (isForwardScroll) {
                             scrollRight();
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 56c8b39..490ed6a 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -170,11 +170,7 @@
     }
 
     public boolean invertLayoutHorizontally() {
-        return mInvertIfRtl && isLayoutRtl();
-    }
-
-    public boolean isLayoutRtl() {
-        return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
+        return mInvertIfRtl && Utilities.isRtl(getResources());
     }
 
     @Override
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index c351135..0fc8f32 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -1,5 +1,6 @@
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Build;
@@ -7,7 +8,6 @@
 import android.os.UserManager;
 import android.util.AttributeSet;
 import android.util.Pair;
-
 import com.android.launcher3.R;
 import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.util.Thunk;
@@ -36,6 +36,7 @@
         return supportsDrop(getContext(), info);
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
     public static boolean supportsDrop(Context context, Object info) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 2981747..f3435fc 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -631,4 +631,10 @@
         Matcher m = sTrimPattern.matcher(s);
         return m.replaceAll("$1");
     }
+
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    public static boolean isRtl(Resources res) {
+        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) &&
+                (res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
+    }
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 93bfeaf..fe09fb6 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -444,7 +444,7 @@
             } catch (Resources.NotFoundException e) { }
             c.setBitmap(null);
         }
-        return mManager.getBadgeBitmap(info, preview);
+        return mManager.getBadgeBitmap(info, preview, Math.min(preview.getHeight(), previewHeight));
     }
 
     private Bitmap generateShortcutPreview(
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4004b1d..58e5877 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -21,6 +21,7 @@
 import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
+import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.app.WallpaperManager;
 import android.appwidget.AppWidgetHostView;
@@ -56,7 +57,6 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.widget.TextView;
-
 import com.android.launcher3.FolderIcon.FolderRingAnimator;
 import com.android.launcher3.Launcher.CustomContentCallbacks;
 import com.android.launcher3.Launcher.LauncherOverlay;
@@ -70,7 +70,6 @@
 import com.android.launcher3.util.WallpaperUtils;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -553,8 +552,10 @@
             throw new RuntimeException("Screen id " + screenId + " already exists!");
         }
 
-        CellLayout newScreen = (CellLayout)
-                mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
+        // Inflate the cell layout, but do not add it automatically so that we can get the newly
+        // created CellLayout.
+        CellLayout newScreen = (CellLayout) mLauncher.getLayoutInflater().inflate(
+                        R.layout.workspace_screen, this, false /* attachToRoot */);
 
         newScreen.setOnLongClickListener(mLongClickListener);
         newScreen.setOnClickListener(mLauncher);
@@ -573,7 +574,7 @@
 
     public void createCustomContentContainer() {
         CellLayout customScreen = (CellLayout)
-                mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
+                mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, this, false);
         customScreen.disableBackground();
         customScreen.disableDragTarget();
 
@@ -1033,6 +1034,7 @@
      * listener via setOnInterceptTouchEventListener(). This allows us to tell the CellLayout
      * that it should intercept touch events, which is not something that is normally supported.
      */
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouch(View v, MotionEvent event) {
         return (workspaceInModalState() || !isFinishedSwitchingState())
@@ -1136,7 +1138,7 @@
         boolean passRightSwipesToCustomContent =
                 (mTouchDownTime - mCustomContentShowTime) > CUSTOM_CONTENT_GESTURE_DELAY;
 
-        boolean swipeInIgnoreDirection = isLayoutRtl() ? deltaX < 0 : deltaX > 0;
+        boolean swipeInIgnoreDirection = mIsRtl ? deltaX < 0 : deltaX > 0;
         boolean onCustomContentScreen =
                 getScreenIdForPageIndex(getCurrentPage()) == CUSTOM_CONTENT_SCREEN_ID;
         if (swipeInIgnoreDirection && onCustomContentScreen && passRightSwipesToCustomContent) {
@@ -1243,15 +1245,14 @@
 
     @Override
     protected void overScroll(float amount) {
-        boolean isRtl = isLayoutRtl();
-        boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || isRtl)) ||
-                (amount >= 0 && (!hasCustomContent() || !isRtl));
+        boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || mIsRtl)) ||
+                (amount >= 0 && (!hasCustomContent() || !mIsRtl));
 
         boolean shouldScrollOverlay = mLauncherOverlay != null &&
-                ((amount <= 0 && !isRtl) || (amount >= 0 && isRtl));
+                ((amount <= 0 && !mIsRtl) || (amount >= 0 && mIsRtl));
 
         boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlaySroll != 0 &&
-                ((amount >= 0 && !isRtl) || (amount <= 0 && isRtl));
+                ((amount >= 0 && !mIsRtl) || (amount <= 0 && mIsRtl));
 
         if (shouldScrollOverlay) {
             if (!mStartedSendingScrollEvents && mScrollInteractionBegan) {
@@ -1265,7 +1266,7 @@
             int progress = (int) Math.abs((f * 100));
 
             mLastOverlaySroll = progress;
-            mLauncherOverlay.onScrollChange(progress, isRtl);
+            mLauncherOverlay.onScrollChange(progress, mIsRtl);
         } else if (shouldOverScroll) {
             dampedOverScroll(amount);
             mOverScrollEffect = acceleratedOverFactor(amount);
@@ -1274,7 +1275,7 @@
         }
 
         if (shouldZeroOverlay) {
-            mLauncherOverlay.onScrollChange(0, isRtl);
+            mLauncherOverlay.onScrollChange(0, mIsRtl);
         }
     }
 
@@ -1409,7 +1410,7 @@
             mNumPagesForWallpaperParallax = parallaxPageSpan;
 
             if (getChildCount() <= 1) {
-                if (isLayoutRtl()) {
+                if (mIsRtl) {
                     return 1 - 1.0f/mNumPagesForWallpaperParallax;
                 }
                 return 0;
@@ -1420,7 +1421,7 @@
             int firstIndex = numCustomPages();
             // Exclude the last extra empty screen (if we have > MIN_PARALLAX_PAGE_SPAN pages)
             int lastIndex = getChildCount() - 1 - emptyExtraPages;
-            if (isLayoutRtl()) {
+            if (mIsRtl) {
                 int temp = firstIndex;
                 firstIndex = lastIndex;
                 lastIndex = temp;
@@ -1441,7 +1442,7 @@
                 // On RTL devices, push the wallpaper offset to the right if we don't have enough
                 // pages (ie if numScrollingPages < MIN_PARALLAX_PAGE_SPAN)
                 if (!mWallpaperIsLiveWallpaper && numScrollingPages < MIN_PARALLAX_PAGE_SPAN
-                        && isLayoutRtl()) {
+                        && mIsRtl) {
                     return offset * (parallaxPageSpan - numScrollingPages + 1) / parallaxPageSpan;
                 }
                 return offset * (numScrollingPages - 1) / parallaxPageSpan;
@@ -1648,7 +1649,7 @@
             translationX = scrollRange - scrollDelta;
             progress = (scrollRange - scrollDelta) / scrollRange;
 
-            if (isLayoutRtl()) {
+            if (mIsRtl) {
                 translationX = Math.min(0, translationX);
             } else {
                 translationX = Math.max(0, translationX);
@@ -1702,7 +1703,6 @@
 
     @Override
     protected void screenScrolled(int screenCenter) {
-        final boolean isRtl = isLayoutRtl();
         super.screenScrolled(screenCenter);
 
         updatePageAlphaValues(screenCenter);
@@ -1717,7 +1717,7 @@
             final int upperIndex = getChildCount() - 1;
 
             final boolean isLeftPage = mOverScrollX < 0;
-            index = (!isRtl && isLeftPage) || (isRtl && !isLeftPage) ? lowerIndex : upperIndex;
+            index = (!mIsRtl && isLeftPage) || (mIsRtl && !isLeftPage) ? lowerIndex : upperIndex;
 
             CellLayout cl = (CellLayout) getChildAt(index);
             float effect = Math.abs(mOverScrollEffect);
diff --git a/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java
index d3f5230..c5b52de 100644
--- a/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java
@@ -16,17 +16,20 @@
 
 package com.android.launcher3.accessibility;
 
+import android.annotation.TargetApi;
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.util.SparseArray;
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class OverviewScreenAccessibilityDelegate extends AccessibilityDelegate {
 
     private static final int MOVE_BACKWARD = R.id.action_move_screen_backwards;
@@ -39,7 +42,7 @@
         mWorkspace = workspace;
 
         Context context = mWorkspace.getContext();
-        boolean isRtl = mWorkspace.isLayoutRtl();
+        boolean isRtl = Utilities.isRtl(context.getResources());
         mActions.put(MOVE_BACKWARD, new AccessibilityAction(MOVE_BACKWARD,
                 context.getText(isRtl ? R.string.action_move_screen_right :
                     R.string.action_move_screen_left)));
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
index e41a66f..7aa36d4 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
@@ -78,6 +78,7 @@
 
     public abstract Drawable loadIcon(LauncherAppWidgetProviderInfo info, IconCache cache);
 
-    public abstract Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap);
+    public abstract Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap,
+            int imageHeight);
 
 }
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
index 967b53b..a64c705 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.app.Activity;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
@@ -49,6 +50,7 @@
         return Utilities.trim(info.label);
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     @Override
     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, AppWidgetProviderInfo info,
             Bundle options) {
@@ -85,7 +87,7 @@
     }
 
     @Override
-    public Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap) {
+    public Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap, int imageHeight) {
         return bitmap;
     }
 }
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
index 6c3e092..96ace84 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
@@ -108,7 +108,7 @@
     }
 
     @Override
-    public Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap) {
+    public Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap, int imageHeight) {
         if (info.isCustomWidget || info.getProfile().equals(android.os.Process.myUserHandle())) {
             return bitmap;
         }
@@ -117,9 +117,10 @@
         final Resources res = mContext.getResources();
         final int badgeSize = res.getDimensionPixelSize(R.dimen.profile_badge_size);
         final int badgeMargin = res.getDimensionPixelSize(R.dimen.profile_badge_margin);
+        final int badgeMinTop = res.getDimensionPixelSize(R.dimen.profile_badge_minimum_top);
         final Rect badgeLocation = new Rect(0, 0, badgeSize, badgeSize);
 
-        final int top = bitmap.getHeight() - badgeSize - badgeMargin;
+        final int top = Math.max(imageHeight - badgeSize - badgeMargin, badgeMinTop);
         if (res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
             badgeLocation.offset(badgeMargin, top);
         } else {
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
index b52cf1d..4448758 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
@@ -16,12 +16,14 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
+import android.os.Build;
 
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class LauncherActivityInfoCompatVL extends LauncherActivityInfoCompat {
     private LauncherActivityInfo mLauncherActivityInfo;
 
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index e0d28b5..c862ffc 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -32,6 +33,7 @@
 import java.util.List;
 import java.util.Map;
 
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class LauncherAppsCompatVL extends LauncherAppsCompat {
 
     private LauncherApps mLauncherApps;
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index 395d5f9..3ad5101 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -16,10 +16,12 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionCallback;
 import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Build;
 import android.os.Handler;
 import android.util.SparseArray;
 
@@ -30,6 +32,7 @@
 
 import java.util.HashMap;
 
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class PackageInstallerCompatVL extends PackageInstallerCompat {
 
     @Thunk final SparseArray<String> mActiveSessions = new SparseArray<>();
diff --git a/src/com/android/launcher3/compat/UserHandleCompat.java b/src/com/android/launcher3/compat/UserHandleCompat.java
index 2ae6731..d8e60b8 100644
--- a/src/com/android/launcher3/compat/UserHandleCompat.java
+++ b/src/com/android/launcher3/compat/UserHandleCompat.java
@@ -16,10 +16,10 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.content.Intent;
 import android.os.Build;
 import android.os.UserHandle;
-
 import com.android.launcher3.Utilities;
 
 public class UserHandleCompat {
@@ -32,6 +32,7 @@
     private UserHandleCompat() {
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public static UserHandleCompat myUserHandle() {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             return new UserHandleCompat(android.os.Process.myUserHandle());
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV17.java b/src/com/android/launcher3/compat/UserManagerCompatV17.java
index 055359a..c42c00c 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV17.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV17.java
@@ -16,14 +16,12 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
+import android.os.Build;
 import android.os.UserManager;
 
-import java.util.ArrayList;
-import java.util.List;
-
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
 public class UserManagerCompatV17 extends UserManagerCompatV16 {
     protected UserManager mUserManager;
 
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index 884d6fe..f6434c5 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -17,18 +17,19 @@
 
 package com.android.launcher3.compat;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.UserHandle;
-
 import com.android.launcher3.LauncherAppState;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class UserManagerCompatVL extends UserManagerCompatV17 {
     private static final String USER_CREATION_TIME_KEY = "user_creation_time_";
 
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index cefa71c..ae67ba0 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -274,4 +274,30 @@
         keysOut.add(INSTALLED_PACKAGES_PREFIX + userSerial);
         keysOut.add(USER_FOLDER_ID_PREFIX + userSerial);
     }
+
+    /**
+     * 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);
+        UserHandleCompat myUser = UserHandleCompat.myUserHandle();
+
+        SharedPreferences prefs = null;
+        for (UserHandleCompat user : userManager.getUserProfiles()) {
+            if (myUser.equals(user)) {
+                continue;
+            }
+
+            if (prefs == null) {
+                prefs = context.getSharedPreferences(
+                        LauncherFiles.MANAGED_USER_PREFERENCES_KEY,
+                        Context.MODE_PRIVATE);
+            }
+            String folderIdKey = USER_FOLDER_ID_PREFIX + userManager.getSerialNumberForUser(user);
+            if (!prefs.contains(folderIdKey)) {
+                prefs.edit().putLong(folderIdKey, ItemInfo.NO_ID).apply();
+            }
+        }
+    }
 }
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 7ca4df9..aade85f 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -62,7 +62,7 @@
     private ImageView mWidgetImage;
     private TextView mWidgetName;
     private TextView mWidgetDims;
-    private final Rect mOriginalImagePadding = new Rect();
+    private final Rect mOrigImgPadding = new Rect();
 
     private String mDimensionsFormatString;
     private boolean mIsAppWidget;
@@ -102,10 +102,10 @@
         super.onFinishInflate();
 
         mWidgetImage = (ImageView) findViewById(R.id.widget_preview);
-        mOriginalImagePadding.left = mWidgetImage.getPaddingLeft();
-        mOriginalImagePadding.top = mWidgetImage.getPaddingTop();
-        mOriginalImagePadding.right = mWidgetImage.getPaddingRight();
-        mOriginalImagePadding.bottom = mWidgetImage.getPaddingBottom();
+        mOrigImgPadding.left = mWidgetImage.getPaddingLeft();
+        mOrigImgPadding.top = mWidgetImage.getPaddingTop();
+        mOrigImgPadding.right = mWidgetImage.getPaddingRight();
+        mOrigImgPadding.bottom = mWidgetImage.getPaddingBottom();
 
         mWidgetName = ((TextView) findViewById(R.id.widget_name));
         mWidgetDims = ((TextView) findViewById(R.id.widget_dims));
@@ -164,6 +164,7 @@
 
     public int[] getPreviewSize() {
         int[] maxSize = new int[2];
+
         maxSize[0] = mPresetPreviewSize;
         maxSize[1] = mPresetPreviewSize;
         return maxSize;
@@ -171,25 +172,21 @@
 
     public void applyPreview(Bitmap bitmap) {
         FastBitmapDrawable preview = new FastBitmapDrawable(bitmap);
-        if (DEBUG) {
-            Log.d(TAG, String.format("[tag=%s] applyPreview preview: %s",
-                    getTagToString(), preview));
-        }
+
         if (preview != null) {
             mWidgetImage.setImageDrawable(preview);
+
             if (mIsAppWidget) {
                 // center horizontally
                 int[] imageSize = getPreviewSize();
                 int centerAmount = (imageSize[0] - preview.getIntrinsicWidth()) / 2;
-                mWidgetImage.setPadding(mOriginalImagePadding.left + centerAmount,
-                        mOriginalImagePadding.top,
-                        mOriginalImagePadding.right,
-                        mOriginalImagePadding.bottom);
+                mWidgetImage.setPadding(mOrigImgPadding.left + centerAmount,
+                        mOrigImgPadding.top,
+                        mOrigImgPadding.right,
+                        mOrigImgPadding.bottom);
             }
             mWidgetImage.setAlpha(0f);
             mWidgetImage.animate().alpha(1.0f).setDuration(FADE_IN_DURATION_MS);
-            // TODO(hyunyoungs): figure out why this has to be called explicitly.
-            mWidgetImage.requestLayout();
         }
     }
 
@@ -202,11 +199,6 @@
             Log.d(TAG, String.format("[tag=%s] ensurePreview (%d, %d):",
                     getTagToString(), size[0], size[1]));
         }
-
-        if (size[0] <= 0 || size[1] <= 0) {
-            addOnLayoutChangeListener(this);
-            return;
-        }
         Bitmap[] immediateResult = new Bitmap[1];
         mActiveRequest = mWidgetPreviewLoader.getPreview(mInfo, size[0], size[1], this,
                 immediateResult);
diff --git a/src/com/android/launcher3/widget/WidgetImageView.java b/src/com/android/launcher3/widget/WidgetImageView.java
index 75167bc..f1eaf64 100644
--- a/src/com/android/launcher3/widget/WidgetImageView.java
+++ b/src/com/android/launcher3/widget/WidgetImageView.java
@@ -22,18 +22,11 @@
 import android.widget.ImageView;
 
 public class WidgetImageView extends ImageView {
-    public boolean mAllowRequestLayout = true;
 
     public WidgetImageView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    public void requestLayout() {
-        if (mAllowRequestLayout) {
-            super.requestLayout();
-        }
-    }
-
     @Override
     protected void onDraw(Canvas canvas) {
         canvas.save();
diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java
index d6e0628..2dbe7a5 100644
--- a/src/com/android/launcher3/widget/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java
@@ -15,8 +15,10 @@
  */
 package com.android.launcher3.widget;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.pm.ResolveInfo;
+import android.os.Build;
 import android.support.v7.widget.RecyclerView;
 import android.content.res.Resources;
 import android.support.v7.widget.RecyclerView.Adapter;
@@ -27,9 +29,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.LinearLayout;
-
 import com.android.launcher3.BubbleTextView;
-
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.DynamicGrid;
 import com.android.launcher3.IconCache;
@@ -38,7 +38,6 @@
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.WidgetPreviewLoader;
-
 import java.util.List;
 
 /**
@@ -152,11 +151,12 @@
                 widget.setTag(pasi);
                 widget.applyFromResolveInfo(mLauncher.getPackageManager(), info, mWidgetPreviewLoader);
             }
-            widget.setVisibility(View.VISIBLE);
             widget.ensurePreview();
+            widget.setVisibility(View.VISIBLE);
         }
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     @Override
     public WidgetsRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         if (DEBUG) {
@@ -167,7 +167,11 @@
                 R.layout.widgets_list_row_view, parent, false);
         LinearLayout cellList = (LinearLayout) container.findViewById(R.id.widgets_cell_list);
         MarginLayoutParams lp = (MarginLayoutParams) cellList.getLayoutParams();
-        lp.setMarginStart(mIndent);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            lp.setMarginStart(mIndent);
+        } else {
+            lp.leftMargin = mIndent;
+        }
         cellList.setLayoutParams(lp);
         return new WidgetsRowViewHolder(container);
     }