Fixing folders to always show in view, removing old assets and references to LauncherModel count.
diff --git a/res/drawable-hdpi/divider_launcher_holo.9.png b/res/drawable-hdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 3b7f000..0000000
--- a/res/drawable-hdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_scrubber_holo.9.png b/res/drawable-hdpi/hotseat_scrubber_holo.9.png
deleted file mode 100644
index 00645c4..0000000
--- a/res/drawable-hdpi/hotseat_scrubber_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_track_holo.9.png b/res/drawable-hdpi/hotseat_track_holo.9.png
deleted file mode 100644
index 255add0..0000000
--- a/res/drawable-hdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/page_hover_left_holo.9.png b/res/drawable-hdpi/page_hover_left_holo.9.png
index 2ac2c39..c3243a9 100644
--- a/res/drawable-hdpi/page_hover_left_holo.9.png
+++ b/res/drawable-hdpi/page_hover_left_holo.9.png
Binary files differ
diff --git a/res/drawable-land-hdpi/divider_launcher_holo.9.png b/res/drawable-land-hdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 23a0f97..0000000
--- a/res/drawable-land-hdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-hdpi/hotseat_track_holo.9.png b/res/drawable-land-hdpi/hotseat_track_holo.9.png
deleted file mode 100644
index 255add0..0000000
--- a/res/drawable-land-hdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-mdpi/divider_launcher_holo.9.png b/res/drawable-land-mdpi/divider_launcher_holo.9.png
deleted file mode 100644
index e4c0c40..0000000
--- a/res/drawable-land-mdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-mdpi/hotseat_track_holo.9.png b/res/drawable-land-mdpi/hotseat_track_holo.9.png
deleted file mode 100644
index 168f092..0000000
--- a/res/drawable-land-mdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xhdpi/divider_launcher_holo.9.png b/res/drawable-land-xhdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 0b2956d..0000000
--- a/res/drawable-land-xhdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xhdpi/hotseat_track_holo.9.png b/res/drawable-land-xhdpi/hotseat_track_holo.9.png
deleted file mode 100644
index 3ad3c0d..0000000
--- a/res/drawable-land-xhdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/divider_launcher_holo.9.png b/res/drawable-mdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 7bdf323..0000000
--- a/res/drawable-mdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_scrubber_holo.9.png b/res/drawable-mdpi/hotseat_scrubber_holo.9.png
deleted file mode 100644
index 1b335d8..0000000
--- a/res/drawable-mdpi/hotseat_scrubber_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_track_holo.9.png b/res/drawable-mdpi/hotseat_track_holo.9.png
deleted file mode 100644
index 168f092..0000000
--- a/res/drawable-mdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/page_hover_left_holo.9.png b/res/drawable-mdpi/page_hover_left_holo.9.png
index e1e84c9..f436fe7 100644
--- a/res/drawable-mdpi/page_hover_left_holo.9.png
+++ b/res/drawable-mdpi/page_hover_left_holo.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/divider_launcher_holo.9.png b/res/drawable-sw600dp-hdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 0a1bd2a..0000000
--- a/res/drawable-sw600dp-hdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-land-hdpi/divider_launcher_holo.9.png b/res/drawable-sw600dp-land-hdpi/divider_launcher_holo.9.png
deleted file mode 100644
index e8bcf0a..0000000
--- a/res/drawable-sw600dp-land-hdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-land-mdpi/divider_launcher_holo.9.png b/res/drawable-sw600dp-land-mdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 5c3e9f3..0000000
--- a/res/drawable-sw600dp-land-mdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/divider_launcher_holo.9.png b/res/drawable-sw600dp-mdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 6d101f4..0000000
--- a/res/drawable-sw600dp-mdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw720dp-land-hdpi/divider_launcher_holo.9.png b/res/drawable-sw720dp-land-hdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 0a1bd2a..0000000
--- a/res/drawable-sw720dp-land-hdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw720dp-land-mdpi/divider_launcher_holo.9.png b/res/drawable-sw720dp-land-mdpi/divider_launcher_holo.9.png
deleted file mode 100644
index 6d101f4..0000000
--- a/res/drawable-sw720dp-land-mdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/divider_launcher_holo.9.png b/res/drawable-xhdpi/divider_launcher_holo.9.png
deleted file mode 100644
index e226ae7..0000000
--- a/res/drawable-xhdpi/divider_launcher_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/hotseat_scrubber_holo.9.png b/res/drawable-xhdpi/hotseat_scrubber_holo.9.png
deleted file mode 100644
index a32b139..0000000
--- a/res/drawable-xhdpi/hotseat_scrubber_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/hotseat_track_holo.9.png b/res/drawable-xhdpi/hotseat_track_holo.9.png
deleted file mode 100644
index 3ad3c0d..0000000
--- a/res/drawable-xhdpi/hotseat_track_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/page_hover_left_holo.9.png b/res/drawable-xhdpi/page_hover_left_holo.9.png
index b00d367..6833a59 100644
--- a/res/drawable-xhdpi/page_hover_left_holo.9.png
+++ b/res/drawable-xhdpi/page_hover_left_holo.9.png
Binary files differ
diff --git a/res/layout/scroll_indicator.xml b/res/layout/scroll_indicator.xml
deleted file mode 100644
index 4ea312b..0000000
--- a/res/layout/scroll_indicator.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.
--->
-<ImageView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:visibility="gone"
-    android:alpha="0"
-    android:scaleType="fitXY"
-    android:src="@drawable/hotseat_scrubber_holo" />
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 245d7ea..899b1f2 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -438,6 +438,9 @@
     }
 
     public void onPackagesUpdated(ArrayList<Object> widgetsAndShortcuts) {
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+
         // Get the list of widgets and shortcuts
         mWidgets.clear();
         for (Object o : widgetsAndShortcuts) {
@@ -450,8 +453,8 @@
                     int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget);
                     int minSpanX = Math.min(spanXY[0], minSpanXY[0]);
                     int minSpanY = Math.min(spanXY[1], minSpanXY[1]);
-                    if (minSpanX <= LauncherModel.getCellCountX() &&
-                        minSpanY <= LauncherModel.getCellCountY()) {
+                    if (minSpanX <= (int) grid.numColumns &&
+                        minSpanY <= (int) grid.numRows) {
                         mWidgets.add(widget);
                     } else {
                         Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" +
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 52b76b8..3c41804 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -189,6 +189,8 @@
         setClipToPadding(false);
         mLauncher = (Launcher) context;
 
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
 
         mCellWidth = -1;
@@ -196,8 +198,8 @@
         mWidthGap = mOriginalWidthGap = 0;
         mHeightGap = mOriginalHeightGap = 0;
         mMaxGap = Integer.MAX_VALUE;
-        mCountX = LauncherModel.getCellCountX();
-        mCountY = LauncherModel.getCellCountY();
+        mCountX = (int) grid.numColumns;
+        mCountY = (int) grid.numRows;
         mOccupied = new boolean[mCountX][mCountY];
         mTmpOccupied = new boolean[mCountX][mCountY];
         mPreviousReorderDirection[0] = INVALID_DIRECTION;
@@ -208,8 +210,6 @@
         setAlwaysDrawnWithCacheEnabled(false);
 
         final Resources res = getResources();
-        LauncherAppState app = LauncherAppState.getInstance();
-        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
         mHotseatScale = (float) grid.hotseatIconSize / grid.iconSize;
 
         mNormalBackground = res.getDrawable(R.drawable.homescreen_blue_normal_holo);
@@ -1204,6 +1204,11 @@
             int left = topLeft[0];
             int top = topLeft[1];
 
+            // Offset icons by their padding
+            if (v instanceof BubbleTextView) {
+                top += v.getPaddingTop();
+            }
+
             if (v != null && dragOffset == null) {
                 // When drawing the drag outline, it did not account for margin offsets
                 // added by the view's parent.
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 37cccfb..16af648 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -68,6 +68,8 @@
 
     int widthPx;
     int heightPx;
+    int availableWidthPx;
+    int availableHeightPx;
     int iconSizePx;
     int iconTextSizePx;
     int cellWidthPx;
@@ -100,16 +102,15 @@
     }
 
     DeviceProfile(ArrayList<DeviceProfile> profiles,
-                  float minWidth, int minWidthPx,
-                  float minHeight, int minHeightPx,
+                  float minWidth, float minHeight,
                   int wPx, int hPx,
+                  int awPx, int ahPx,
                   Resources resources) {
         DisplayMetrics dm = resources.getDisplayMetrics();
         ArrayList<DeviceProfileQuery> points =
                 new ArrayList<DeviceProfileQuery>();
         transposeLayoutWithOrientation =
                 resources.getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
-        updateFromConfiguration(resources, wPx, hPx);
         minWidthDps = minWidth;
         minHeightDps = minHeight;
 
@@ -133,16 +134,16 @@
             points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconSize));
         }
         iconSize = invDistWeightedInterpolate(minWidth, minHeight, points);
-        iconSizePx = (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                iconSize, dm));
+        iconSizePx = DynamicGrid.pxFromDp(iconSize, dm);
+
         // Interpolate the icon text size
         points.clear();
         for (DeviceProfile p : profiles) {
             points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconTextSize));
         }
         iconTextSize = invDistWeightedInterpolate(minWidth, minHeight, points);
-        iconTextSizePx = (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
-                iconTextSize, dm));
+        iconTextSizePx = DynamicGrid.pxFromSp(iconTextSize, dm);
+
         // Interpolate the hotseat size
         points.clear();
         for (DeviceProfile p : profiles) {
@@ -154,14 +155,12 @@
         for (DeviceProfile p : profiles) {
             points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.hotseatIconSize));
         }
-
         // Hotseat
         hotseatIconSize = invDistWeightedInterpolate(minWidth, minHeight, points);
-        hotseatIconSizePx = (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                hotseatIconSize, dm));
-        hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx;
-        hotseatCellWidthPx = iconSizePx;
-        hotseatCellHeightPx = iconSizePx;
+        hotseatIconSizePx = DynamicGrid.pxFromDp(hotseatIconSize, dm);
+
+        // Calculate other vars based on Configuration
+        updateFromConfiguration(resources, wPx, hPx, awPx, ahPx);
 
         // Search Bar
         searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
@@ -176,6 +175,27 @@
         cellWidthPx = iconSizePx;
         cellHeightPx = iconSizePx + (int) Math.ceil(fm.bottom - fm.top);
 
+        // At this point, if the cells do not fit into the available height, then we need
+        // to shrink the icon size
+        /*
+        Rect padding = getWorkspacePadding(isLandscape ?
+                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
+        int h = (int) (numRows * cellHeightPx) + padding.top + padding.bottom;
+        if (h > availableHeightPx) {
+            float delta = h - availableHeightPx;
+            int deltaPx = (int) Math.ceil(delta / numRows);
+            iconSizePx -= deltaPx;
+            iconSize = DynamicGrid.dpiFromPx(iconSizePx, dm);
+            cellWidthPx = iconSizePx;
+            cellHeightPx = iconSizePx + (int) Math.ceil(fm.bottom - fm.top);
+        }
+        */
+
+        // Hotseat
+        hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx;
+        hotseatCellWidthPx = iconSizePx;
+        hotseatCellHeightPx = iconSizePx;
+
         // Folder
         folderCellWidthPx = cellWidthPx + 3 * edgeMarginPx;
         folderCellHeightPx = cellHeightPx + edgeMarginPx;
@@ -183,13 +203,17 @@
         folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
     }
 
-    void updateFromConfiguration(Resources resources, int wPx, int hPx) {
+    void updateFromConfiguration(Resources resources, int wPx, int hPx,
+                                 int awPx, int ahPx) {
+        DisplayMetrics dm = resources.getDisplayMetrics();
         isLandscape = (resources.getConfiguration().orientation ==
                 Configuration.ORIENTATION_LANDSCAPE);
         isTablet = resources.getBoolean(R.bool.is_tablet);
         isLargeTablet = resources.getBoolean(R.bool.is_large_tablet);
         widthPx = wPx;
         heightPx = hPx;
+        availableWidthPx = awPx;
+        availableHeightPx = ahPx;
     }
 
     private float dist(PointF p0, PointF p1) {
@@ -415,13 +439,22 @@
     private float mMinWidth;
     private float mMinHeight;
 
-    public static int dpiFromPx(int size, DisplayMetrics metrics){
+    public static float dpiFromPx(int size, DisplayMetrics metrics){
         float densityRatio = (float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT;
-        return (int) Math.round(size / densityRatio);
+        return (size / densityRatio);
+    }
+    public static int pxFromDp(float size, DisplayMetrics metrics) {
+        return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                size, metrics));
+    }
+    public static int pxFromSp(float size, DisplayMetrics metrics) {
+        return (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
+                size, metrics));
     }
 
     public DynamicGrid(Resources resources, int minWidthPx, int minHeightPx,
-                       int widthPx, int heightPx) {
+                       int widthPx, int heightPx,
+                       int awPx, int ahPx) {
         DisplayMetrics dm = resources.getDisplayMetrics();
         ArrayList<DeviceProfile> deviceProfiles =
                 new ArrayList<DeviceProfile>();
@@ -456,9 +489,9 @@
         mMinWidth = dpiFromPx(minWidthPx, dm);
         mMinHeight = dpiFromPx(minHeightPx, dm);
         mProfile = new DeviceProfile(deviceProfiles,
-                mMinWidth, minWidthPx,
-                mMinHeight, minHeightPx,
+                mMinWidth, mMinHeight,
                 widthPx, heightPx,
+                awPx, ahPx,
                 resources);
     }
 
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index d428abc..6308bb7 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -29,7 +29,9 @@
 import android.text.Selection;
 import android.text.Spannable;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -85,7 +87,6 @@
     private int mMaxCountY;
     private int mMaxVisibleX;
     private int mMaxVisibleY;
-    private int mMaxContentAreaHeight = 0;
     private int mMaxNumItems;
     private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
     private Drawable mIconDrawable;
@@ -108,8 +109,6 @@
     private float mFolderIconPivotX;
     private float mFolderIconPivotY;
 
-    private static final int SCROLL_CUT_OFF_AMOUNT = 60;
-
     private static final float MAX_SCROLL_VELOCITY = 1500f;
 
     private boolean mIsEditingName = false;
@@ -146,7 +145,8 @@
         mIconCache = app.getIconCache();
 
         Resources res = getResources();
-        mMaxCountX = mMaxVisibleX = mMaxVisibleY = (int) (grid.numColumns);
+        mMaxCountX = mMaxVisibleX = (int) grid.numColumns;
+        mMaxVisibleY = (int) grid.numRows;
         mMaxCountY = mMaxNumItems = Integer.MAX_VALUE;
 
         mInputMethodManager = (InputMethodManager)
@@ -175,11 +175,11 @@
 
         LauncherAppState app = LauncherAppState.getInstance();
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        Rect padding = grid.getWorkspacePadding(grid.isLandscape ?
+                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
+        DisplayMetrics dm = getResources().getDisplayMetrics();
 
-        // Beyond this height, the area scrolls
         mContent.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
-        mContent.setGridSize(mMaxVisibleX, mMaxVisibleY);
-        mMaxContentAreaHeight = mContent.getDesiredHeight() - SCROLL_CUT_OFF_AMOUNT;
         mContent.setGridSize(0, 0);
         mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
         mContent.setInvertIfRtl(true);
@@ -875,9 +875,9 @@
     private void centerAboutIcon() {
         DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
 
+        DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
         int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
         int height = getFolderHeight();
-        DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
 
         float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, mTempRect);
 
@@ -945,31 +945,33 @@
         centerAboutIcon();
     }
 
+    private int getContentAreaHeight() {
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        Rect workspacePadding = grid.getWorkspacePadding(grid.isLandscape ?
+                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
+        int maxContentAreaHeight = grid.availableHeightPx -
+                4 * grid.edgeMarginPx -
+                workspacePadding.top - workspacePadding.bottom -
+                getPaddingTop() - getPaddingBottom() -
+                mFolderNameHeight;
+        return Math.min(maxContentAreaHeight,
+                mContent.getDesiredHeight());
+    }
+
     private int getFolderHeight() {
-        int contentAreaHeight = mContent.getDesiredHeight();
-        if (contentAreaHeight >= mMaxContentAreaHeight) {
-            // Subtract a bit so the user can see that it's scrollable.
-            contentAreaHeight = mMaxContentAreaHeight;
-        }
-        int height = getPaddingTop() + getPaddingBottom() + contentAreaHeight
-                + mFolderNameHeight;
+        int height = getPaddingTop() + getPaddingBottom()
+                + getContentAreaHeight() + mFolderNameHeight;
         return height;
     }
 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int contentAreaHeight = mContent.getDesiredHeight();
-        if (contentAreaHeight >= mMaxContentAreaHeight) {
-            // Subtract a bit so the user can see that it's scrollable.
-            contentAreaHeight = mMaxContentAreaHeight;
-        }
-
         int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
         int height = getFolderHeight();
         int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredWidth(),
                 MeasureSpec.EXACTLY);
-        int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(contentAreaHeight,
+        int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(getContentAreaHeight(),
                 MeasureSpec.EXACTLY);
-
         mContent.setFixedSize(mContent.getDesiredWidth(), mContent.getDesiredHeight());
         mScrollView.measure(contentAreaWidthSpec, contentAreaHeightSpec);
         mFolderName.measure(contentAreaWidthSpec,
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 244b3db..5cfecb7 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -192,8 +192,8 @@
             data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
 
         // Queue the item up for adding if launcher has not loaded properly yet
-        boolean launcherNotLoaded = LauncherModel.getCellCountX() <= 0 ||
-                LauncherModel.getCellCountY() <= 0;
+        LauncherAppState app = LauncherAppState.getInstance();
+        boolean launcherNotLoaded = (app.getDynamicGrid() == null);
 
         PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, name, intent);
         info.icon = icon;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d5fafac..7fc7033 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -68,6 +68,7 @@
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.method.TextKeyListener;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Display;
 import android.view.Gravity;
@@ -376,11 +377,14 @@
         Display display = getWindowManager().getDefaultDisplay();
         display.getCurrentSizeRange(smallestSize, largestSize);
         display.getRealSize(realSize);
+        DisplayMetrics dm = new DisplayMetrics();
+        display.getMetrics(dm);
         // Lazy-initialize the dynamic grid
         DeviceProfile grid = app.initDynamicGrid(this,
                 Math.min(smallestSize.x, smallestSize.y),
                 Math.min(largestSize.x, largestSize.y),
-                realSize.x, realSize.y);
+                realSize.x, realSize.y,
+                dm.widthPixels, dm.heightPixels);
 
         // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet
         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 53d2ec5..c8b208b 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -164,21 +164,22 @@
         return SHARED_PREFERENCES_KEY;
     }
 
-    DeviceProfile initDynamicGrid(Context context, int minWidth, int minHeight, int width, int height) {
+    DeviceProfile initDynamicGrid(Context context, int minWidth, int minHeight,
+                                  int width, int height,
+                                  int availableWidth, int availableHeight) {
         boolean created = false;
         if (mDynamicGrid == null) {
             mDynamicGrid = new DynamicGrid(context.getResources(),
-                    minWidth, minHeight, width, height);
+                    minWidth, minHeight, width, height,
+                    availableWidth, availableHeight);
             created = true;
         }
 
-        DeviceProfile grid = mDynamicGrid.getDeviceProfile();
-        if (created) {
-            LauncherModel.updateWorkspaceLayoutCells((int) grid.numColumns, (int) grid.numRows);
-        }
         // Update the icon size
+        DeviceProfile grid = mDynamicGrid.getDeviceProfile();
         Utilities.setIconSize(grid.iconSizePx);
-        grid.updateFromConfiguration(context.getResources(), width, height);
+        grid.updateFromConfiguration(context.getResources(), width, height,
+                availableWidth, availableHeight);
         return grid;
     }
     DynamicGrid getDynamicGrid() {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index d80c2ac..8676b09 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -143,9 +143,6 @@
     private IconCache mIconCache;
     private Bitmap mDefaultIcon;
 
-    private static int mCellCountX;
-    private static int mCellCountY;
-
     protected int mPreviousConfigMcc;
 
     public interface Callbacks {
@@ -219,8 +216,10 @@
 
     static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> items, int[] xy,
                                  long screen) {
-        final int xCount = LauncherModel.getCellCountX();
-        final int yCount = LauncherModel.getCellCountY();
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        final int xCount = (int) grid.numColumns;
+        final int yCount = (int) grid.numRows;
         boolean[][] occupied = new boolean[xCount][yCount];
 
         int cellX, cellY, spanX, spanY;
@@ -923,23 +922,6 @@
                 | ((int) screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
     }
 
-    static int getCellCountX() {
-        return mCellCountX;
-    }
-
-    static int getCellCountY() {
-        return mCellCountY;
-    }
-
-    /**
-     * Updates the model orientation helper to take into account the current layout dimensions
-     * when performing local/canonical coordinate transformations.
-     */
-    static void updateWorkspaceLayoutCells(int shortAxisCellCount, int longAxisCellCount) {
-        mCellCountX = shortAxisCellCount;
-        mCellCountY = longAxisCellCount;
-    }
-
     /**
      * Removes the specified item from the database
      * @param context
@@ -1558,12 +1540,19 @@
         }
 
         private boolean checkItemDimensions(ItemInfo info) {
-            return (info.cellX + info.spanX) > mCellCountX ||
-                    (info.cellY + info.spanY) > mCellCountY;
+            LauncherAppState app = LauncherAppState.getInstance();
+            DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+            return (info.cellX + info.spanX) > (int) grid.numColumns ||
+                    (info.cellY + info.spanY) > (int) grid.numRows;
         }
 
         // check & update map of what's occupied; used to discard overlapping/invalid items
         private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item) {
+            LauncherAppState app = LauncherAppState.getInstance();
+            DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+            int countX = (int) grid.numColumns;
+            int countY = (int) grid.numRows;
+
             long containerIndex = item.screenId;
             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
                 if (occupied.containsKey(LauncherSettings.Favorites.CONTAINER_HOTSEAT)) {
@@ -1577,7 +1566,7 @@
                             return false;
                     }
                 } else {
-                    ItemInfo[][] items = new ItemInfo[mCellCountX + 1][mCellCountY + 1];
+                    ItemInfo[][] items = new ItemInfo[countX + 1][countY + 1];
                     items[(int) item.screenId][0] = item;
                     occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, items);
                     return true;
@@ -1588,7 +1577,7 @@
             }
 
             if (!occupied.containsKey(item.screenId)) {
-                ItemInfo[][] items = new ItemInfo[mCellCountX + 1][mCellCountY + 1];
+                ItemInfo[][] items = new ItemInfo[countX + 1][countY + 1];
                 occupied.put(item.screenId, items);
             }
 
@@ -1625,6 +1614,11 @@
             final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
             final boolean isSafeMode = manager.isSafeMode();
 
+            LauncherAppState app = LauncherAppState.getInstance();
+            DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+            int countX = (int) grid.numColumns;
+            int countY = (int) grid.numRows;
+
             // Make sure the default workspace is loaded, if needed
             mApp.getLauncherProvider().loadDefaultFavoritesIfNecessary(0);
 
@@ -1930,7 +1924,6 @@
                     for (ItemInfo item: sBgItemsIdMap.values()) {
                         maxItemId = Math.max(maxItemId, item.id);
                     }
-                    LauncherAppState app = LauncherAppState.getInstance();
                     app.getLauncherProvider().updateMaxItemId(maxItemId);
                 } else {
                     Log.w(TAG, "10249126 - loadWorkspace - !loadedOldDb");
@@ -1963,7 +1956,7 @@
                     Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
                     Log.d(TAG, "workspace layout: ");
                     int nScreens = occupied.size();
-                    for (int y = 0; y < mCellCountY; y++) {
+                    for (int y = 0; y < countY; y++) {
                         String line = "";
 
                         Iterator<Long> iter = occupied.keySet().iterator();
@@ -1972,7 +1965,7 @@
                             if (screenId > 0) {
                                 line += " | ";
                             }
-                            for (int x = 0; x < mCellCountX; x++) {
+                            for (int x = 0; x < countX; x++) {
                                 line += ((occupied.get(screenId)[x][y] != null) ? "#" : ".");
                             }
                         }
@@ -2086,12 +2079,14 @@
         /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to
          * right) */
         private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) {
+            final LauncherAppState app = LauncherAppState.getInstance();
+            final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
             // XXX: review this
             Collections.sort(workspaceItems, new Comparator<ItemInfo>() {
                 @Override
                 public int compare(ItemInfo lhs, ItemInfo rhs) {
-                    int cellCountX = LauncherModel.getCellCountX();
-                    int cellCountY = LauncherModel.getCellCountY();
+                    int cellCountX = (int) grid.numColumns;
+                    int cellCountY = (int) grid.numRows;
                     int screenOffset = cellCountX * cellCountY;
                     int containerOffset = screenOffset * (Launcher.SCREEN_COUNT + 1); // +1 hotseat
                     long lr = (lhs.container * containerOffset + lhs.screenId * screenOffset +
diff --git a/src/com/android/launcher3/PagedViewCellLayout.java b/src/com/android/launcher3/PagedViewCellLayout.java
index 38fd1ed..51699e9 100644
--- a/src/com/android/launcher3/PagedViewCellLayout.java
+++ b/src/com/android/launcher3/PagedViewCellLayout.java
@@ -64,8 +64,8 @@
         Resources resources = context.getResources();
         mOriginalCellWidth = mCellWidth = grid.cellWidthPx;
         mOriginalCellHeight = mCellHeight = grid.cellHeightPx;
-        mCellCountX = LauncherModel.getCellCountX();
-        mCellCountY = LauncherModel.getCellCountY();
+        mCellCountX = (int) grid.numColumns;
+        mCellCountY = (int) grid.numRows;
         mOriginalWidthGap = mOriginalHeightGap = mWidthGap = mHeightGap = -1;
         mMaxGap = resources.getDimensionPixelSize(R.dimen.apps_customize_max_gap);
 
diff --git a/src/com/android/launcher3/PagedViewWidget.java b/src/com/android/launcher3/PagedViewWidget.java
index bd40c5c..220a9f7 100644
--- a/src/com/android/launcher3/PagedViewWidget.java
+++ b/src/com/android/launcher3/PagedViewWidget.java
@@ -106,6 +106,9 @@
 
     public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info,
             int maxWidth, int[] cellSpan, WidgetPreviewLoader loader) {
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+
         mIsAppWidget = true;
         mInfo = info;
         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
@@ -116,8 +119,8 @@
         name.setText(info.label);
         final TextView dims = (TextView) findViewById(R.id.widget_dims);
         if (dims != null) {
-            int hSpan = Math.min(cellSpan[0], LauncherModel.getCellCountX());
-            int vSpan = Math.min(cellSpan[1], LauncherModel.getCellCountY());
+            int hSpan = Math.min(cellSpan[0], (int) grid.numColumns);
+            int vSpan = Math.min(cellSpan[1], (int) grid.numRows);
             dims.setText(String.format(mDimensionsFormatString, hSpan, vSpan));
         }
         mWidgetPreviewLoader = loader;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2298c53..ba18b8d 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2580,6 +2580,8 @@
         Point smallestSize = new Point();
         Point largestSize = new Point();
         display.getCurrentSizeRange(smallestSize, largestSize);
+        int countX = (int) grid.numColumns;
+        int countY = (int) grid.numRows;
         if (orientation == CellLayout.LANDSCAPE) {
             if (mLandscapeCellLayoutMetrics == null) {
                 Rect padding = grid.getWorkspacePadding(CellLayout.LANDSCAPE);
@@ -2587,7 +2589,7 @@
                 int height = smallestSize.y - padding.top - padding.bottom;
                 mLandscapeCellLayoutMetrics = new Rect();
                 CellLayout.getMetrics(mLandscapeCellLayoutMetrics, width, height,
-                        LauncherModel.getCellCountX(), LauncherModel.getCellCountY());
+                        countX, countY);
             }
             return mLandscapeCellLayoutMetrics;
         } else if (orientation == CellLayout.PORTRAIT) {
@@ -2597,7 +2599,7 @@
                 int height = largestSize.y - padding.top - padding.bottom;
                 mPortraitCellLayoutMetrics = new Rect();
                 CellLayout.getMetrics(mPortraitCellLayoutMetrics, width, height,
-                        LauncherModel.getCellCountX(), LauncherModel.getCellCountY());
+                        countX, countY);
             }
             return mPortraitCellLayoutMetrics;
         }