Fixing ModelPreload cancelling existing load

When a model preload call was made while the loader task is running
(eg: on enabling/disabling icon theme, Launcher reloads and then
launcher preview start a model-preload), it would cancel the original
loader and then start a new loader with empty callbacks. So the
model indeed get loaded, but the original callbacks never got notified
of it.

> Instead we only start preload if an existing task is not running.
> Also when preloading, we use existing callbacks, instead of using
  empty callbacks

Bug: 193851085
Bug: 195155924
Test: Verified repro steps
Change-Id: I0a96310be8489756f364aa2a12e4345e1418733d
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index eef3980..545f4c3 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -72,6 +72,7 @@
 import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 /**
@@ -376,7 +377,13 @@
                     loaderResults.bindWidgets();
                     return true;
                 } else {
-                    startLoaderForResults(loaderResults);
+                    stopLoader();
+                    mLoaderTask = new LoaderTask(
+                            mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);
+
+                    // Always post the loader task, instead of running directly
+                    // (even on same thread) so that we exit any nested synchronized blocks
+                    MODEL_EXECUTOR.post(mLoaderTask);
                 }
             }
         }
@@ -399,25 +406,17 @@
         }
     }
 
-    public void startLoaderForResults(LoaderResults results) {
+    /**
+     * Loads the model if not loaded
+     * @param callback called with the data model upon successful load or null on model thread.
+     */
+    public void loadAsync(Consumer<BgDataModel> callback) {
         synchronized (mLock) {
-            stopLoader();
-            mLoaderTask = new LoaderTask(
-                    mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, results);
-
-            // Always post the loader task, instead of running directly (even on same thread) so
-            // that we exit any nested synchronized blocks
-            MODEL_EXECUTOR.post(mLoaderTask);
-        }
-    }
-
-    public void startLoaderForResultsIfNotLoaded(LoaderResults results) {
-        synchronized (mLock) {
-            if (!isModelLoaded()) {
-                Log.d(TAG, "Workspace not loaded, loading now");
-                startLoaderForResults(results);
+            if (!mModelLoaded && !mIsLoaderTaskRunning) {
+                startLoader();
             }
         }
+        MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null));
     }
 
     @Override