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
This commit is contained in:
Sunny Goyal
2021-08-06 11:52:10 -07:00
parent 464fc41df7
commit 57d4f748b8
3 changed files with 22 additions and 105 deletions
+16 -17
View File
@@ -72,6 +72,7 @@ import java.util.HashSet;
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 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
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 class LauncherModel extends LauncherApps.Callback implements InstallSessi
}
}
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