Merge "Enabling translation for preference string" into ub-launcher3-burnaby
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 77c4540..b70d6d0 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -3427,7 +3427,7 @@
     private void tryAndUpdatePredictedApps() {
         if (mLauncherCallbacks != null) {
             List<ComponentKey> apps = mLauncherCallbacks.getPredictedApps();
-            if (!apps.isEmpty()) {
+            if (apps != null) {
                 mAppsView.setPredictedApps(apps);
             }
         }
@@ -4490,42 +4490,63 @@
         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);
     }
 
+    // TODO: These method should be a part of LauncherSearchCallback
     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {
-        // Called from search suggestion, not supported in other profiles.
-        final UserHandleCompat myUser = UserHandleCompat.myUserHandle();
+        // Called from search suggestion
+        return createAppDragInfo(appLaunchIntent, UserHandleCompat.myUserHandle());
+    }
+
+    // TODO: This method should be a part of LauncherSearchCallback
+    public ItemInfo createAppDragInfo(Intent appLaunchIntent, 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
+        long serialNumber = UserManagerCompat.getInstance(this).getSerialNumberForUser(user);
+        appLaunchIntent.putExtra(AppInfo.EXTRA_PROFILE, serialNumber);
         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);
         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,
-                myUser);
+                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.
+        // Called from search suggestion
         return createShortcutDragInfo(shortcutIntent, caption, icon,
                 UserHandleCompat.myUserHandle());
     }
 
+    // TODO: This method should be a part of LauncherSearchCallback
     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,
             Bitmap icon, UserHandleCompat user) {
+        if (user == null) {
+            user = UserHandleCompat.myUserHandle();
+        }
+
+        // Called from search suggestion
         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) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 32b7be8..0651fb0 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -417,7 +417,7 @@
                     new SimpleSectionMergeAlgorithm((int) Math.ceil(mNumAppsPerRow / 2f),
                             MIN_ROWS_IN_MERGED_SECTION_PHONE, MAX_NUM_MERGES_PHONE);
 
-            mAppsRecyclerView.setNumAppsPerRow(mNumAppsPerRow);
+            mAppsRecyclerView.setNumAppsPerRow(grid, mNumAppsPerRow);
             mAdapter.setNumAppsPerRow(mNumAppsPerRow);
             mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow, mergeAlgorithm);
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 874e895..988ecdd 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -21,13 +21,11 @@
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
 import android.view.View;
 
 import com.android.launcher3.BaseRecyclerView;
 import com.android.launcher3.BaseRecyclerViewFastScrollBar;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.Stats;
 import com.android.launcher3.util.Thunk;
 
@@ -57,7 +55,6 @@
     private final int mFastScrollMode = FAST_SCROLL_MODE_JUMP_TO_FIRST_ICON;
     private final int mScrollBarMode = FAST_SCROLL_BAR_MODE_DISTRIBUTE_BY_ROW;
 
-    private Launcher mLauncher;
     private ScrollPositionState mScrollPosState = new ScrollPositionState();
 
     public AllAppsRecyclerView(Context context) {
@@ -75,9 +72,6 @@
     public AllAppsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr);
-        // We have a theme on this view, so we need to coerce the base activity context from that
-        ContextThemeWrapper ctx = (ContextThemeWrapper) context;
-        mLauncher = (Launcher) ctx.getBaseContext();
     }
 
     /**
@@ -90,10 +84,9 @@
     /**
      * Sets the number of apps per row in this recycler view.
      */
-    public void setNumAppsPerRow(int numAppsPerRow) {
+    public void setNumAppsPerRow(DeviceProfile grid, int numAppsPerRow) {
         mNumAppsPerRow = numAppsPerRow;
 
-        DeviceProfile grid = mLauncher.getDeviceProfile();
         RecyclerView.RecycledViewPool pool = getRecycledViewPool();
         int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
         pool.setMaxRecycledViews(AllAppsGridAdapter.PREDICTION_BAR_SPACER_TYPE, 1);
diff --git a/src/com/android/launcher3/model/AppNameComparator.java b/src/com/android/launcher3/model/AppNameComparator.java
index cd45d2c..c4b74d4 100644
--- a/src/com/android/launcher3/model/AppNameComparator.java
+++ b/src/com/android/launcher3/model/AppNameComparator.java
@@ -85,8 +85,10 @@
      */
     @Thunk int compareTitles(String titleA, String titleB) {
         // Ensure that we de-prioritize any titles that don't start with a linguistic letter or digit
-        boolean aStartsWithLetter = Character.isLetterOrDigit(titleA.codePointAt(0));
-        boolean bStartsWithLetter = Character.isLetterOrDigit(titleB.codePointAt(0));
+        boolean aStartsWithLetter = (titleA.length() > 0) &&
+                Character.isLetterOrDigit(titleA.codePointAt(0));
+        boolean bStartsWithLetter = (titleB.length() > 0) &&
+                Character.isLetterOrDigit(titleB.codePointAt(0));
         if (aStartsWithLetter && !bStartsWithLetter) {
             return -1;
         } else if (!aStartsWithLetter && bStartsWithLetter) {