Merge "Fixing crash and updating default layout"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index eab4044..5289ebd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -37,7 +37,7 @@
 
 <!-- AllApps/Customize/AppsCustomize -->
     <dimen name="apps_customize_tab_bar_height">56dp</dimen>
-    <dimen name="app_icon_size">56dp</dimen>
+    <dimen name="app_icon_size">48dp</dimen>
     <!-- The width can be 72dp because we don't have L/R padding -->
     <dimen name="apps_customize_cell_width">72dp</dimen>
     <dimen name="apps_customize_cell_height">80dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 95d35d0..3928fa4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -45,8 +45,8 @@
     <string name="widgets_tab_label">Widgets</string>
 
     <!-- AppsCustomize pane -->
-    <!-- Message to tell the user to long-press on a widget to add it [CHAR_LIMIT=50] -->
-    <string name="long_press_widget_to_add">Long-press to pick up a widget</string>
+    <!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
+    <string name="long_press_widget_to_add">Touch &amp; hold to pick up a widget</string>
     <!-- Market button text.  The market button text is removed in Launcher.java 
          in the Phone UI. [CHAR LIMIT=32] -->
     <string name="market">Shop</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 15ca427..be9b0fd 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -39,18 +39,18 @@
     </style>
 
     <style name="WorkspaceIcon.Portrait">
-        <item name="android:drawablePadding">4dp</item>
+        <item name="android:drawablePadding">8dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
-        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingTop">8dp</item>
         <item name="android:paddingBottom">4dp</item>
     </style>
 
     <style name="WorkspaceIcon.Landscape">
-        <item name="android:drawablePadding">0dp</item>
+        <item name="android:drawablePadding">4dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
-        <item name="android:paddingTop">2dp</item>
+        <item name="android:paddingTop">6dp</item>
         <item name="android:paddingBottom">4dp</item>
     </style>
 
@@ -66,18 +66,18 @@
 
     <style name="WorkspaceIcon.Portrait.AppsCustomize">
         <item name="android:background">@null</item>
-        <item name="android:paddingTop">0dp</item>
+        <item name="android:paddingTop">4dp</item>
         <item name="android:paddingBottom">0dp</item>
         <item name="android:paddingLeft">0dp</item>
         <item name="android:paddingRight">0dp</item>
-        <item name="android:drawablePadding">4dp</item>
+        <item name="android:drawablePadding">8dp</item>
         <item name="android:includeFontPadding">false</item>
     </style>
     <style name="WorkspaceIcon.Landscape.AppsCustomize">
         <item name="android:background">@null</item>
-        <item name="android:paddingTop">0dp</item>
+        <item name="android:paddingTop">4dp</item>
         <item name="android:paddingBottom">0dp</item>
-        <item name="android:drawablePadding">2dp</item>
+        <item name="android:drawablePadding">6dp</item>
         <item name="android:includeFontPadding">false</item>
     </style>
 
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 641e0f7..15a0642 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -292,13 +292,6 @@
         return mInfo;
     }
 
-    void onOpen() {
-        // When the folder opens, we need to refresh the GridView's selection by
-        // forcing a layout
-        // TODO: find out if this is still necessary
-        mContent.requestLayout();
-    }
-
     void bind(FolderInfo info) {
         mInfo = info;
         ArrayList<ShortcutInfo> children = info.contents;
@@ -849,7 +842,8 @@
 
     private void onCloseComplete() {
         DragLayer parent = (DragLayer) getParent();
-        parent.removeView(Folder.this);
+        parent.removeView(this);
+        mDragController.removeDropTarget((DropTarget) this);
         clearFocus();
 
         if (mRearrangeOnClose) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 1fa3210..bb7bdf5 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1464,25 +1464,6 @@
         }
     }
 
-    public void closeFolder() {
-        Folder folder = mWorkspace.getOpenFolder();
-        if (folder != null) {
-            closeFolder(folder);
-        }
-    }
-
-    void closeFolder(Folder folder) {
-        folder.getInfo().opened = false;
-
-        ViewGroup parent = (ViewGroup) folder.getParent().getParent();
-        if (parent != null) {
-            FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);
-            shrinkAndFadeInFolderIcon(fi);
-            mDragController.removeDropTarget((DropTarget)folder);
-        }
-        folder.animateClosed();
-    }
-
     /**
      * Re-listen when widgets are reset.
      */
@@ -1728,11 +1709,34 @@
         growAndFadeOutFolderIcon(folderIcon);
         info.opened = true;
 
-        mDragLayer.addView(folder);
-        mDragController.addDropTarget((DropTarget) folder);
-
+        // Just verify that the folder hasn't already been added to the DragLayer.
+        // There was a one-off crash where the folder had a parent already.
+        if (folder.getParent() == null) {
+            mDragLayer.addView(folder);
+            mDragController.addDropTarget((DropTarget) folder);
+        } else {
+            Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +
+                    folder.getParent() + ").");
+        }
         folder.animateOpen();
-        folder.onOpen();
+    }
+
+    public void closeFolder() {
+        Folder folder = mWorkspace.getOpenFolder();
+        if (folder != null) {
+            closeFolder(folder);
+        }
+    }
+
+    void closeFolder(Folder folder) {
+        folder.getInfo().opened = false;
+
+        ViewGroup parent = (ViewGroup) folder.getParent().getParent();
+        if (parent != null) {
+            FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);
+            shrinkAndFadeInFolderIcon(fi);
+        }
+        folder.animateClosed();
     }
 
     public boolean onLongClick(View v) {
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 63e8077..1573483 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1511,7 +1511,7 @@
         // the db
         if (icon == null) {
             if (c != null) {
-                icon = getIconFromCursor(c, iconIndex);
+                icon = getIconFromCursor(c, iconIndex, context);
             }
         }
         // the fallback icon
@@ -1581,7 +1581,7 @@
             }
             // the db
             if (icon == null) {
-                icon = getIconFromCursor(c, iconIndex);
+                icon = getIconFromCursor(c, iconIndex, context);
             }
             // the fallback icon
             if (icon == null) {
@@ -1590,7 +1590,7 @@
             }
             break;
         case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
-            icon = getIconFromCursor(c, iconIndex);
+            icon = getIconFromCursor(c, iconIndex, context);
             if (icon == null) {
                 icon = getFallbackIcon();
                 info.customIcon = false;
@@ -1609,14 +1609,15 @@
         return info;
     }
 
-    Bitmap getIconFromCursor(Cursor c, int iconIndex) {
+    Bitmap getIconFromCursor(Cursor c, int iconIndex, Context context) {
         if (false) {
             Log.d(TAG, "getIconFromCursor app="
                     + c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE)));
         }
         byte[] data = c.getBlob(iconIndex);
         try {
-            return BitmapFactory.decodeByteArray(data, 0, data.length);
+            return Utilities.createIconBitmap(
+                    BitmapFactory.decodeByteArray(data, 0, data.length), context);
         } catch (Exception e) {
             return null;
         }
diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java
index c63c822..b537f7a 100644
--- a/src/com/android/launcher2/Utilities.java
+++ b/src/com/android/launcher2/Utilities.java
@@ -76,8 +76,32 @@
     }
 
     /**
-     * Returns a bitmap suitable for the all apps view.  The bitmap will be a power
-     * of two sized ARGB_8888 bitmap that can be used as a gl texture.
+     * Returns a bitmap suitable for the all apps view. Used to convert pre-ICS
+     * icon bitmaps that are stored in the database (which were 74x74 pixels at hdpi size)
+     * to the proper size (48dp)
+     */
+    static Bitmap createIconBitmap(Bitmap icon, Context context) {
+        int textureWidth = sIconTextureWidth;
+        int textureHeight = sIconTextureHeight;
+        int sourceWidth = icon.getWidth();
+        int sourceHeight = icon.getHeight();
+        if (sourceWidth > textureWidth && sourceHeight > textureHeight) {
+            // Icon is bigger than it should be; clip it (solves the GB->ICS migration case)
+            return Bitmap.createBitmap(icon,
+                    (sourceWidth - textureWidth) / 2,
+                    (sourceHeight - textureHeight) / 2,
+                    textureWidth, textureHeight);
+        } else if (sourceWidth == textureWidth && sourceHeight == textureHeight) {
+            // Icon is the right size, no need to change it
+            return icon;
+        } else {
+            // Icon is too small, render to a larger bitmap
+            return createIconBitmap(new BitmapDrawable(icon), context);
+        }
+    }
+
+    /**
+     * Returns a bitmap suitable for the all apps view.
      */
     static Bitmap createIconBitmap(Drawable icon, Context context) {
         synchronized (sCanvas) { // we share the statics :-(
@@ -103,7 +127,7 @@
             int sourceWidth = icon.getIntrinsicWidth();
             int sourceHeight = icon.getIntrinsicHeight();
 
-            if (sourceWidth > 0 && sourceWidth > 0) {
+            if (sourceWidth > 0 && sourceHeight > 0) {
                 // There are intrinsic sizes.
                 if (width < sourceWidth || height < sourceHeight) {
                     // It's too big, scale it down.