merge in ics-release history after reset to master
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index cfdfe3c..dd9120f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -19,9 +19,7 @@
 -->
 <manifest
     xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.launcher"
-    android:sharedUserId="@string/sharedUserId"
-    >
+    package="com.android.launcher">
 
     <original-package android:name="com.android.launcher2" />
 
@@ -51,20 +49,15 @@
         android:description="@string/permdesc_write_settings"/>
 
     <uses-permission android:name="android.permission.CALL_PHONE" />
-    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
-    <uses-permission android:name="android.permission.GET_TASKS" />
-    <uses-permission android:name="android.permission.READ_CONTACTS"/>
     <uses-permission android:name="android.permission.SET_WALLPAPER" />
     <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
     <uses-permission android:name="android.permission.VIBRATE" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.BIND_APPWIDGET" />
     <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
     <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
 
     <application
         android:name="com.android.launcher2.LauncherApplication"
-        android:process="@string/process"
         android:label="@string/application_name"
         android:icon="@drawable/ic_launcher_home"
         android:hardwareAccelerated="@bool/config_hardwareAccelerated"
diff --git a/res/layout-port/search_bar.xml b/res/layout-port/search_bar.xml
index dbacd3d..6b2c827 100644
--- a/res/layout-port/search_bar.xml
+++ b/res/layout-port/search_bar.xml
@@ -24,6 +24,7 @@
    <!-- Global search icon -->
    <LinearLayout
         style="@style/SearchButton"
+        android:id="@+id/search_button_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_alignParentLeft="true"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0f4a3ba..6f6a158 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,13 +18,6 @@
 -->
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Manifest configuration. -->
-    <skip />
-    <!-- Do not translate. android:sharedUserId of this application. -->
-    <string name="sharedUserId" translatable="false"><xliff:g id="x"></xliff:g></string>
-    <!-- Do not translate. android:process of this application. -->
-    <string name="process" translatable="false"><xliff:g id="x"></xliff:g></string>
-
     <!-- General -->
     <skip />
     <!-- Application name -->
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 1fbf7a5..5eaf773 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -95,8 +95,10 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -188,7 +190,7 @@
     private Hotseat mHotseat;
     private View mAllAppsButton;
 
-    private SearchDropTargetBar mSearchDeleteBar;
+    private SearchDropTargetBar mSearchDropTargetBar;
     private AppsCustomizeTabHost mAppsCustomizeTabHost;
     private AppsCustomizePagedView mAppsCustomizeContent;
     private boolean mAutoAdvanceRunning = false;
@@ -236,6 +238,8 @@
     private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
     private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2];
 
+    static final ArrayList<String> sDumpLogs = new ArrayList<String>();
+
     private DragLayer mDragLayer;
 
     private BubbleTextView mWaitingForResume;
@@ -307,22 +311,28 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         registerReceiver(mCloseSystemDialogsReceiver, filter);
 
+        boolean searchVisible = false;
+        boolean voiceVisible = false;
         // If we have a saved version of these external icons, we load them up immediately
         int coi = getCurrentOrientationIndexForGlobalIcons();
         if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null ||
                 sAppMarketIcon[coi] == null) {
-            updateIconsAffectedByPackageManagerChanges();
-            updateGlobalSearchIcon();
+            updateAppMarketIcon();
+            searchVisible = updateGlobalSearchIcon();
+            voiceVisible = updateVoiceSearchIcon(searchVisible);
         }
         if (sGlobalSearchIcon[coi] != null) {
              updateGlobalSearchIcon(sGlobalSearchIcon[coi]);
+             searchVisible = true;
         }
         if (sVoiceSearchIcon[coi] != null) {
             updateVoiceSearchIcon(sVoiceSearchIcon[coi]);
+            voiceVisible = true;
         }
         if (sAppMarketIcon[coi] != null) {
             updateAppMarketIcon(sAppMarketIcon[coi]);
         }
+        mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
 
         // On large interfaces, we want the screen to auto-rotate based on the current orientation
         if (LauncherApplication.isScreenLarge() || Build.TYPE.contentEquals("eng")) {
@@ -720,7 +730,7 @@
         dragController.addDragListener(mWorkspace);
 
         // Get the search/delete bar
-        mSearchDeleteBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar);
+        mSearchDropTargetBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar);
 
         // Setup AppsCustomize
         mAppsCustomizeTabHost = (AppsCustomizeTabHost)
@@ -736,8 +746,8 @@
         dragController.setScrollView(mDragLayer);
         dragController.setMoveTarget(mWorkspace);
         dragController.addDropTarget(mWorkspace);
-        if (mSearchDeleteBar != null) {
-            mSearchDeleteBar.setup(this, dragController);
+        if (mSearchDropTargetBar != null) {
+            mSearchDropTargetBar.setup(this, dragController);
         }
     }
 
@@ -2360,7 +2370,7 @@
                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should
                     // clean up our state transition functions
                     mAppsCustomizeTabHost.setVisibility(View.GONE);
-                    mSearchDeleteBar.showSearchBar(true);
+                    mSearchDropTargetBar.showSearchBar(true);
                     showWorkspace(true);
                 } else {
                     exitSpringLoadedDragMode();
@@ -2388,7 +2398,7 @@
     void showHotseat(boolean animated) {
         if (!LauncherApplication.isScreenLarge()) {
             if (animated) {
-                int duration = mSearchDeleteBar.getTransitionInDuration();
+                int duration = mSearchDropTargetBar.getTransitionInDuration();
                 mHotseat.animate().alpha(1f).setDuration(duration);
             } else {
                 mHotseat.setAlpha(1f);
@@ -2402,7 +2412,7 @@
     void hideHotseat(boolean animated) {
         if (!LauncherApplication.isScreenLarge()) {
             if (animated) {
-                int duration = mSearchDeleteBar.getTransitionOutDuration();
+                int duration = mSearchDropTargetBar.getTransitionOutDuration();
                 mHotseat.animate().alpha(0f).setDuration(duration);
             } else {
                 mHotseat.setAlpha(0f);
@@ -2417,7 +2427,7 @@
         mAppsCustomizeTabHost.requestFocus();
 
         // Hide the search bar and hotseat
-        mSearchDeleteBar.hideSearchBar(animated);
+        mSearchDropTargetBar.hideSearchBar(animated);
 
         // Change the state *after* we've called all the transition code
         mState = State.APPS_CUSTOMIZE;
@@ -2476,7 +2486,7 @@
             cameraZoomIn(State.APPS_CUSTOMIZE, animated, false);
 
             // Show the search bar and hotseat
-            mSearchDeleteBar.showSearchBar(animated);
+            mSearchDropTargetBar.showSearchBar(animated);
 
             // Set focus to the AppsCustomize button
             if (mAllAppsButton != null) {
@@ -2593,9 +2603,11 @@
         button.setImageDrawable(d.newDrawable(getResources()));
     }
 
-    private void updateGlobalSearchIcon() {
+    private boolean updateGlobalSearchIcon() {
+        final View searchButtonContainer = findViewById(R.id.search_button_container);
         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
         final View searchDivider = findViewById(R.id.search_divider);
+        final View voiceButtonContainer = findViewById(R.id.voice_button_container);
         final View voiceButton = findViewById(R.id.voice_button);
 
         final SearchManager searchManager =
@@ -2605,13 +2617,18 @@
             int coi = getCurrentOrientationIndexForGlobalIcons();
             sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
                     R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo);
-            searchButton.setVisibility(View.VISIBLE);
             if (searchDivider != null) searchDivider.setVisibility(View.VISIBLE);
+            if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);
+            searchButton.setVisibility(View.VISIBLE);
+            return true;
         } else {
             // We disable both search and voice search when there is no global search provider
-            searchButton.setVisibility(View.GONE);
             if (searchDivider != null) searchDivider.setVisibility(View.GONE);
+            if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);
+            if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
+            searchButton.setVisibility(View.GONE);
             voiceButton.setVisibility(View.GONE);
+            return false;
         }
     }
 
@@ -2619,21 +2636,27 @@
         updateButtonWithDrawable(R.id.search_button, d);
     }
 
-    private void updateVoiceSearchIcon() {
+    private boolean updateVoiceSearchIcon(boolean searchVisible) {
         final View searchDivider = findViewById(R.id.search_divider);
+        final View voiceButtonContainer = findViewById(R.id.voice_button_container);
         final View voiceButton = findViewById(R.id.voice_button);
 
+        // We only show/update the voice search icon if the search icon is enabled as well
         Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
         ComponentName activityName = intent.resolveActivity(getPackageManager());
-        if (activityName != null) {
+        if (searchVisible && activityName != null) {
             int coi = getCurrentOrientationIndexForGlobalIcons();
             sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
                     R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo);
             if (searchDivider != null) searchDivider.setVisibility(View.VISIBLE);
+            if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);
             voiceButton.setVisibility(View.VISIBLE);
+            return true;
         } else {
             if (searchDivider != null) searchDivider.setVisibility(View.GONE);
+            if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
             voiceButton.setVisibility(View.GONE);
+            return false;
         }
     }
 
@@ -2937,21 +2960,17 @@
             completeAdd(sPendingAddList.get(i));
         }
         sPendingAddList.clear();
-    }
 
-    /**
-     * Updates the icons on the launcher that are affected by changes to the package list
-     * on the device.
-     */
-    private void updateIconsAffectedByPackageManagerChanges() {
+        // Update the market app icon as necessary (the other icons will be managed in response to
+        // package changes in bindSearchablesChanged()
         updateAppMarketIcon();
-        updateVoiceSearchIcon();
     }
 
     @Override
     public void bindSearchablesChanged() {
-        updateGlobalSearchIcon();
-        updateVoiceSearchIcon();
+        boolean searchVisible = updateGlobalSearchIcon();
+        boolean voiceVisible = updateVoiceSearchIcon(searchVisible);
+        mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
     }
 
     /**
@@ -2977,9 +2996,6 @@
                 }
             }
         });
-
-        updateIconsAffectedByPackageManagerChanges();
-        updateGlobalSearchIcon();
     }
 
     /**
@@ -2994,7 +3010,6 @@
         if (mAppsCustomizeContent != null) {
             mAppsCustomizeContent.addApps(apps);
         }
-        updateIconsAffectedByPackageManagerChanges();
     }
 
     /**
@@ -3012,7 +3027,6 @@
         if (mAppsCustomizeContent != null) {
             mAppsCustomizeContent.updateApps(apps);
         }
-        updateIconsAffectedByPackageManagerChanges();
     }
 
     /**
@@ -3029,7 +3043,6 @@
         if (mAppsCustomizeContent != null) {
             mAppsCustomizeContent.removeApps(apps);
         }
-        updateIconsAffectedByPackageManagerChanges();
 
         // Notify the drag controller
         mDragController.onAppsRemoved(apps, this);
@@ -3223,6 +3236,16 @@
         }
         Log.d(TAG, "END launcher2 dump state");
     }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        super.dump(prefix, fd, writer, args);
+        writer.println(" ");
+        writer.println("Debug logs: ");
+        for (int i = 0; i < sDumpLogs.size(); i++) {
+            writer.println("  " + sDumpLogs.get(i));
+        }
+    }
 }
 
 interface LauncherTransitionable {
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index f752de1..fc31d65 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1091,8 +1091,10 @@
 
                             if (!isSafeMode && (provider == null || provider.provider == null ||
                                     provider.provider.getPackageName() == null)) {
-                                Log.e(TAG, "Deleting widget that isn't installed anymore: id="
-                                        + id + " appWidgetId=" + appWidgetId);
+                                String log = "Deleting widget that isn't installed anymore: id="
+                                    + id + " appWidgetId=" + appWidgetId;
+                                Log.e(TAG, log); 
+                                Launcher.sDumpLogs.add(log);
                                 itemsToRemove.add(id);
                             } else {
                                 appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId);
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index 69a1213..b4a9fc9 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -21,7 +21,7 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.AccelerateInterpolator;
@@ -52,6 +52,8 @@
     private int mBarHeight;
     private boolean mDeferOnDragEnd = false;
 
+    private Drawable mPreviousBackground;
+
     public SearchDropTargetBar(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -213,4 +215,18 @@
             mDeferOnDragEnd = false;
         }
     }
+
+    public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
+        if (mQSBSearchBar != null) {
+            Drawable bg = mQSBSearchBar.getBackground();
+            if (bg != null && (!searchVisible && !voiceVisible)) {
+                // Save the background and disable it
+                mPreviousBackground = bg;
+                mQSBSearchBar.setBackgroundResource(0);
+            } else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
+                // Restore the background
+                mQSBSearchBar.setBackgroundDrawable(mPreviousBackground);
+            }
+        }
+    }
 }