Merge "Making the search bar span the available space on the phone ui in portrait."
diff --git a/res/layout/qsb_bar.xml b/res/layout/qsb_bar.xml
index b5b563b..abcc941 100644
--- a/res/layout/qsb_bar.xml
+++ b/res/layout/qsb_bar.xml
@@ -26,7 +26,7 @@
     <LinearLayout
         style="@style/SearchDropTargetBar"
         android:id="@+id/drag_target_bar"
-        android:alpha="0">
+        android:visibility="gone">
 
         <com.android.launcher2.DeleteDropTarget
             style="@style/DropTargetButtonContainer"
diff --git a/res/values-land/config.xml b/res/values-land/config.xml
new file mode 100644
index 0000000..adbc015
--- /dev/null
+++ b/res/values-land/config.xml
@@ -0,0 +1,5 @@
+<resources>
+<!-- Workspace -->
+    <!-- Whether or not the drop targets drop down as opposed to fade in -->
+    <bool name="config_useDropTargetDownTransition">false</bool>
+</resources>
diff --git a/res/values-large-land/dimens.xml b/res/values-large-land/dimens.xml
index d14a8df..12fc8b3 100644
--- a/res/values-large-land/dimens.xml
+++ b/res/values-large-land/dimens.xml
@@ -34,4 +34,4 @@
     <dimen name="apps_customize_pageLayoutPaddingBottom">14dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingLeft">40dp</dimen>
     <dimen name="apps_customize_pageLayoutPaddingRight">40dp</dimen>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/res/values-large/config.xml b/res/values-large/config.xml
index 2a52664..34dbb0f 100644
--- a/res/values-large/config.xml
+++ b/res/values-large/config.xml
@@ -18,6 +18,9 @@
     <integer name="config_customizeWorkspaceShrinkTime">800</integer>
 
 <!-- Workspace -->
+    <!-- Whether or not the drop targets drop down as opposed to fade in -->
+    <bool name="config_useDropTargetDownTransition">true</bool>
+
     <!-- When dragging items on the workspace, how much bigger (in pixels) the dragged view
          should be, as compared to the original view. If 0, it will not be scaled at all.
          Should be an even number, for pixel alignment. -->
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
index 59aaa41..05ec9c8 100644
--- a/res/values-large/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -56,10 +56,6 @@
     <dimen name="all_apps_button_drawable_padding">0dip</dimen>
     <dimen name="all_apps_button_vertical_padding">4dip</dimen>
 
-    <!-- height & width of the drop rectangle for the trash icon -->
-    <dimen name="delete_zone_vertical_drag_padding">20dip</dimen>
-    <dimen name="delete_zone_horizontal_drag_padding">20dip</dimen>
-
     <!-- roughly a status bar (for determining how many rows of icons are in home) -->
     <dimen name="status_bar_height">48dip</dimen>
 
diff --git a/res/values/config.xml b/res/values/config.xml
index fca0acc..7a45211 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,5 +1,6 @@
 <resources>
     <bool name="config_hardwareAccelerated">true</bool>
+
 <!-- AllApps/Customize/AppsCustomize -->
     <!-- The alpha of the AppsCustomize bg in spring loaded mode -->
     <integer name="config_appsCustomizeSpringLoadedBgAlpha">45</integer>
@@ -46,6 +47,9 @@
     <integer name="config_allAppsBatchSize">0</integer>
 
 <!-- Workspace -->
+    <!-- Whether or not the drop targets drop down as opposed to fade in -->
+    <bool name="config_useDropTargetDownTransition">true</bool>
+
     <!-- The transition duration for the background of the drop targets -->
     <integer name="config_dropTargetBgTransitionDuration">100</integer>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c04dd8e..08a2c76 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -43,6 +43,9 @@
     <!-- height of the bottom row of controls -->
     <dimen name="button_bar_height">56dip</dimen>
 
+    <!-- Drag padding to add to the drop targets -->
+    <dimen name="drop_target_drag_padding">20dp</dimen>
+
     <!-- so we have access to this dimension in landscape mode even though
          button_bar_height changes -->
     <dimen name="button_bar_height_portrait">56dip</dimen>
diff --git a/src/com/android/launcher2/ButtonDropTarget.java b/src/com/android/launcher2/ButtonDropTarget.java
index f87889c..edc5acf 100644
--- a/src/com/android/launcher2/ButtonDropTarget.java
+++ b/src/com/android/launcher2/ButtonDropTarget.java
@@ -17,6 +17,7 @@
 package com.android.launcher2;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Paint;
 import android.util.AttributeSet;
 import android.widget.FrameLayout;
@@ -32,6 +33,7 @@
     protected final int mTransitionDuration;
 
     protected Launcher mLauncher;
+    private int mBottomDragPadding;
 
     /** Whether this drop target is active for the current drag */
     protected boolean mActive;
@@ -46,8 +48,9 @@
     public ButtonDropTarget(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        mTransitionDuration =
-            context.getResources().getInteger(R.integer.config_dropTargetBgTransitionDuration);
+        Resources r = getResources();
+        mTransitionDuration = r.getInteger(R.integer.config_dropTargetBgTransitionDuration);
+        mBottomDragPadding = r.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
     }
 
     void setLauncher(Launcher launcher) {
@@ -87,6 +90,12 @@
     }
 
     @Override
+    public void getHitRect(android.graphics.Rect outRect) {
+        super.getHitRect(outRect);
+        outRect.bottom += mBottomDragPadding;
+    }
+
+    @Override
     public DropTarget getDropTargetDelegate(DragObject d) {
         return null;
     }
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index c8c6faa..ffe4533 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -17,6 +17,7 @@
 package com.android.launcher2;
 
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.PorterDuff;
@@ -31,6 +32,7 @@
 public class DeleteDropTarget extends ButtonDropTarget {
 
     private TextView mText;
+    private ColorStateList mOriginalTextColor;
     private TransitionDrawable mDrawable;
     private int mHoverColor = 0xFFFF0000;
 
@@ -48,6 +50,7 @@
 
         // Get the drawable
         mText = (TextView) findViewById(R.id.delete_target_text);
+        mOriginalTextColor = mText.getTextColors();
 
         // Get the hover color
         Resources r = getResources();
@@ -114,6 +117,7 @@
 
         mActive = isVisible;
         mDrawable.resetTransition();
+        mText.setTextColor(mOriginalTextColor);
         setVisibility(isVisible ? View.VISIBLE : View.GONE);
         if (mText.getText().length() > 0) {
             mText.setText(isUninstall ? R.string.delete_target_uninstall_label
@@ -131,6 +135,7 @@
         super.onDragEnter(d);
 
         mDrawable.startTransition(mTransitionDuration);
+        mText.setTextColor(mHoverColor);
     }
 
     public void onDragExit(DragObject d) {
@@ -138,6 +143,7 @@
 
         if (!d.dragComplete) {
             mDrawable.resetTransition();
+            mText.setTextColor(mOriginalTextColor);
         }
     }
 
diff --git a/src/com/android/launcher2/InfoDropTarget.java b/src/com/android/launcher2/InfoDropTarget.java
index 02e3f01..6ad7630 100644
--- a/src/com/android/launcher2/InfoDropTarget.java
+++ b/src/com/android/launcher2/InfoDropTarget.java
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.PorterDuff;
@@ -32,6 +33,7 @@
 public class InfoDropTarget extends ButtonDropTarget {
 
     private TextView mText;
+    private ColorStateList mOriginalTextColor;
     private TransitionDrawable mDrawable;
     private int mHoverColor = 0xFF0000FF;
 
@@ -48,6 +50,7 @@
         super.onFinishInflate();
 
         mText = (TextView) findViewById(R.id.info_target_text);
+        mOriginalTextColor = mText.getTextColors();
 
         // Get the hover color
         Resources r = getResources();
@@ -98,6 +101,7 @@
 
         mActive = isVisible;
         mDrawable.resetTransition();
+        mText.setTextColor(mOriginalTextColor);
         setVisibility(isVisible ? View.VISIBLE : View.GONE);
     }
 
@@ -111,6 +115,7 @@
         super.onDragEnter(d);
 
         mDrawable.startTransition(mTransitionDuration);
+        mText.setTextColor(mHoverColor);
     }
 
     public void onDragExit(DragObject d) {
@@ -118,6 +123,7 @@
 
         if (!d.dragComplete) {
             mDrawable.resetTransition();
+            mText.setTextColor(mOriginalTextColor);
         }
     }
 }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 4e69ee8..885d360 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -2706,7 +2706,9 @@
                 }
             }
         } catch (NameNotFoundException e) {
-            // Do nothing
+            // This can happen if the activity defines an invalid drawable
+            Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +
+                    " not found", e);
         } catch (Resources.NotFoundException nfe) {
             // This can happen if the activity defines an invalid drawable
             Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 1a097b5..331f124 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -16,15 +16,6 @@
 
 package com.android.launcher2;
 
-import java.lang.ref.WeakReference;
-import java.net.URISyntaxException;
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.BroadcastReceiver;
@@ -55,6 +46,16 @@
 import com.android.launcher.R;
 import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
 
+import java.lang.ref.WeakReference;
+import java.net.URISyntaxException;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
 /**
  * Maintains in-memory state of the Launcher. It is expected that there should be only one
  * LauncherModel object held in a static. Also provide APIs for updating the database state
@@ -567,6 +568,7 @@
             // to reload.  Either way, mAllAppsLoaded will be cleared so it re-reads everything
             // next time.
             mAllAppsLoaded = false;
+            mWorkspaceLoaded = false;
             startLoaderFromBackground();
         }
     }
@@ -653,6 +655,7 @@
             if (DEBUG_LOADERS) {
                 Log.d(TAG, "loadAndBindWorkspace mWorkspaceLoaded=" + mWorkspaceLoaded);
             }
+
             if (!mWorkspaceLoaded) {
                 loadWorkspace();
                 if (mStopped) {
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index e4cf361..201daab 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -18,10 +18,14 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 
 import com.android.launcher.R;
@@ -32,11 +36,11 @@
  */
 public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener {
 
-    private static final int sTransitionInDuration = 275;
-    private static final int sTransitionOutDuration = 125;
+    private static final int sTransitionInDuration = 200;
+    private static final int sTransitionOutDuration = 175;
 
-    private ObjectAnimator mDropTargetBarFadeInAnim;
-    private ObjectAnimator mDropTargetBarFadeOutAnim;
+    private AnimatorSet mDropTargetBarFadeInAnim;
+    private AnimatorSet mDropTargetBarFadeOutAnim;
     private ObjectAnimator mQSBSearchBarFadeInAnim;
     private ObjectAnimator mQSBSearchBarFadeOutAnim;
 
@@ -45,6 +49,7 @@
     private View mDropTargetBar;
     private ButtonDropTarget mInfoDropTarget;
     private ButtonDropTarget mDeleteDropTarget;
+    private int mBarHeight;
 
     public SearchDropTargetBar(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -73,9 +78,21 @@
         mDropTargetBar = findViewById(R.id.drag_target_bar);
         mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target);
         mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target);
+        mBarHeight = getResources().getDimensionPixelSize(R.dimen.qsb_bar_height);
+
+        boolean enableDropDownDropTargets =
+            getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
 
         // Create the various fade animations
-        mDropTargetBarFadeInAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 1f);
+        mDropTargetBar.setAlpha(0f);
+        ObjectAnimator fadeInAlphaAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 1f);
+        fadeInAlphaAnim.setInterpolator(new DecelerateInterpolator());
+        mDropTargetBarFadeInAnim = new AnimatorSet();
+        AnimatorSet.Builder fadeInAnimators = mDropTargetBarFadeInAnim.play(fadeInAlphaAnim);
+        if (enableDropDownDropTargets) {
+            mDropTargetBar.setTranslationY(-mBarHeight);
+            fadeInAnimators.with(ObjectAnimator.ofFloat(mDropTargetBar, "translationY", 0f));
+        }
         mDropTargetBarFadeInAnim.setDuration(sTransitionInDuration);
         mDropTargetBarFadeInAnim.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -83,12 +100,20 @@
                 mDropTargetBar.setVisibility(View.VISIBLE);
             }
         });
-        mDropTargetBarFadeOutAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f);
+        ObjectAnimator fadeOutAlphaAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f);
+        fadeOutAlphaAnim.setInterpolator(new AccelerateInterpolator());
+        mDropTargetBarFadeOutAnim = new AnimatorSet();
+        AnimatorSet.Builder fadeOutAnimators = mDropTargetBarFadeOutAnim.play(fadeOutAlphaAnim);
+        if (enableDropDownDropTargets) {
+            fadeOutAnimators.with(ObjectAnimator.ofFloat(mDropTargetBar, "translationY",
+                    -mBarHeight));
+        }
         mDropTargetBarFadeOutAnim.setDuration(sTransitionOutDuration);
         mDropTargetBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 mDropTargetBar.setVisibility(View.GONE);
+                mDropTargetBar.setLayerType(View.LAYER_TYPE_NONE, null);
             }
         });
         mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 1f);
@@ -156,8 +181,12 @@
     @Override
     public void onDragStart(DragSource source, Object info, int dragAction) {
         // Animate out the QSB search bar, and animate in the drop target bar
+        mDropTargetBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        mDropTargetBar.buildLayer();
+        mDropTargetBarFadeOutAnim.cancel();
         mDropTargetBarFadeInAnim.start();
         if (!mIsSearchBarHidden) {
+            mQSBSearchBarFadeInAnim.cancel();
             mQSBSearchBarFadeOutAnim.start();
         }
     }
@@ -165,8 +194,10 @@
     @Override
     public void onDragEnd() {
         // Restore the QSB search bar, and animate out the drop target bar
+        mDropTargetBarFadeInAnim.cancel();
         mDropTargetBarFadeOutAnim.start();
         if (!mIsSearchBarHidden) {
+            mQSBSearchBarFadeOutAnim.cancel();
             mQSBSearchBarFadeInAnim.start();
         }
     }