OSDN Git Service

Adding viewId for the QSB
[android-x86/packages-apps-Launcher3.git] / src / com / android / launcher3 / Launcher.java
index 191fdf4..c317da4 100644 (file)
@@ -36,7 +36,6 @@ import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -48,7 +47,6 @@ import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
-import android.database.ContentObserver;
 import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -66,6 +64,7 @@ import android.os.Handler;
 import android.os.Message;
 import android.os.StrictMode;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
@@ -99,13 +98,13 @@ import android.widget.Toast;
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.PagedView.PageSwitchListener;
 import com.android.launcher3.allapps.AllAppsContainerView;
-import com.android.launcher3.allapps.AppSearchManager;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.LongArrayMap;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -117,8 +116,6 @@ import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -133,14 +130,10 @@ import java.util.concurrent.atomic.AtomicInteger;
  */
 public class Launcher extends Activity
         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
-                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,
-                   LauncherStateTransitionAnimation.Callbacks {
+                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {
     static final String TAG = "Launcher";
     static final boolean LOGD = false;
 
-    // Temporary flag
-    static final boolean DISABLE_ALL_APPS_SEARCH_INTEGRATION = true;
-
     static final boolean PROFILE_STARTUP = false;
     static final boolean DEBUG_WIDGETS = true;
     static final boolean DEBUG_STRICT_MODE = false;
@@ -214,6 +207,8 @@ public class Launcher extends Activity
 
     private static final String QSB_WIDGET_ID = "qsb_widget_id";
     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";
+    // Item id to use for QSB widget.
+    private static final int QSB_ITEM_ID = -1;
 
     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";
 
@@ -244,7 +239,6 @@ public class Launcher extends Activity
 
     private final BroadcastReceiver mCloseSystemDialogsReceiver
             = new CloseSystemDialogsIntentReceiver();
-    private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();
 
     private LayoutInflater mInflater;
 
@@ -268,6 +262,7 @@ public class Launcher extends Activity
     private ViewGroup mOverviewPanel;
 
     private View mAllAppsButton;
+    private View mWidgetsButton;
 
     private SearchDropTargetBar mSearchDropTargetBar;
 
@@ -308,6 +303,8 @@ public class Launcher extends Activity
     private boolean mHasFocus = false;
     private boolean mAttached = false;
 
+    private LauncherClings mClings;
+
     private static LongArrayMap<FolderInfo> sFolders = new LongArrayMap<>();
 
     private View.OnTouchListener mHapticFeedbackTouchListener;
@@ -365,18 +362,6 @@ public class Launcher extends Activity
         }
     }
 
-    // TODO: remove this field and call method directly when Launcher3 can depend on M APIs
-    private static Method sClipRevealMethod = null;
-    static {
-        Class<?> activityOptionsClass = ActivityOptions.class;
-        try {
-            sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",
-                    View.class, int.class, int.class, int.class, int.class);
-        } catch (Exception e) {
-            // Earlier version
-        }
-    }
-
     @Thunk Runnable mBuildLayersRunnable = new Runnable() {
         public void run() {
             if (mWorkspace != null) {
@@ -441,7 +426,6 @@ public class Launcher extends Activity
 
         LauncherAppState.setApplicationContext(getApplicationContext());
         LauncherAppState app = LauncherAppState.getInstance();
-        LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);
 
         // Load configuration-specific DeviceProfile
         mDeviceProfile = getResources().getConfiguration().orientation
@@ -457,7 +441,7 @@ public class Launcher extends Activity
 
         mDragController = new DragController(this);
         mInflater = getLayoutInflater();
-        mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);
+        mStateTransitionAnimation = new LauncherStateTransitionAnimation(this);
 
         mStats = new Stats(this);
 
@@ -481,8 +465,6 @@ public class Launcher extends Activity
         setupViews();
         mDeviceProfile.layout(this);
 
-        registerContentObservers();
-
         lockAllApps();
 
         mSavedState = savedInstanceState;
@@ -562,59 +544,45 @@ public class Launcher extends Activity
 
     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
         mLauncherCallbacks = callbacks;
-        mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {
-            @Override
-            public void onAllAppsBoundsChanged(Rect bounds) {
-                if (LOGD) {
-                    Log.d(TAG, "onAllAppsBoundsChanged(Rect): " + bounds);
-                }
-                mAppsView.setFixedBounds(bounds);
-                mWidgetsView.setFixedBounds(bounds);
-            }
-
-            @Override
-            public void dismissAllApps() {
-                if (!DISABLE_ALL_APPS_SEARCH_INTEGRATION) {
-                    // Dismiss All Apps if we aren't already paused/invisible
-                    if (!mPaused) {
-                        showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true,
-                                null /* onCompleteRunnable */, false /* notifyLauncherCallbacks */);
-                    }
-                }
-            }
-
-            @Override
-            public void setSearchManager(AppSearchManager manager) {
-                mAppsView.setSearchManager(manager);
-            }
-        });
         mLauncherCallbacks.setLauncherSearchCallback(new Launcher.LauncherSearchCallbacks() {
-            private boolean mImportanceStored = false;
+            private boolean mWorkspaceImportanceStored = false;
+            private boolean mHotseatImportanceStored = false;
             private int mWorkspaceImportanceForAccessibility =
                 View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
             private int mHotseatImportanceForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
 
             @Override
             public void onSearchOverlayOpened() {
-                if (mImportanceStored) {
+                if (mWorkspaceImportanceStored || mHotseatImportanceStored) {
                     return;
                 }
                 // The underlying workspace and hotseat are temporarily suppressed by the search
                 // overlay. So they sholudn't be accessible.
-                mWorkspaceImportanceForAccessibility = mWorkspace.getImportantForAccessibility();
-                mHotseatImportanceForAccessibility = mHotseat.getImportantForAccessibility();
-                mWorkspace.setImportantForAccessibility(
-                    View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
-                mHotseat.setImportantForAccessibility(
-                    View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
-                mImportanceStored = true;
+                if (mWorkspace != null) {
+                    mWorkspaceImportanceForAccessibility =
+                            mWorkspace.getImportantForAccessibility();
+                    mWorkspace.setImportantForAccessibility(
+                            View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+                    mWorkspaceImportanceStored = true;
+                }
+                if (mHotseat != null) {
+                    mHotseatImportanceForAccessibility = mHotseat.getImportantForAccessibility();
+                    mHotseat.setImportantForAccessibility(
+                            View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+                    mHotseatImportanceStored = true;
+                }
             }
 
             @Override
             public void onSearchOverlayClosed() {
-                mWorkspace.setImportantForAccessibility(mWorkspaceImportanceForAccessibility);
-                mHotseat.setImportantForAccessibility(mHotseatImportanceForAccessibility);
-                mImportanceStored = false;
+                if (mWorkspaceImportanceStored && mWorkspace != null) {
+                    mWorkspace.setImportantForAccessibility(mWorkspaceImportanceForAccessibility);
+                }
+                if (mHotseatImportanceStored && mHotseat != null) {
+                    mHotseat.setImportantForAccessibility(mHotseatImportanceForAccessibility);
+                }
+                mWorkspaceImportanceStored = false;
+                mHotseatImportanceStored = false;
             }
         });
         return true;
@@ -627,6 +595,14 @@ public class Launcher extends Activity
         }
     }
 
+    /**
+     * Updates the bounds of all the overlays to match the new fixed bounds.
+     */
+    public void updateOverlayBounds(Rect newBounds) {
+        mAppsView.setSearchBarBounds(newBounds);
+        mWidgetsView.setSearchBarBounds(newBounds);
+    }
+
     /** To be overridden by subclasses to hint to Launcher that we have custom content */
     protected boolean hasCustomContentToLeft() {
         if (mLauncherCallbacks != null) {
@@ -676,12 +652,12 @@ public class Launcher extends Activity
     public boolean isDraggingEnabled() {
         // We prevent dragging when we are loading the workspace as it is possible to pick up a view
         // that is subsequently removed from the workspace in startBinding().
-        return !mModel.isLoadingWorkspace();
+        return !isWorkspaceLoading();
     }
 
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public static int generateViewId() {
-        if (Build.VERSION.SDK_INT >= 17) {
+        if (Utilities.ATLEAST_JB_MR1) {
             return View.generateViewId();
         } else {
             // View.generateViewId() is not available. The following fallback logic is a copy
@@ -700,7 +676,10 @@ public class Launcher extends Activity
 
     public int getViewIdForItem(ItemInfo info) {
         // This cast is safe given the > 2B range for int.
-        int itemId = (int) info.id;
+        return getViewIdForItemId((int) info.id);
+    }
+
+    public int getViewIdForItemId(int itemId) {
         if (mItemIdToViewId.containsKey(itemId)) {
             return mItemIdToViewId.get(itemId);
         }
@@ -756,6 +735,7 @@ public class Launcher extends Activity
         };
 
         if (requestCode == REQUEST_BIND_APPWIDGET) {
+            // This is called only if the user did not previously have permissions to bind widgets
             final int appWidgetId = data != null ?
                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;
             if (resultCode == RESULT_CANCELED) {
@@ -765,6 +745,10 @@ public class Launcher extends Activity
             } else if (resultCode == RESULT_OK) {
                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,
                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);
+
+                // When the user has granted permission to bind widgets, we should check to see if
+                // we can inflate the default search bar widget.
+                getOrCreateQsbBar();
             }
             return;
         } else if (requestCode == REQUEST_PICK_WALLPAPER) {
@@ -885,6 +869,15 @@ public class Launcher extends Activity
         }
     }
 
+    /** @Override for MNC */
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onRequestPermissionsResult(requestCode, permissions,
+                    grantResults);
+        }
+    }
+
     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int
             appWidgetId, ItemInfo info) {
         PendingAddArguments args = new PendingAddArguments();
@@ -995,22 +988,12 @@ public class Launcher extends Activity
             // view after launching an app, as they may be depending on the UI to be static to
             // switch to another app, otherwise, if it was
             showAppsView(false /* animated */, false /* resetListToTop */,
-                    !launchedFromApp /* updatePredictedApps */);
+                    !launchedFromApp /* updatePredictedApps */, false /* focusSearchBar */);
         } else if (mOnResumeState == State.WIDGETS) {
             showWidgetsView(false, false);
         }
         mOnResumeState = State.NONE;
 
-        // Restore the apps state if we are in all apps
-        if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {
-            // Otherwise, notify the callbacks if we are in all apps mode
-            if (mState == State.APPS) {
-                if (mLauncherCallbacks != null) {
-                    mLauncherCallbacks.onAllAppsShown();
-                }
-            }
-        }
-
         // Background was set to gradient in onPause(), restore to transparent if in all apps.
         setWorkspaceBackground(mState == State.WORKSPACE ? WORKSPACE_BACKGROUND_GRADIENT
                 : WORKSPACE_BACKGROUND_TRANSPARENT);
@@ -1018,6 +1001,12 @@ public class Launcher extends Activity
         mPaused = false;
         if (mRestoring || mOnResumeNeedsLoad) {
             setWorkspaceLoading(true);
+
+            // If we're starting binding all over again, clear any bind calls we'd postponed in
+            // the past (see waitUntilResume) -- we don't need them since we're starting binding
+            // from scratch again
+            mBindOnResumeCallbacks.clear();
+
             mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);
             mRestoring = false;
             mOnResumeNeedsLoad = false;
@@ -1151,24 +1140,6 @@ public class Launcher extends Activity
         public void forceExitFullImmersion();
     }
 
-    public interface LauncherAppsCallbacks {
-        /**
-         * Updates launcher to the available space that AllApps can take so as not to overlap with
-         * any other views.
-         */
-        public void onAllAppsBoundsChanged(Rect bounds);
-
-        /**
-         * Called to dismiss all apps if it is showing.
-         */
-        public void dismissAllApps();
-
-        /**
-         * Sets the search manager to be used for app search.
-         */
-        public void setSearchManager(AppSearchManager manager);
-    }
-
     public interface LauncherSearchCallbacks {
         /**
          * Called when the search overlay is shown.
@@ -1403,8 +1374,8 @@ public class Launcher extends Activity
         }
 
         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
-        View widgetButton = findViewById(R.id.widget_button);
-        widgetButton.setOnClickListener(new OnClickListener() {
+        mWidgetsButton = findViewById(R.id.widget_button);
+        mWidgetsButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
                 if (!mWorkspace.isSwitchingState()) {
@@ -1412,7 +1383,7 @@ public class Launcher extends Activity
                 }
             }
         });
-        widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());
+        mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());
 
         View wallpaperButton = findViewById(R.id.wallpaper_button);
         wallpaperButton.setOnClickListener(new OnClickListener() {
@@ -1452,14 +1423,14 @@ public class Launcher extends Activity
         mSearchDropTargetBar = (SearchDropTargetBar)
                 mDragLayer.findViewById(R.id.search_drop_target_bar);
 
-        // Setup Apps
+        // Setup Apps and Widgets
         mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
-        if (isAllAppsSearchOverridden()) {
-            mAppsView.hideHeaderBar();
-        }
-
-        // Setup AppsCustomize
         mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);
+        if (mLauncherCallbacks != null && mLauncherCallbacks.getAllAppsSearchBarController() != null) {
+            mAppsView.setSearchBarController(mLauncherCallbacks.getAllAppsSearchBarController());
+        } else {
+            mAppsView.setSearchBarController(mAppsView.newDefaultAppSearchController());
+        }
 
         // Setup the drag controller (drop targets have to be added in reverse order in priority)
         dragController.setDragScoller(mWorkspace);
@@ -1498,6 +1469,10 @@ public class Launcher extends Activity
         return mAllAppsButton;
     }
 
+    public View getWidgetsButton() {
+        return mWidgetsButton;
+    }
+
     /**
      * Creates a view representing a shortcut.
      *
@@ -1581,23 +1556,6 @@ public class Launcher extends Activity
         }
     }
 
-    private int[] getSpanForWidget(ComponentName component, int minWidth, int minHeight) {
-        Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(this, component, null);
-        // We want to account for the extra amount of padding that we are adding to the widget
-        // to ensure that it gets the full amount of space that it has requested
-        int requiredWidth = minWidth + padding.left + padding.right;
-        int requiredHeight = minHeight + padding.top + padding.bottom;
-        return CellLayout.rectToCell(this, requiredWidth, requiredHeight, null);
-    }
-
-    public int[] getSpanForWidget(AppWidgetProviderInfo info) {
-        return getSpanForWidget(info.provider, info.minWidth, info.minHeight);
-    }
-
-    public int[] getMinSpanForWidget(AppWidgetProviderInfo info) {
-        return getSpanForWidget(info.provider, info.minResizeWidth, info.minResizeHeight);
-    }
-
     /**
      * Add a widget to the workspace.
      *
@@ -1694,18 +1652,18 @@ public class Launcher extends Activity
         }
         registerReceiver(mReceiver, filter);
         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());
-        setupTransparentSystemBarsForLmp();
+        setupTransparentSystemBarsForLollipop();
         mAttached = true;
         mVisible = true;
     }
 
     /**
-     * Sets up transparent navigation and status bars in LMP.
+     * Sets up transparent navigation and status bars in Lollipop.
      * This method is a no-op for other platform versions.
      */
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-    private void setupTransparentSystemBarsForLmp() {
-        if (Utilities.isLmpOrAbove()) {
+    private void setupTransparentSystemBarsForLollipop() {
+        if (Utilities.ATLEAST_LOLLIPOP) {
             Window window = getWindow();
             window.getAttributes().systemUiVisibility |=
                     (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
@@ -1872,7 +1830,7 @@ public class Launcher extends Activity
         return mOverviewPanel;
     }
 
-    public SearchDropTargetBar getSearchBar() {
+    public SearchDropTargetBar getSearchDropTargetBar() {
         return mSearchDropTargetBar;
     }
 
@@ -1908,29 +1866,22 @@ public class Launcher extends Activity
         super.onNewIntent(intent);
 
         // Close the menu
-        if (Intent.ACTION_MAIN.equals(intent.getAction())) {
+        Folder openFolder = mWorkspace.getOpenFolder();
+        boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &
+                Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
+                != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
+        boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
+        if (isActionMain) {
             // also will cancel mWaitingForResult.
             closeSystemDialogs();
 
-            final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &
-                    Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
-                    != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
-
             if (mWorkspace == null) {
                 // Can be cases where mWorkspace is null, this prevents a NPE
                 return;
             }
-            Folder openFolder = mWorkspace.getOpenFolder();
             // In all these cases, only animate if we're already on home
             mWorkspace.exitWidgetResizeMode();
 
-            boolean moveToDefaultScreen = mLauncherCallbacks != null ?
-                    mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
-            if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
-                    openFolder == null && moveToDefaultScreen) {
-                mWorkspace.moveToDefaultScreen(true);
-            }
-
             closeFolder();
             exitSpringLoadedDragMode();
 
@@ -1964,13 +1915,30 @@ public class Launcher extends Activity
             }
         }
 
-        if (DEBUG_RESUME_TIME) {
-            Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
-        }
-
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onNewIntent(intent);
         }
+
+        // Defer moving to the default screen until after we callback to the LauncherCallbacks
+        // as slow logic in the callbacks eat into the time the scroller expects for the snapToPage
+        // animation.
+        if (isActionMain) {
+            boolean moveToDefaultScreen = mLauncherCallbacks != null ?
+                    mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
+            if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
+                    openFolder == null && moveToDefaultScreen) {
+                mWorkspace.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mWorkspace.moveToDefaultScreen(true);
+                    }
+                });
+            }
+        }
+
+        if (DEBUG_RESUME_TIME) {
+            Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
+        }
     }
 
     @Override
@@ -2045,7 +2013,6 @@ public class Launcher extends Activity
 
         TextKeyListener.getInstance().release();
 
-        getContentResolver().unregisterContentObserver(mWidgetObserver);
         unregisterReceiver(mCloseSystemDialogsReceiver);
 
         mDragLayer.clearAllResizeFrames();
@@ -2179,6 +2146,15 @@ public class Launcher extends Activity
         }
     }
 
+    public void startSearchFromAllApps(View v, Intent searchIntent, String searchQuery) {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.startSearchFromAllApps(searchQuery)) {
+            return;
+        }
+
+        // If not handled, then just start the provided search intent
+        startActivitySafely(v, searchIntent, null);
+    }
+
     public boolean isOnCustomContent() {
         return mWorkspace.isOnOrMovingToCustomContent();
     }
@@ -2247,7 +2223,7 @@ public class Launcher extends Activity
         mPendingAddInfo.screenId = -1;
         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;
         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;
-        mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;
+        mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = 1;
         mPendingAddInfo.dropPos = null;
     }
 
@@ -2414,16 +2390,6 @@ public class Launcher extends Activity
         sFolders.remove(folder.id);
     }
 
-    /**
-     * Registers various content observers. The current implementation registers
-     * only a favorites observer to keep track of the favorites applications.
-     */
-    private void registerContentObservers() {
-        ContentResolver resolver = getContentResolver();
-        resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,
-                true, mWidgetObserver);
-    }
-
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
@@ -2480,9 +2446,10 @@ public class Launcher extends Activity
     }
 
     /**
-     * Re-listen when widgets are reset.
+     * Re-listen when widget host is reset.
      */
-    @Thunk void onAppWidgetReset() {
+    @Override
+    public void onAppWidgetHostReset() {
         if (mAppWidgetHost != null) {
             mAppWidgetHost.startListening();
         }
@@ -2586,12 +2553,21 @@ public class Launcher extends Activity
      */
     protected void onClickAllAppsButton(View v) {
         if (LOGD) Log.d(TAG, "onClickAllAppsButton");
-        if (isAppsViewVisible()) {
-            showWorkspace(true);
-        } else {
-            // Try and refresh the set of predicted apps before we enter launcher
+        if (!isAppsViewVisible()) {
+            showAppsView(true /* animated */, false /* resetListToTop */,
+                    true /* updatePredictedApps */, false /* focusSearchBar */);
+
+            if (mLauncherCallbacks != null) {
+                mLauncherCallbacks.onClickAllAppsButton(v);
+            }
+        }
+    }
+
+    protected void onLongClickAllAppsButton(View v) {
+        if (LOGD) Log.d(TAG, "onLongClickAllAppsButton");
+        if (!isAppsViewVisible()) {
             showAppsView(true /* animated */, false /* resetListToTop */,
-                    true /* updatePredictedApps */);
+                    true /* updatePredictedApps */, true /* focusSearchBar */);
         }
     }
 
@@ -2712,6 +2688,7 @@ public class Launcher extends Activity
             throw new IllegalArgumentException("Input must be a FolderIcon");
         }
 
+        // TODO(sunnygoyal): Re-evaluate this code.
         FolderIcon folderIcon = (FolderIcon) v;
         final FolderInfo info = folderIcon.getFolderInfo();
         Folder openFolder = mWorkspace.getFolderForTag(info);
@@ -2850,17 +2827,8 @@ public class Launcher extends Activity
     public void updateInteraction(Workspace.State fromState, Workspace.State toState) {
         // Only update the interacting state if we are transitioning to/from a view with an
         // overlay
-        boolean fromStateWithOverlay;
-        boolean toStateWithOverlay;
-        if (Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {
-            fromStateWithOverlay = fromState != Workspace.State.NORMAL;
-            toStateWithOverlay = toState != Workspace.State.NORMAL;
-        } else {
-            fromStateWithOverlay = fromState != Workspace.State.NORMAL &&
-                    fromState != Workspace.State.NORMAL_HIDDEN;
-            toStateWithOverlay = toState != Workspace.State.NORMAL &&
-                    toState != Workspace.State.NORMAL_HIDDEN;
-        }
+        boolean fromStateWithOverlay = fromState != Workspace.State.NORMAL;
+        boolean toStateWithOverlay = toState != Workspace.State.NORMAL;
         if (toStateWithOverlay) {
             onInteractionBegin();
         } else if (fromStateWithOverlay) {
@@ -2924,8 +2892,7 @@ public class Launcher extends Activity
             Bundle optsBundle = null;
             if (useLaunchAnimation) {
                 ActivityOptions opts = null;
-                if (sClipRevealMethod != null) {
-                    // TODO: call method directly when Launcher3 can depend on M APIs
+                if (Utilities.ATLEAST_MARSHMALLOW) {
                     int left = 0, top = 0;
                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
                     if (v instanceof TextView) {
@@ -2939,20 +2906,17 @@ public class Launcher extends Activity
                             height = bounds.height();
                         }
                     }
-                    try {
-                        opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,
-                                left, top, width, height);
-                    } catch (IllegalAccessException e) {
-                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);
-                        sClipRevealMethod = null;
-                    } catch (InvocationTargetException e) {
-                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);
-                        sClipRevealMethod = null;
-                    }
-                }
-                if (opts == null && !Utilities.isLmpOrAbove()) {
+                    opts = ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
+                } else if (!Utilities.ATLEAST_LOLLIPOP) {
+                    // Below L, we use a scale up animation
                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                                     v.getMeasuredWidth(), v.getMeasuredHeight());
+                } else if (Utilities.ATLEAST_LOLLIPOP_MR1) {
+                    // On L devices, we use the device default slide-up transition.
+                    // On L MR1 devices, we a custom version of the slide-up transition which
+                    // doesn't have the delay present in the device default.
+                    opts = ActivityOptions.makeCustomAnimation(this,
+                            R.anim.task_open_enter, R.anim.no_anim);
                 }
                 optsBundle = opts != null ? opts.toBundle() : null;
             }
@@ -2976,7 +2940,7 @@ public class Launcher extends Activity
         return false;
     }
 
-    private boolean startActivitySafely(View v, Intent intent, Object tag) {
+    public boolean startActivitySafely(View v, Intent intent, Object tag) {
         boolean success = false;
         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {
             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
@@ -3062,7 +3026,7 @@ public class Launcher extends Activity
 
         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,
                 scaleX, scaleY);
-        if (Utilities.isLmpOrAbove()) {
+        if (Utilities.ATLEAST_LOLLIPOP) {
             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));
         }
         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));
@@ -3170,6 +3134,11 @@ public class Launcher extends Activity
         if (isWorkspaceLocked()) return false;
         if (mState != State.WORKSPACE) return false;
 
+        if (v == mAllAppsButton) {
+            onLongClickAllAppsButton(v);
+            return true;
+        }
+
         if (v instanceof Workspace) {
             if (!mWorkspace.isInOverviewMode()) {
                 if (!mWorkspace.isTouchActive()) {
@@ -3295,43 +3264,26 @@ public class Launcher extends Activity
         }
     }
 
-    @Override
-    public void onStateTransitionHideSearchBar() {
-        // Hide the search bar
-        if (mSearchDropTargetBar != null) {
-            mSearchDropTargetBar.hideSearchBar(false /* animated */);
-        }
-    }
-
     public void showWorkspace(boolean animated) {
-        showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null,
-                true);
+        showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated, null);
     }
 
     public void showWorkspace(boolean animated, Runnable onCompleteRunnable) {
         showWorkspace(WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,
-                onCompleteRunnable, true);
+                onCompleteRunnable);
     }
 
     protected void showWorkspace(int snapToPage, boolean animated) {
-        showWorkspace(snapToPage, animated, null, true);
+        showWorkspace(snapToPage, animated, null);
     }
 
-    void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable,
-            boolean notifyLauncherCallbacks) {
+    void showWorkspace(int snapToPage, boolean animated, Runnable onCompleteRunnable) {
         boolean changed = mState != State.WORKSPACE ||
                 mWorkspace.getState() != Workspace.State.NORMAL;
         if (changed) {
-            boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);
             mWorkspace.setVisibility(View.VISIBLE);
-            mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,
-                    snapToPage, animated, onCompleteRunnable);
-
-            // Show the search bar (only animate if we were showing the drop target bar in spring
-            // loaded mode)
-            if (mSearchDropTargetBar != null) {
-                mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);
-            }
+            mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(),
+                    Workspace.State.NORMAL, snapToPage, animated, onCompleteRunnable);
 
             // Set focus to the AppsCustomize button
             if (mAllAppsButton != null) {
@@ -3350,18 +3302,13 @@ public class Launcher extends Activity
             // Send an accessibility event to announce the context change
             getWindow().getDecorView()
                     .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-            if (notifyLauncherCallbacks) {
-                // Dismiss all apps when the workspace is shown
-                if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {
-                    mLauncherCallbacks.onAllAppsHidden();
-                }
-            }
         }
     }
 
     void showOverviewMode(boolean animated) {
         mWorkspace.setVisibility(View.VISIBLE);
-        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,
+        mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(),
+                Workspace.State.OVERVIEW,
                 WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, animated,
                 null /* onCompleteRunnable */);
         mState = State.WORKSPACE;
@@ -3370,14 +3317,15 @@ public class Launcher extends Activity
     /**
      * Shows the apps view.
      */
-    void showAppsView(boolean animated, boolean resetListToTop, boolean updatePredictedApps) {
+    void showAppsView(boolean animated, boolean resetListToTop, boolean updatePredictedApps,
+            boolean focusSearchBar) {
         if (resetListToTop) {
             mAppsView.scrollToTop();
         }
         if (updatePredictedApps) {
             tryAndUpdatePredictedApps();
         }
-        showAppsOrWidgets(animated, State.APPS);
+        showAppsOrWidgets(State.APPS, animated, focusSearchBar);
     }
 
     /**
@@ -3388,7 +3336,7 @@ public class Launcher extends Activity
         if (resetPageToZero) {
             mWidgetsView.scrollToTop();
         }
-        showAppsOrWidgets(animated, State.WIDGETS);
+        showAppsOrWidgets(State.WIDGETS, animated, false);
 
         mWidgetsView.post(new Runnable() {
             @Override
@@ -3405,7 +3353,7 @@ public class Launcher extends Activity
      */
     // TODO: calling method should use the return value so that when {@code false} is returned
     // the workspace transition doesn't fall into invalid state.
-    private boolean showAppsOrWidgets(boolean animated, State toState) {
+    private boolean showAppsOrWidgets(State toState, boolean animated, boolean focusSearchBar) {
         if (mState != State.WORKSPACE &&  mState != State.APPS_SPRING_LOADED &&
                 mState != State.WIDGETS_SPRING_LOADED) {
             return false;
@@ -3415,12 +3363,10 @@ public class Launcher extends Activity
         }
 
         if (toState == State.APPS) {
-            mStateTransitionAnimation.startAnimationToAllApps(animated);
-            if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {
-                mLauncherCallbacks.onAllAppsShown();
-            }
+            mStateTransitionAnimation.startAnimationToAllApps(mWorkspace.getState(), animated,
+                    focusSearchBar);
         } else {
-            mStateTransitionAnimation.startAnimationToWidgets(animated);
+            mStateTransitionAnimation.startAnimationToWidgets(mWorkspace.getState(), animated);
         }
 
         // Change the state *after* we've called all the transition code
@@ -3456,7 +3402,8 @@ public class Launcher extends Activity
             return;
         }
 
-        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,
+        mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(),
+                Workspace.State.SPRING_LOADED,
                 WorkspaceStateTransitionAnimation.SCROLL_TO_CURRENT_PAGE, true /* animated */,
                 null /* onCompleteRunnable */);
         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;
@@ -3466,14 +3413,6 @@ public class Launcher extends Activity
             final Runnable onCompleteRunnable) {
         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;
 
-        if (successfulDrop) {
-            // We need to trigger all apps hidden to notify search to update itself before the
-            // delayed call to showWorkspace below
-            if (!Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION && mLauncherCallbacks != null) {
-                mLauncherCallbacks.onAllAppsHidden();
-            }
-        }
-
         mHandler.postDelayed(new Runnable() {
             @Override
             public void run() {
@@ -3495,7 +3434,7 @@ public class Launcher extends Activity
     void exitSpringLoadedDragMode() {
         if (mState == State.APPS_SPRING_LOADED) {
             showAppsView(true /* animated */, false /* resetListToTop */,
-                    false /* updatePredictedApps */);
+                    false /* updatePredictedApps */, false /* focusSearchBar */);
         } else if (mState == State.WIDGETS_SPRING_LOADED) {
             showWidgetsView(true, false);
         }
@@ -3507,8 +3446,8 @@ public class Launcher extends Activity
      */
     private void tryAndUpdatePredictedApps() {
         if (mLauncherCallbacks != null) {
-            List<ComponentName> apps = mLauncherCallbacks.getPredictedApps();
-            if (!apps.isEmpty()) {
+            List<ComponentKey> apps = mLauncherCallbacks.getPredictedApps();
+            if (apps != null) {
                 mAppsView.setPredictedApps(apps);
             }
         }
@@ -3570,10 +3509,12 @@ public class Launcher extends Activity
                     .commit();
             }
 
+            mAppWidgetHost.setQsbWidgetId(widgetId);
             if (widgetId != -1) {
                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);
                 mQsb.updateAppWidgetOptions(opts);
                 mQsb.setPadding(0, 0, 0, 0);
+                mQsb.setId(getViewIdForItemId(QSB_ITEM_ID));
                 mSearchDropTargetBar.addView(mQsb);
                 mSearchDropTargetBar.setQsbSearchBar(mQsb);
             }
@@ -3600,6 +3541,8 @@ public class Launcher extends Activity
             text.add(getString(R.string.all_apps_button_label));
         } else if (mState == State.WIDGETS) {
             text.add(getString(R.string.widget_button_text));
+        } else if (mWorkspace != null) {
+            text.add(mWorkspace.getCurrentPageDescription());
         } else {
             text.add(getString(R.string.all_apps_home_button_label));
         }
@@ -3617,20 +3560,6 @@ public class Launcher extends Activity
     }
 
     /**
-     * Receives notifications whenever the appwidgets are reset.
-     */
-    private class AppWidgetResetObserver extends ContentObserver {
-        public AppWidgetResetObserver() {
-            super(new Handler());
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            onAppWidgetReset();
-        }
-    }
-
-    /**
      * If the activity is currently paused, signal that we need to run the passed Runnable
      * in onResume.
      *
@@ -3840,11 +3769,12 @@ public class Launcher extends Activity
                 continue;
             }
 
+            final View view;
             switch (item.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                     ShortcutInfo info = (ShortcutInfo) item;
-                    View shortcut = createShortcut(info);
+                    view = createShortcut(info);
 
                     /*
                      * TODO: FIX collision case
@@ -3863,28 +3793,26 @@ public class Launcher extends Activity
                             }
                         }
                     }
-
-                    workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,
-                            item.cellY, 1, 1);
-                    if (animateIcons) {
-                        // Animate all the applications up now
-                        shortcut.setAlpha(0f);
-                        shortcut.setScaleX(0f);
-                        shortcut.setScaleY(0f);
-                        bounceAnims.add(createNewAppBounceAnimation(shortcut, i));
-                        newShortcutsScreenId = item.screenId;
-                    }
                     break;
                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
-                    FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
+                    view = FolderIcon.fromXml(R.layout.folder_icon, this,
                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
                             (FolderInfo) item, mIconCache);
-                    workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,
-                            item.cellY, 1, 1);
                     break;
                 default:
                     throw new RuntimeException("Invalid Item Type");
             }
+
+            workspace.addInScreenFromBind(view, item.container, item.screenId, item.cellX,
+                    item.cellY, 1, 1);
+            if (animateIcons) {
+                // Animate all the applications up now
+                view.setAlpha(0f);
+                view.setScaleX(0f);
+                view.setScaleY(0f);
+                bounceAnims.add(createNewAppBounceAnimation(view, i));
+                newShortcutsScreenId = item.screenId;
+            }
         }
 
         if (animateIcons) {
@@ -3959,7 +3887,8 @@ public class Launcher extends Activity
 
         if (!mIsSafeModeEnabled
                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)
-                && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {
+                && (item.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED)) {
+
             if (appWidgetInfo == null) {
                 if (DEBUG_WIDGETS) {
                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
@@ -3969,42 +3898,51 @@ public class Launcher extends Activity
                 LauncherModel.deleteItemFromDatabase(this, item);
                 return;
             }
-            // Note: This assumes that the id remap broadcast is received before this step.
-            // If that is not the case, the id remap will be ignored and user may see the
-            // click to setup view.
-            PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo, null);
-            pendingInfo.spanX = item.spanX;
-            pendingInfo.spanY = item.spanY;
-            pendingInfo.minSpanX = item.minSpanX;
-            pendingInfo.minSpanY = item.minSpanY;
-            Bundle options = null;
-                    WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
-
-            int newWidgetId = mAppWidgetHost.allocateAppWidgetId();
-            boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
-                    newWidgetId, appWidgetInfo, options);
 
-            // TODO consider showing a permission dialog when the widget is clicked.
-            if (!success) {
-                mAppWidgetHost.deleteAppWidgetId(newWidgetId);
-                if (DEBUG_WIDGETS) {
-                    Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
-                            + " belongs to component " + item.providerName
-                            + ", as the launcher is unable to bing a new widget id");
+            // If we do not have a valid id, try to bind an id.
+            if ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0) {
+                // Note: This assumes that the id remap broadcast is received before this step.
+                // If that is not the case, the id remap will be ignored and user may see the
+                // click to setup view.
+                PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo, null);
+                pendingInfo.spanX = item.spanX;
+                pendingInfo.spanY = item.spanY;
+                pendingInfo.minSpanX = item.minSpanX;
+                pendingInfo.minSpanY = item.minSpanY;
+                Bundle options = null;
+                        WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
+
+                int newWidgetId = mAppWidgetHost.allocateAppWidgetId();
+                boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
+                        newWidgetId, appWidgetInfo, options);
+
+                // TODO consider showing a permission dialog when the widget is clicked.
+                if (!success) {
+                    mAppWidgetHost.deleteAppWidgetId(newWidgetId);
+                    if (DEBUG_WIDGETS) {
+                        Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
+                                + " belongs to component " + item.providerName
+                                + ", as the launcher is unable to bing a new widget id");
+                    }
+                    LauncherModel.deleteItemFromDatabase(this, item);
+                    return;
                 }
-                LauncherModel.deleteItemFromDatabase(this, item);
-                return;
-            }
 
-            item.appWidgetId = newWidgetId;
+                item.appWidgetId = newWidgetId;
 
-            // If the widget has a configure activity, it is still needs to set it up, otherwise
-            // the widget is ready to go.
-            item.restoreStatus = (appWidgetInfo.configure == null)
-                    ? LauncherAppWidgetInfo.RESTORE_COMPLETED
-                    : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
+                // If the widget has a configure activity, it is still needs to set it up, otherwise
+                // the widget is ready to go.
+                item.restoreStatus = (appWidgetInfo.configure == null)
+                        ? LauncherAppWidgetInfo.RESTORE_COMPLETED
+                        : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
 
-            LauncherModel.updateItemInDatabase(this, item);
+                LauncherModel.updateItemInDatabase(this, item);
+            } else if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_UI_NOT_READY) != 0)
+                    && (appWidgetInfo.configure == null)) {
+                // If the ID is already valid, verify if we need to configure or not.
+                item.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
+                LauncherModel.updateItemInDatabase(this, item);
+            }
         }
 
         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
@@ -4015,6 +3953,8 @@ public class Launcher extends Activity
             }
 
             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
+            item.minSpanX = appWidgetInfo.minSpanX;
+            item.minSpanY = appWidgetInfo.minSpanY;
         } else {
             appWidgetInfo = null;
             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,
@@ -4137,7 +4077,8 @@ public class Launcher extends Activity
 
     private boolean canRunNewAppsAnimation() {
         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();
-        return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);
+        return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000)
+                && (mClings == null || !mClings.isVisible());
     }
 
     private ValueAnimator createNewAppBounceAnimation(View v, int i) {
@@ -4159,7 +4100,7 @@ public class Launcher extends Activity
         return mDeviceProfile.getSearchBarBounds(Utilities.isRtl(getResources()));
     }
 
-    public void bindSearchablesChanged() {
+    public void bindSearchProviderChanged() {
         if (mSearchDropTargetBar == null) {
             return;
         }
@@ -4382,13 +4323,14 @@ public class Launcher extends Activity
         return oriMap[(d.getRotation() + indexOffset) % 4];
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
     public void lockScreenOrientation() {
         if (mRotationEnabled) {
-            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            if (Utilities.ATLEAST_JB_MR2) {
+                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
+            } else {
                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()
                         .getConfiguration().orientation));
-            } else {
-                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
             }
         }
     }
@@ -4457,20 +4399,6 @@ public class Launcher extends Activity
         return null;
     }
 
-    /**
-     * Returns whether the launcher callbacks overrides search in all apps.
-     */
-    @Thunk boolean isAllAppsSearchOverridden() {
-        if (DISABLE_ALL_APPS_SEARCH_INTEGRATION) {
-            return false;
-        }
-
-        if (mLauncherCallbacks != null) {
-            return mLauncherCallbacks.overrideAllAppsSearch();
-        }
-        return false;
-    }
-
     private boolean shouldRunFirstRunActivity() {
         return !ActivityManager.isRunningInTestHarness() &&
                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);
@@ -4577,6 +4505,7 @@ public class Launcher extends Activity
         // launcher2). Otherwise, we prompt the user upon started for migration
         LauncherClings launcherClings = new LauncherClings(this);
         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {
+            mClings = launcherClings;
             if (mModel.canMigrateFromOldLauncherDb(this)) {
                 launcherClings.showMigrationCling();
             } else {
@@ -4589,52 +4518,66 @@ public class Launcher extends Activity
         if (mWorkspace != null) mWorkspace.setAlpha(1f);
         if (mHotseat != null) mHotseat.setAlpha(1f);
         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);
-        if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);
+        if (mSearchDropTargetBar != null) mSearchDropTargetBar.animateToState(
+                SearchDropTargetBar.State.SEARCH_BAR, 0);
     }
 
     void hideWorkspaceSearchAndHotseat() {
         if (mWorkspace != null) mWorkspace.setAlpha(0f);
         if (mHotseat != null) mHotseat.setAlpha(0f);
         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);
-        if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);
+        if (mSearchDropTargetBar != null) mSearchDropTargetBar.animateToState(
+                SearchDropTargetBar.State.INVISIBLE, 0);
     }
 
+    // TODO: These method should be a part of LauncherSearchCallback
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {
-        // Called from search suggestion, not supported in other profiles.
-        final UserHandleCompat myUser = UserHandleCompat.myUserHandle();
+        // Called from search suggestion
+        UserHandleCompat user = null;
+        if (Utilities.ATLEAST_LOLLIPOP) {
+            UserHandle userHandle = appLaunchIntent.getParcelableExtra(Intent.EXTRA_USER);
+            if (userHandle != null) {
+                user = UserHandleCompat.fromUser(userHandle);
+            }
+        }
+        return createAppDragInfo(appLaunchIntent, user);
+    }
+
+    // TODO: This method should be a part of LauncherSearchCallback
+    public ItemInfo createAppDragInfo(Intent intent, UserHandleCompat user) {
+        if (user == null) {
+            user = UserHandleCompat.myUserHandle();
+        }
+
+        // Called from search suggestion, add the profile extra to the intent to ensure that we
+        // can launch it correctly
         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);
-        LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,
-                myUser);
+        LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(intent, user);
         if (activityInfo == null) {
             return null;
         }
-        return new AppInfo(this, activityInfo, myUser, mIconCache);
+        return new AppInfo(this, activityInfo, user, mIconCache);
     }
 
+    // TODO: This method should be a part of LauncherSearchCallback
     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,
             Bitmap icon) {
-        // Called from search suggestion, not supported in other profiles.
-        return createShortcutDragInfo(shortcutIntent, caption, icon,
+        return new ShortcutInfo(shortcutIntent, caption, caption, icon,
                 UserHandleCompat.myUserHandle());
     }
 
-    public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,
-            Bitmap icon, UserHandleCompat user) {
-        UserManagerCompat userManager = UserManagerCompat.getInstance(this);
-        CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);
-        return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);
-    }
-
-    protected void moveWorkspaceToDefaultScreen() {
-        mWorkspace.moveToDefaultScreen(false);
-    }
-
+    // TODO: This method should be a part of LauncherSearchCallback
     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {
         dragView.setTag(dragInfo);
         mWorkspace.onExternalDragStartedWithItem(dragView);
         mWorkspace.beginExternalDragShared(dragView, source);
     }
 
+    protected void moveWorkspaceToDefaultScreen() {
+        mWorkspace.moveToDefaultScreen(false);
+    }
+
     @Override
     public void onPageSwitch(View newPage, int newPageIndex) {
         if (mLauncherCallbacks != null) {