Merge "Import translations. DO NOT MERGE" into jb-ub-now-jetsonic
diff --git a/res/layout/all_apps_button.xml b/res/layout/all_apps_button.xml
new file mode 100644
index 0000000..1b9ea08
--- /dev/null
+++ b/res/layout/all_apps_button.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+   style="@style/WorkspaceIcon"
+   android:focusable="true"
+   android:background="@drawable/focusable_view_bg" />
diff --git a/res/values/config.xml b/res/values/config.xml
index 97408cc..8718f15 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -12,7 +12,7 @@
 
 <!-- AllApps/Customize/AppsCustomize -->
     <!-- The alpha of the AppsCustomize bg in spring loaded mode -->
-    <integer name="config_appsCustomizeSpringLoadedBgAlpha">45</integer>
+    <integer name="config_appsCustomizeSpringLoadedBgAlpha">65</integer>
     <integer name="config_workspaceUnshrinkTime">300</integer>
     <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
     <integer name="config_workspaceSpringLoadShrinkPercentage">80</integer>
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index fbbb09f..986a89b 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -28,6 +28,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.FrameLayout;
+import android.widget.TextView;
 
 import java.util.ArrayList;
 
@@ -126,27 +127,17 @@
             // Add the Apps button
             Context context = getContext();
 
-            Drawable rawIcon =
-                    context.getResources().getDrawable(R.drawable.all_apps_button_icon);
-            Bitmap icon = Utilities.createIconBitmap(rawIcon, context);
-
             LayoutInflater inflater = LayoutInflater.from(context);
-            BubbleTextView allAppsButton = (BubbleTextView)
-                    inflater.inflate(R.layout.application, mContent, false);
-            allAppsButton.setCompoundDrawablesWithIntrinsicBounds(null,
-                    new FastBitmapDrawable(icon), null, null);
-            allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
-            allAppsButton.setOnTouchListener(new View.OnTouchListener() {
-                @Override
-                public boolean onTouch(View v, MotionEvent event) {
-                    if (mLauncher != null &&
-                            (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
-                        mLauncher.onTouchDownAllAppsButton(v);
-                    }
-                    return false;
-                }
-            });
+            TextView allAppsButton = (TextView)
+                    inflater.inflate(R.layout.all_apps_button, mContent, false);
+            Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
+            d.setBounds(0, 0, Utilities.sIconTextureWidth, Utilities.sIconTextureHeight);
+            allAppsButton.setCompoundDrawables(null, d, null, null);
 
+            allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
+            if (mLauncher != null) {
+                allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
+            }
             allAppsButton.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(android.view.View v) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ba34c13..7ae429d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -281,7 +281,7 @@
 
     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();
 
-    private Intent mAppMarketIntent = null;
+    private View.OnTouchListener mHapticFeedbackTouchListener;
 
     // Related to the auto-advancing of widgets
     private final int ADVANCE_MSG = 1;
@@ -301,6 +301,9 @@
     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
     private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2];
 
+    private Intent mAppMarketIntent = null;
+    private static final boolean DISABLE_MARKET_BUTTON = true;
+
     private Drawable mWorkspaceBackgroundDrawable;
 
     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
@@ -513,7 +516,9 @@
         int coi = getCurrentOrientationIndexForGlobalIcons();
         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null ||
                 sAppMarketIcon[coi] == null) {
-            updateAppMarketIcon();
+            if (!DISABLE_MARKET_BUTTON) {
+                updateAppMarketIcon();
+            }
             searchVisible = updateGlobalSearchIcon();
             voiceVisible = updateVoiceSearchIcon(searchVisible);
         }
@@ -525,7 +530,7 @@
             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);
             voiceVisible = true;
         }
-        if (sAppMarketIcon[coi] != null) {
+        if (!DISABLE_MARKET_BUTTON && sAppMarketIcon[coi] != null) {
             updateAppMarketIcon(sAppMarketIcon[coi]);
         }
         if (mSearchDropTargetBar != null) {
@@ -895,6 +900,9 @@
         // Process any items that were added while Launcher was away.
         InstallShortcutReceiver.disableAndFlushInstallQueue(this);
 
+        // Update the voice search button proxy
+        updateVoiceButtonProxyVisible(false);
+
         // Again, as with the above scenario, it's possible that one or more of the global icons
         // were updated in the wrong orientation.
         updateGlobalIcons();
@@ -1145,24 +1153,32 @@
         }
 
         mOverviewPanel = findViewById(R.id.overview_panel);
-        findViewById(R.id.widget_button).setOnClickListener(new OnClickListener() {
+        View widgetButton = findViewById(R.id.widget_button);
+        widgetButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
                 showAllApps(true, AppsCustomizePagedView.ContentType.Widgets);
             }
         });
-        findViewById(R.id.wallpaper_button).setOnClickListener(new OnClickListener() {
+        widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());
+
+        View wallpaperButton = findViewById(R.id.wallpaper_button);
+        wallpaperButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
                 startWallpaper();
             }
         });
-        findViewById(R.id.settings_button).setOnClickListener(new OnClickListener() {
+        wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
+
+        View settingsButton = findViewById(R.id.settings_button);
+        settingsButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
                 startSettings();
             }
         });
+        settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
         mOverviewPanel.setAlpha(0f);
 
         // Setup the workspace
@@ -1527,7 +1543,9 @@
             }
             // When Launcher comes back to foreground, a different Activity might be responsible for
             // the app market intent, so refresh the icon
-            updateAppMarketIcon();
+            if (!DISABLE_MARKET_BUTTON) {
+                updateAppMarketIcon();
+            }
             clearTypedText();
         }
     }
@@ -2269,11 +2287,33 @@
         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
     }
 
+    public void performHapticFeedbackOnTouchDown(View v) {
+        // Provide the same haptic feedback that the system offers for virtual keys.
+        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+    }
+
+    public View.OnTouchListener getHapticFeedbackTouchListener() {
+        if (mHapticFeedbackTouchListener == null) {
+            mHapticFeedbackTouchListener = new View.OnTouchListener() {
+                @Override
+                public boolean onTouch(View v, MotionEvent event) {
+                    if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
+                        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                    }
+                    return false;
+                }
+            };
+        }
+        return mHapticFeedbackTouchListener;
+    }
+
     public void onClickAppMarketButton(View v) {
-        if (mAppMarketIntent != null) {
-            startActivitySafely(v, mAppMarketIntent, "app market");
-        } else {
-            Log.e(TAG, "Invalid app market intent.");
+        if (!DISABLE_MARKET_BUTTON) {
+            if (mAppMarketIntent != null) {
+                startActivitySafely(v, mAppMarketIntent, "app market");
+            } else {
+                Log.e(TAG, "Invalid app market intent.");
+            }
         }
     }
 
@@ -3301,7 +3341,7 @@
             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
             if (searchButton != null) searchButton.setVisibility(View.GONE);
             if (voiceButton != null) voiceButton.setVisibility(View.GONE);
-            setVoiceButtonProxyVisible(false);
+            updateVoiceButtonProxyVisible(false);
             return false;
         }
     }
@@ -3348,13 +3388,13 @@
             }
             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);
             voiceButton.setVisibility(View.VISIBLE);
-            setVoiceButtonProxyVisible(true);
+            updateVoiceButtonProxyVisible(false);
             invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
             return true;
         } else {
             if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
             if (voiceButton != null) voiceButton.setVisibility(View.GONE);
-            setVoiceButtonProxyVisible(false);
+            updateVoiceButtonProxyVisible(false);
             return false;
         }
     }
@@ -3366,45 +3406,60 @@
         invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
     }
 
-    public void setVoiceButtonProxyVisible(boolean visible) {
+    public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {
         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);
         if (voiceButtonProxy != null) {
+            boolean visible = !forceDisableVoiceButtonProxy &&
+                    mWorkspace.shouldVoiceButtonProxyBeVisible();
             voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);
+            voiceButtonProxy.bringToFront();
         }
     }
+
+    /**
+     * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button proxy
+     * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.
+     */
+    public void disableVoiceButtonProxy(boolean disabled) {
+        updateVoiceButtonProxyVisible(disabled);
+    }
     /**
      * Sets the app market icon
      */
     private void updateAppMarketIcon() {
-        final View marketButton = findViewById(R.id.market_button);
-        Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);
-        // Find the app market activity by resolving an intent.
-        // (If multiple app markets are installed, it will return the ResolverActivity.)
-        ComponentName activityName = intent.resolveActivity(getPackageManager());
-        if (activityName != null) {
-            int coi = getCurrentOrientationIndexForGlobalIcons();
-            mAppMarketIntent = intent;
-            sAppMarketIcon[coi] = updateTextButtonWithIconFromExternalActivity(
-                    R.id.market_button, activityName, R.drawable.ic_launcher_market_holo,
-                    TOOLBAR_ICON_METADATA_NAME);
-            marketButton.setVisibility(View.VISIBLE);
-        } else {
-            // We should hide and disable the view so that we don't try and restore the visibility
-            // of it when we swap between drag & normal states from IconDropTarget subclasses.
-            marketButton.setVisibility(View.GONE);
-            marketButton.setEnabled(false);
+        if (!DISABLE_MARKET_BUTTON) {
+            final View marketButton = findViewById(R.id.market_button);
+            Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);
+            // Find the app market activity by resolving an intent.
+            // (If multiple app markets are installed, it will return the ResolverActivity.)
+            ComponentName activityName = intent.resolveActivity(getPackageManager());
+            if (activityName != null) {
+                int coi = getCurrentOrientationIndexForGlobalIcons();
+                mAppMarketIntent = intent;
+                sAppMarketIcon[coi] = updateTextButtonWithIconFromExternalActivity(
+                        R.id.market_button, activityName, R.drawable.ic_launcher_market_holo,
+                        TOOLBAR_ICON_METADATA_NAME);
+                marketButton.setVisibility(View.VISIBLE);
+            } else {
+                // We should hide and disable the view so that we don't try and restore the visibility
+                // of it when we swap between drag & normal states from IconDropTarget subclasses.
+                marketButton.setVisibility(View.GONE);
+                marketButton.setEnabled(false);
+            }
         }
     }
 
     private void updateAppMarketIcon(Drawable.ConstantState d) {
-        // Ensure that the new drawable we are creating has the approprate toolbar icon bounds
-        Resources r = getResources();
-        Drawable marketIconDrawable = d.newDrawable(r);
-        int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);
-        int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);
-        marketIconDrawable.setBounds(0, 0, w, h);
+        if (!DISABLE_MARKET_BUTTON) {
+            // Ensure that the new drawable we are creating has the approprate toolbar icon bounds
+            Resources r = getResources();
+            Drawable marketIconDrawable = d.newDrawable(r);
+            int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);
+            int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);
+            marketIconDrawable.setBounds(0, 0, w, h);
 
-        updateTextButtonWithDrawable(R.id.market_button, marketIconDrawable);
+            updateTextButtonWithDrawable(R.id.market_button, marketIconDrawable);
+        }
     }
 
     @Override
@@ -3826,7 +3881,9 @@
 
         // Update the market app icon as necessary (the other icons will be managed in response to
         // package changes in bindSearchablesChanged()
-        updateAppMarketIcon();
+        if (!DISABLE_MARKET_BUTTON) {
+            updateAppMarketIcon();
+        }
 
         mWorkspaceLoading = false;
         if (upgradePath) {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index f8644b1..cc89d01 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -694,6 +694,7 @@
      */
     static void modifyItemInDatabase(Context context, final ItemInfo item, final long container,
             final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) {
+        item.container = container;
         item.cellX = cellX;
         item.cellY = cellY;
         item.spanX = spanX;
diff --git a/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java b/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
index 7ed1c1b..70ef7c3 100644
--- a/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
+++ b/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
@@ -39,7 +39,8 @@
     private final LayoutInflater mInflater;
     private final PackageManager mPackageManager;
 
-    private List<ResolveInfo> mThirdPartyWallpaperPickers = new ArrayList<ResolveInfo>();
+    private List<ThirdPartyWallpaperTile> mThirdPartyWallpaperPickers =
+            new ArrayList<ThirdPartyWallpaperTile>();
 
     public static class ThirdPartyWallpaperTile extends WallpaperPickerActivity.WallpaperTileInfo {
         private ResolveInfo mResolveInfo;
@@ -96,7 +97,7 @@
                     continue outerLoop;
                 }
             }
-            mThirdPartyWallpaperPickers.add(info);
+            mThirdPartyWallpaperPickers.add(new ThirdPartyWallpaperTile(info));
         }
     }
 
@@ -104,7 +105,7 @@
         return mThirdPartyWallpaperPickers.size();
     }
 
-    public ResolveInfo getItem(int position) {
+    public ThirdPartyWallpaperTile getItem(int position) {
         return mThirdPartyWallpaperPickers.get(position);
     }
 
@@ -123,7 +124,7 @@
 
         WallpaperPickerActivity.setWallpaperItemPaddingToZero((FrameLayout) view);
 
-        ResolveInfo info = mThirdPartyWallpaperPickers.get(position);
+        ResolveInfo info = mThirdPartyWallpaperPickers.get(position).mResolveInfo;
         TextView label = (TextView) view.findViewById(R.id.wallpaper_item_label);
         label.setText(info.loadLabel(mPackageManager));
         label.setCompoundDrawablesWithIntrinsicBounds(
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 4a8a237..b6900fe 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -48,8 +48,8 @@
 
     private static int sIconWidth = -1;
     private static int sIconHeight = -1;
-    private static int sIconTextureWidth = -1;
-    private static int sIconTextureHeight = -1;
+    public static int sIconTextureWidth = -1;
+    public static int sIconTextureHeight = -1;
 
     private static final Paint sBlurPaint = new Paint();
     private static final Paint sGlowColorPressedPaint = new Paint();
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index bc8df6c..cdfcd1c 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -506,7 +506,9 @@
                             (int) returnRect.height(), Bitmap.Config.ARGB_8888);
                     if (tmp != null) {
                         Canvas c = new Canvas(tmp);
-                        c.drawBitmap(crop, m, new Paint());
+                        Paint p = new Paint();
+                        p.setFilterBitmap(true);
+                        c.drawBitmap(crop, m, p);
                         crop = tmp;
                     }
                 } else if (mRotation > 0) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index baddc2d..ea348ef 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1024,28 +1024,28 @@
             stripEmptyScreens();
             mStripScreensOnPageStopMoving = false;
         }
-
-        if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
-            mCustomContentShowing = true;
-            if (mCustomContentCallbacks != null) {
-                mCustomContentCallbacks.onShow();
-                mCustomContentShowTime = System.currentTimeMillis();
-                mLauncher.setVoiceButtonProxyVisible(false);
-            }
-        } else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
-            mCustomContentShowing = false;
-            if (mCustomContentCallbacks != null) {
-                mCustomContentCallbacks.onHide();
-                mLauncher.resetQSBScroll();
-                mLauncher.setVoiceButtonProxyVisible(true);
-            }
-        }
     }
 
     @Override
     protected void notifyPageSwitchListener() {
         super.notifyPageSwitchListener();
         Launcher.setScreen(mCurrentPage);
+
+        if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
+            mCustomContentShowing = true;
+            if (mCustomContentCallbacks != null) {
+                mCustomContentCallbacks.onShow();
+                mCustomContentShowTime = System.currentTimeMillis();
+                mLauncher.updateVoiceButtonProxyVisible(false);
+            }
+        } else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
+            mCustomContentShowing = false;
+            if (mCustomContentCallbacks != null) {
+                mCustomContentCallbacks.onHide();
+                mLauncher.resetQSBScroll();
+                mLauncher.updateVoiceButtonProxyVisible(false);
+            }
+        }
     };
 
     protected void setWallpaperDimension() {
@@ -1070,7 +1070,6 @@
     class WallpaperOffsetInterpolator implements Choreographer.FrameCallback {
         float mFinalOffset = 0.0f;
         float mCurrentOffset = 0.5f; // to force an initial update
-        //long mLastWallpaperOffsetUpdateTime;
         boolean mWaitingForUpdate;
         Choreographer mChoreographer;
         Interpolator mInterpolator;
@@ -1135,10 +1134,12 @@
             }
 
             // Exclude the leftmost page
-            final int firstIndex = isLayoutRtl() ? getChildCount() - 2 : 1;
+            final int startPage = hasCustomContent() ? 1 : 0;
+            final int firstIndex = isLayoutRtl() ? getChildCount() - 1 - startPage : startPage;
             // Exclude the last extra empty screen (if we have > MIN_PARALLAX_PAGE_SPAN pages)
-            int extra = numExtraScreensToIgnore();
-            final int lastIndex = isLayoutRtl() ? 0 + extra : getChildCount() - 1 - extra;
+            int emptyExtraPages = numExtraScreensToIgnore();
+            final int lastIndex =
+                    isLayoutRtl() ? 0 + emptyExtraPages : getChildCount() - 1 - emptyExtraPages;
 
             int firstPageScrollX = getScrollForPage(firstIndex);
             int scrollRange = getScrollForPage(lastIndex) - firstPageScrollX;
@@ -1166,7 +1167,8 @@
         }
 
         private int getNumScreensExcludingExtraEmptyScreenAndLeftmost() {
-            int numScrollingPages = getChildCount() - 1 - numExtraScreensToIgnore();
+            int numScrollingPages = getChildCount() - numExtraScreensToIgnore();
+            if (hasCustomContent()) numScrollingPages -= 1;
             return numScrollingPages;
         }
 
@@ -1823,6 +1825,16 @@
         return offsetDelta;
     }
 
+    boolean shouldVoiceButtonProxyBeVisible() {
+        if (isOnOrMovingToCustomContent()) {
+            return false;
+        }
+        if (mState != State.NORMAL) {
+            return false;
+        }
+        return true;
+    }
+
     Animator getChangeStateAnimation(final State state, boolean animated, int delay, int snapPage) {
         if (mState == state) {
             return null;
@@ -1975,11 +1987,7 @@
             setScaleY(mNewScale);
             setTranslationY(finalWorkspaceTranslationY);
         }
-        if (finalSearchBarAlpha == 0) {
-            mLauncher.setVoiceButtonProxyVisible(false);
-        } else {
-            mLauncher.setVoiceButtonProxyVisible(true);
-        }
+        mLauncher.updateVoiceButtonProxyVisible(false);
 
         if (stateIsSpringLoaded) {
             // Right now we're covered by Apps Customize