Merge "Fixing workspace state issue with option menu." into ub-launcher3-burnaby-polish
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
index cb7090f..a79fb65 100644
--- a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
+++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
@@ -293,22 +293,16 @@
                         roundedTrueCrop.right = roundedTrueCrop.left + fullSize.getWidth();
                     }
                     if (roundedTrueCrop.right > fullSize.getWidth()) {
-                        // Adjust the left value
-                        int adjustment = roundedTrueCrop.left -
-                                Math.max(0, roundedTrueCrop.right - roundedTrueCrop.width());
-                        roundedTrueCrop.left -= adjustment;
-                        roundedTrueCrop.right -= adjustment;
+                        // Adjust the left and right values.
+                        roundedTrueCrop.offset(-(roundedTrueCrop.right - fullSize.getWidth()), 0);
                     }
                     if (roundedTrueCrop.height() > fullSize.getHeight()) {
                         // Adjust the height
                         roundedTrueCrop.bottom = roundedTrueCrop.top + fullSize.getHeight();
                     }
                     if (roundedTrueCrop.bottom > fullSize.getHeight()) {
-                        // Adjust the top value
-                        int adjustment = roundedTrueCrop.top -
-                                Math.max(0, roundedTrueCrop.bottom - roundedTrueCrop.height());
-                        roundedTrueCrop.top -= adjustment;
-                        roundedTrueCrop.bottom -= adjustment;
+                        // Adjust the top and bottom values.
+                        roundedTrueCrop.offset(0, -(roundedTrueCrop.bottom - fullSize.getHeight()));
                     }
 
                     crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 0dbd357..b717b59 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -361,6 +361,9 @@
     protected void cropImageAndSetWallpaper(Uri uri,
             BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler,
             final boolean finishActivityWhenDone, final boolean shouldFadeOutOnFinish) {
+        // Give some feedback so user knows something is happening.
+        mProgressView.setVisibility(View.VISIBLE);
+
         boolean centerCrop = getResources().getBoolean(R.bool.center_crop);
         // Get the crop
         boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 3460555..e13d44c 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -43,12 +43,25 @@
 import java.util.WeakHashMap;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 public class WidgetPreviewLoader {
 
     private static final String TAG = "WidgetPreviewLoader";
     private static final boolean DEBUG = false;
 
+    // These values are same as that in {@link AsyncTask}.
+    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
+    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
+    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
+    private static final int KEEP_ALIVE = 1;
+    private static final Executor PREVIEW_LOAD_EXECUTOR = new ThreadPoolExecutor(
+            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
+            TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
+
     private static final float WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE = 0.25f;
 
     private final HashMap<String, long[]> mPackageVersions = new HashMap<>();
@@ -96,7 +109,7 @@
         WidgetCacheKey key = getObjectKey(o, size);
 
         PreviewLoadTask task = new PreviewLoadTask(key, o, previewWidth, previewHeight, caller);
-        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        task.executeOnExecutor(PREVIEW_LOAD_EXECUTOR);
         return new PreviewLoadRequest(task);
     }
 
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index eef4f91..99a53ff 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -34,19 +34,19 @@
     private static final boolean DEBUG = false;
 
     /* List of packages that is tracked by this model. */
-    private ArrayList<PackageItemInfo> mPackageItemInfos = new ArrayList<>();
+    private final ArrayList<PackageItemInfo> mPackageItemInfos;
 
     /* Map of widgets and shortcuts that are tracked per package. */
-    private HashMap<PackageItemInfo, ArrayList<Object>> mWidgetsList = new HashMap<>();
-
-    private ArrayList<Object> mRawList;
+    private final HashMap<PackageItemInfo, ArrayList<Object>> mWidgetsList;
 
     private final AppWidgetManagerCompat mAppWidgetMgr;
     private final WidgetsAndShortcutNameComparator mWidgetAndShortcutNameComparator;
     private final Comparator<ItemInfo> mAppNameComparator;
     private final IconCache mIconCache;
     private final AppFilter mAppFilter;
-    private AlphabeticIndexCompat mIndexer;
+    private final AlphabeticIndexCompat mIndexer;
+
+    private ArrayList<Object> mRawList;
 
     public WidgetsModel(Context context,  IconCache iconCache, AppFilter appFilter) {
         mAppWidgetMgr = AppWidgetManagerCompat.getInstance(context);
@@ -55,6 +55,10 @@
         mIconCache = iconCache;
         mAppFilter = appFilter;
         mIndexer = new AlphabeticIndexCompat(context);
+        mPackageItemInfos = new ArrayList<>();
+        mWidgetsList = new HashMap<>();
+
+        mRawList = new ArrayList<>();
     }
 
     @SuppressWarnings("unchecked")
@@ -62,18 +66,16 @@
         mAppWidgetMgr = model.mAppWidgetMgr;
         mPackageItemInfos = (ArrayList<PackageItemInfo>) model.mPackageItemInfos.clone();
         mWidgetsList = (HashMap<PackageItemInfo, ArrayList<Object>>) model.mWidgetsList.clone();
-        mRawList = (ArrayList<Object>) model.mRawList.clone();
         mWidgetAndShortcutNameComparator = model.mWidgetAndShortcutNameComparator;
         mAppNameComparator = model.mAppNameComparator;
         mIconCache = model.mIconCache;
         mAppFilter = model.mAppFilter;
+        mIndexer = model.mIndexer;
+        mRawList = (ArrayList<Object>) model.mRawList.clone();
     }
 
     // Access methods that may be deleted if the private fields are made package-private.
     public int getPackageSize() {
-        if (mPackageItemInfos == null) {
-            return 0;
-        }
         return mPackageItemInfos.size();
     }