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:
parent
464fc41df7
commit
57d4f748b8
|
@ -72,6 +72,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -376,7 +377,13 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
|
||||||
loaderResults.bindWidgets();
|
loaderResults.bindWidgets();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} 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) {
|
synchronized (mLock) {
|
||||||
stopLoader();
|
if (!mModelLoaded && !mIsLoaderTaskRunning) {
|
||||||
mLoaderTask = new LoaderTask(
|
startLoader();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -49,7 +49,6 @@ import com.android.launcher3.model.GridSizeMigrationTask;
|
||||||
import com.android.launcher3.model.GridSizeMigrationTaskV2;
|
import com.android.launcher3.model.GridSizeMigrationTaskV2;
|
||||||
import com.android.launcher3.model.LoaderTask;
|
import com.android.launcher3.model.LoaderTask;
|
||||||
import com.android.launcher3.model.ModelDelegate;
|
import com.android.launcher3.model.ModelDelegate;
|
||||||
import com.android.launcher3.model.ModelPreload;
|
|
||||||
import com.android.launcher3.util.ComponentKey;
|
import com.android.launcher3.util.ComponentKey;
|
||||||
import com.android.launcher3.util.RunnableList;
|
import com.android.launcher3.util.RunnableList;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
|
@ -174,18 +173,13 @@ public class PreviewSurfaceRenderer {
|
||||||
}
|
}
|
||||||
}.run();
|
}.run();
|
||||||
} else {
|
} else {
|
||||||
new ModelPreload() {
|
LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> {
|
||||||
|
if (dataModel != null) {
|
||||||
@Override
|
MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null));
|
||||||
public void onComplete(boolean isSuccess) {
|
} else {
|
||||||
if (isSuccess) {
|
Log.e(TAG, "Model loading failed");
|
||||||
MAIN_EXECUTOR.execute(() ->
|
|
||||||
renderView(inflationContext, getBgDataModel(), null));
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Model loading failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.start(inflationContext);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.android.launcher3.model;
|
|
||||||
|
|
||||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.WorkerThread;
|
|
||||||
|
|
||||||
import com.android.launcher3.LauncherAppState;
|
|
||||||
import com.android.launcher3.LauncherModel;
|
|
||||||
import com.android.launcher3.LauncherModel.ModelUpdateTask;
|
|
||||||
import com.android.launcher3.model.BgDataModel.Callbacks;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class to preload LauncherModel
|
|
||||||
*/
|
|
||||||
public class ModelPreload implements ModelUpdateTask {
|
|
||||||
|
|
||||||
private static final String TAG = "ModelPreload";
|
|
||||||
|
|
||||||
private LauncherAppState mApp;
|
|
||||||
private LauncherModel mModel;
|
|
||||||
private BgDataModel mBgDataModel;
|
|
||||||
private AllAppsList mAllAppsList;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel,
|
|
||||||
AllAppsList allAppsList, Executor uiExecutor) {
|
|
||||||
mApp = app;
|
|
||||||
mModel = model;
|
|
||||||
mBgDataModel = dataModel;
|
|
||||||
mAllAppsList = allAppsList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void run() {
|
|
||||||
mModel.startLoaderForResultsIfNotLoaded(
|
|
||||||
new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0]));
|
|
||||||
MODEL_EXECUTOR.post(() -> {
|
|
||||||
Log.d(TAG, "Preload completed : " + mModel.isModelLoaded());
|
|
||||||
onComplete(mModel.isModelLoaded());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public BgDataModel getBgDataModel() {
|
|
||||||
return mBgDataModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the task is complete
|
|
||||||
*/
|
|
||||||
@WorkerThread
|
|
||||||
public void onComplete(boolean isSuccess) { }
|
|
||||||
|
|
||||||
public void start(Context context) {
|
|
||||||
LauncherAppState.getInstance(context).getModel().enqueueModelUpdateTask(this);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue