Merge "7225161 Launcher needs to add android:supportsRtl="true" in his AndroidManifest" into jb-mr1-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 971efe6..3c3897e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -86,7 +86,7 @@
 
         <activity
             android:name="com.android.launcher2.WallpaperChooser"
-            style="@style/Theme.WallpaperPicker"
+            android:theme="@style/Theme.WallpaperPicker"
             android:label="@string/pick_wallpaper"
             android:icon="@drawable/ic_launcher_wallpaper"
             android:finishOnCloseSystemDialogs="true"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index fed4194..0960269 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -18,8 +18,7 @@
 -->
 
 <resources>
-    <style name="Theme.WallpaperPicker">
-        <item name="android:screenOrientation">nosensor</item>
+    <style name="Theme.WallpaperPicker" parent="@android:style/Theme.Holo.NoActionBar">
     </style>
 
     <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index f519329..817eb41 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -372,14 +372,6 @@
         setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f);
     }
 
-    @Override
-    protected void onUnhandledTap(MotionEvent ev) {
-        if (LauncherApplication.isScreenLarge()) {
-            // Dismiss AppsCustomize if we tap
-            mLauncher.showWorkspace(true);
-        }
-    }
-
     /** Returns the item index of the center item on this page so that we can restore to this
      *  item index when we rotate. */
     private int getMiddleComponentIndexOnCurrentPage() {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 7c52ae6..4ae9c7d 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1651,7 +1651,6 @@
     public boolean onSearchRequested() {
         startSearch(null, false, null, true);
         // Use a custom animation for launching search
-        overridePendingTransition(R.anim.fade_in_fast, R.anim.fade_out_fast);
         return true;
     }
 
@@ -1964,7 +1963,6 @@
                 intent.setPackage(activityName.getPackageName());
             }
             startActivity(null, intent, "onClickVoiceButton");
-            overridePendingTransition(R.anim.fade_in_fast, R.anim.fade_out_fast);
         } catch (ActivityNotFoundException e) {
             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -2509,7 +2507,7 @@
                     dispatchOnLauncherTransitionEnd(fromView, animated, false);
                     dispatchOnLauncherTransitionEnd(toView, animated, false);
 
-                    if (!springLoaded && !LauncherApplication.isScreenLarge()) {
+                    if (mWorkspace != null && !springLoaded && !LauncherApplication.isScreenLarge()) {
                         // Hide the workspace scrollbar
                         mWorkspace.hideScrollingIndicator(true);
                         hideDockDivider();
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 11beda8..86a9a84 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -262,28 +262,59 @@
         }
     }
 
+    static void checkItemInfoLocked(
+            final long itemId, final ItemInfo item, StackTraceElement[] stackTrace) {
+        ItemInfo modelItem = sBgItemsIdMap.get(itemId);
+        if (modelItem != null && item != modelItem) {
+            // check all the data is consistent
+            if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) {
+                ShortcutInfo modelShortcut = (ShortcutInfo) modelItem;
+                ShortcutInfo shortcut = (ShortcutInfo) item;
+                if (modelShortcut.title.toString().equals(shortcut.title.toString()) &&
+                        modelShortcut.intent.filterEquals(shortcut.intent) &&
+                        modelShortcut.id == shortcut.id &&
+                        modelShortcut.itemType == shortcut.itemType &&
+                        modelShortcut.container == shortcut.container &&
+                        modelShortcut.screen == shortcut.screen &&
+                        modelShortcut.cellX == shortcut.cellX &&
+                        modelShortcut.cellY == shortcut.cellY &&
+                        modelShortcut.spanX == shortcut.spanX &&
+                        modelShortcut.spanY == shortcut.spanY &&
+                        ((modelShortcut.dropPos == null && shortcut.dropPos == null) ||
+                        (modelShortcut.dropPos != null &&
+                                shortcut.dropPos != null &&
+                                modelShortcut.dropPos[0] == shortcut.dropPos[0] &&
+                        modelShortcut.dropPos[1] == shortcut.dropPos[1]))) {
+                    // For all intents and purposes, this is the same object
+                    return;
+                }
+            }
+
+            // the modelItem needs to match up perfectly with item if our model is
+            // to be consistent with the database-- for now, just require
+            // modelItem == item or the equality check above
+            String msg = "item: " + ((item != null) ? item.toString() : "null") +
+                    "modelItem: " +
+                    ((modelItem != null) ? modelItem.toString() : "null") +
+                    "Error: ItemInfo passed to checkItemInfo doesn't match original";
+            RuntimeException e = new RuntimeException(msg);
+            if (stackTrace != null) {
+                e.setStackTrace(stackTrace);
+            }
+            throw e;
+        }
+    }
+
     static void checkItemInfo(final ItemInfo item) {
         final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
         final long itemId = item.id;
         Runnable r = new Runnable() {
-                public void run() {
-                    synchronized (sBgLock) {
-                        ItemInfo modelItem = sBgItemsIdMap.get(itemId);
-                        if (modelItem != null && item != modelItem) {
-                            // the modelItem needs to match up perfectly with item if our model is
-                            // to be consistent with the database-- for now, just require
-                            // modelItem == item
-                            String msg = "item: " + ((item != null) ? item.toString() : "null") +
-                                "modelItem: " +
-                                    ((modelItem != null) ? modelItem.toString() : "null") +
-                                "Error: ItemInfo passed to checkItemInfo doesn't match original";
-                            RuntimeException e = new RuntimeException(msg);
-                            e.setStackTrace(stackTrace);
-                            throw e;
-                        }
-                    }
+            public void run() {
+                synchronized (sBgLock) {
+                    checkItemInfoLocked(itemId, item, stackTrace);
                 }
-            };
+            }
+        };
         runOnWorkerThread(r);
     }
 
@@ -300,16 +331,7 @@
 
                 // Lock on mBgLock *after* the db operation
                 synchronized (sBgLock) {
-                    ItemInfo modelItem = sBgItemsIdMap.get(itemId);
-                    if (item != modelItem) {
-                        // the modelItem needs to match up perfectly with item if our model is to be
-                        // consistent with the database-- for now, just require modelItem == item
-                        String msg = "item: " + ((item != null) ? item.toString() : "null") +
-                            "modelItem: " + ((modelItem != null) ? modelItem.toString() : "null") +
-                            "Error: ItemInfo passed to " + callingFunction + " doesn't match " +
-                            "original";
-                        throw new RuntimeException(msg);
-                    }
+                    checkItemInfoLocked(itemId, item, stackTrace);
 
                     if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP &&
                             item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
@@ -329,6 +351,7 @@
                     // Items are added/removed from the corresponding FolderInfo elsewhere, such
                     // as in Workspace.onDrop. Here, we just add/remove them from the list of items
                     // that are on the desktop, as appropriate
+                    ItemInfo modelItem = sBgItemsIdMap.get(itemId);
                     if (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP ||
                             modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
                         switch (modelItem.itemType) {
@@ -572,11 +595,7 @@
 
                 // Lock on mBgLock *after* the db operation
                 synchronized (sBgLock) {
-                    if (sBgItemsIdMap.containsKey(item.id)) {
-                        // we should not be adding new items in the db with the same id
-                        throw new RuntimeException("Error: ItemInfo id (" + item.id + ") passed to " +
-                            "addItemToDatabase already exists." + item.toString());
-                    }
+                    checkItemInfoLocked(item.id, item, null);
                     sBgItemsIdMap.put(item.id, item);
                     switch (item.itemType) {
                         case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: