Merge "Import translations. DO NOT MERGE"
diff --git a/res/layout-port/search_bar.xml b/res/layout-port/search_bar.xml
index e51c3a8..7cf79b8 100644
--- a/res/layout-port/search_bar.xml
+++ b/res/layout-port/search_bar.xml
@@ -53,7 +53,7 @@
         android:layout_width="@dimen/search_bar_height"
         android:layout_height="match_parent"
         android:layout_gravity="center_vertical"
-        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"
         android:layout_alignParentTop="true"
         android:paddingEnd="8dp"
         android:gravity="end"
diff --git a/res/layout-sw720dp/search_bar.xml b/res/layout-sw720dp/search_bar.xml
index e51c3a8..7cf79b8 100644
--- a/res/layout-sw720dp/search_bar.xml
+++ b/res/layout-sw720dp/search_bar.xml
@@ -53,7 +53,7 @@
         android:layout_width="@dimen/search_bar_height"
         android:layout_height="match_parent"
         android:layout_gravity="center_vertical"
-        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"
         android:layout_alignParentTop="true"
         android:paddingEnd="8dp"
         android:gravity="end"
diff --git a/res/layout/drop_target_bar.xml b/res/layout/drop_target_bar.xml
index 5fcddc9..ca3f554 100644
--- a/res/layout/drop_target_bar.xml
+++ b/res/layout/drop_target_bar.xml
@@ -23,7 +23,7 @@
             style="@style/DropTargetButton"
             android:id="@+id/delete_target_text"
             android:text="@string/delete_zone_label_workspace"
-            android:drawableLeft="@drawable/remove_target_selector" />
+            android:drawableStart="@drawable/remove_target_selector" />
     </FrameLayout>
     <FrameLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
@@ -34,6 +34,6 @@
             style="@style/DropTargetButton"
             android:id="@+id/info_target_text"
             android:text="@string/info_target_label"
-            android:drawableLeft="@drawable/info_target_selector" />
+            android:drawableStart="@drawable/info_target_selector" />
     </FrameLayout>
 </merge>
\ No newline at end of file
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 121afb0..ed834b9 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -90,7 +90,7 @@
         if (generatedImages != null) {
             if (cancelled) {
                 for (int i = 0; i < generatedImages.size(); i++) {
-                    widgetPreviewLoader.releaseBitmap(items.get(i), generatedImages.get(i));
+                    widgetPreviewLoader.recycleBitmap(items.get(i), generatedImages.get(i));
                 }
             }
             generatedImages.clear();
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 5eb8483..27ceaba 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -264,15 +264,19 @@
                 // Animate the transition
                 ObjectAnimator outAnim = LauncherAnimUtils.ofFloat(mAnimationBuffer, "alpha", 0f);
                 outAnim.addListener(new AnimatorListenerAdapter() {
+                    private void clearAnimationBuffer() {
+                        mAnimationBuffer.setVisibility(View.GONE);
+                        PagedViewWidget.setRecyclePreviewsWhenDetachedFromWindow(false);
+                        mAnimationBuffer.removeAllViews();
+                        PagedViewWidget.setRecyclePreviewsWhenDetachedFromWindow(true);
+                    }
                     @Override
                     public void onAnimationEnd(Animator animation) {
-                        mAnimationBuffer.setVisibility(View.GONE);
-                        mAnimationBuffer.removeAllViews();
+                        clearAnimationBuffer();
                     }
                     @Override
                     public void onAnimationCancel(Animator animation) {
-                        mAnimationBuffer.setVisibility(View.GONE);
-                        mAnimationBuffer.removeAllViews();
+                        clearAnimationBuffer();
                     }
                 });
                 ObjectAnimator inAnim = LauncherAnimUtils.ofFloat(mAppsCustomizePane, "alpha", 1f);
diff --git a/src/com/android/launcher2/ButtonDropTarget.java b/src/com/android/launcher2/ButtonDropTarget.java
index 1c9fa5f..ff0813a 100644
--- a/src/com/android/launcher2/ButtonDropTarget.java
+++ b/src/com/android/launcher2/ButtonDropTarget.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.view.View;
 import android.widget.TextView;
 
 import com.android.launcher.R;
@@ -70,7 +71,7 @@
     }
 
     protected Drawable getCurrentDrawable() {
-        Drawable[] drawables = getCompoundDrawables();
+        Drawable[] drawables = getCompoundDrawablesRelative();
         for (int i = 0; i < drawables.length; ++i) {
             if (drawables[i] != null) {
                 return drawables[i];
@@ -116,21 +117,39 @@
         outRect.bottom += mBottomDragPadding;
     }
 
-    Rect getIconRect(int itemWidth, int itemHeight, int drawableWidth, int drawableHeight) {
+    private boolean isRtl() {
+        return (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
+    }
+
+    Rect getIconRect(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight) {
         DragLayer dragLayer = mLauncher.getDragLayer();
 
         // Find the rect to animate to (the view is center aligned)
         Rect to = new Rect();
         dragLayer.getViewRectRelativeToSelf(this, to);
-        int width = drawableWidth;
-        int height = drawableHeight;
-        int left = to.left + getPaddingLeft();
-        int top = to.top + (getMeasuredHeight() - height) / 2;
-        to.set(left, top, left + width, top + height);
+
+        final int width = drawableWidth;
+        final int height = drawableHeight;
+
+        final int left;
+        final int right;
+
+        if (isRtl()) {
+            right = to.right - getPaddingRight();
+            left = right - width;
+        } else {
+            left = to.left + getPaddingLeft();
+            right = left + width;
+        }
+
+        final int top = to.top + (getMeasuredHeight() - height) / 2;
+        final int bottom = top +  height;
+
+        to.set(left, top, right, bottom);
 
         // Center the destination rect about the trash icon
-        int xOffset = (int) -(itemWidth - width) / 2;
-        int yOffset = (int) -(itemHeight - height) / 2;
+        final int xOffset = (int) -(viewWidth - width) / 2;
+        final int yOffset = (int) -(viewHeight - height) / 2;
         to.offset(xOffset, yOffset);
 
         return to;
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 39a0b09..d575b8f 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -154,9 +154,9 @@
         }
 
         if (isUninstall) {
-            setCompoundDrawablesWithIntrinsicBounds(mUninstallDrawable, null, null, null);
+            setCompoundDrawablesRelativeWithIntrinsicBounds(mUninstallDrawable, null, null, null);
         } else {
-            setCompoundDrawablesWithIntrinsicBounds(mRemoveDrawable, null, null, null);
+            setCompoundDrawablesRelativeWithIntrinsicBounds(mRemoveDrawable, null, null, null);
         }
         mCurrentDrawable = (TransitionDrawable) getCurrentDrawable();
 
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index aece398..bb5827a 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -38,6 +38,7 @@
     static final String TAG = "PagedViewWidgetLayout";
 
     private static boolean sDeletePreviewsWhenDetachedFromWindow = true;
+    private static boolean sRecyclePreviewsWhenDetachedFromWindow = true;
 
     private String mDimensionsFormatString;
     CheckForShortPress mPendingCheckForShortPress = null;
@@ -82,6 +83,10 @@
         sDeletePreviewsWhenDetachedFromWindow = value;
     }
 
+    public static void setRecyclePreviewsWhenDetachedFromWindow(boolean value) {
+        sRecyclePreviewsWhenDetachedFromWindow = value;
+    }
+
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
@@ -90,8 +95,9 @@
             final ImageView image = (ImageView) findViewById(R.id.widget_preview);
             if (image != null) {
                 FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable();
-                if (mInfo != null && preview != null && preview.getBitmap() != null) {
-                    mWidgetPreviewLoader.releaseBitmap(mInfo, preview.getBitmap());
+                if (sRecyclePreviewsWhenDetachedFromWindow &&
+                        mInfo != null && preview != null && preview.getBitmap() != null) {
+                    mWidgetPreviewLoader.recycleBitmap(mInfo, preview.getBitmap());
                 }
                 image.setImageDrawable(null);
             }
diff --git a/src/com/android/launcher2/WidgetPreviewLoader.java b/src/com/android/launcher2/WidgetPreviewLoader.java
index a9bc098..7c72701 100644
--- a/src/com/android/launcher2/WidgetPreviewLoader.java
+++ b/src/com/android/launcher2/WidgetPreviewLoader.java
@@ -234,15 +234,14 @@
         }
     }
 
-    public void releaseBitmap(Object o, Bitmap bitmapToFree) {
-        // enable this code when doDecode doesn't force Bitmaps to become immutable
+    public void recycleBitmap(Object o, Bitmap bitmapToRecycle) {
         String name = getObjectName(o);
         synchronized(mLoadedPreviews) {
             synchronized(mUnusedBitmaps) {
                 Bitmap b = mLoadedPreviews.get(name).get();
-                if (b == bitmapToFree) {
+                if (b == bitmapToRecycle) {
                     mLoadedPreviews.remove(name);
-                    if (bitmapToFree.isMutable()) {
+                    if (bitmapToRecycle.isMutable()) {
                         mUnusedBitmaps.add(new SoftReference<Bitmap>(b));
                     }
                 } else {
@@ -269,7 +268,7 @@
 
         @Override
         public void onCreate(SQLiteDatabase database) {
-            database.execSQL("CREATE TABLE " + TABLE_NAME + " (" +
+            database.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
                     COLUMN_NAME + " TEXT NOT NULL, " +
                     COLUMN_SIZE + " TEXT NOT NULL, " +
                     COLUMN_PREVIEW_BITMAP + " BLOB NOT NULL, " +