Fix out-of-sync updates during grid change

This is a combination of two issues:

1. Widget updates are not passed to the holder when the launcher binding starts
2. Updates from widgetHost.startListening() are overriden by out-of-date info

Fix: 322919716
Test: Manual
Flag: N/A
Change-Id: I9665117412c87b19ed5d98263bb4f9b8da21c5c7
(cherry picked from commit f418b2e16d)
This commit is contained in:
Sihua Ma
2024-03-13 12:17:27 -07:00
parent f8302c388f
commit f0518bb89f
3 changed files with 24 additions and 6 deletions
@@ -26,10 +26,10 @@ import android.util.Log;
import android.util.SparseArray;
import android.widget.RemoteViews;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WidgetsModel;
@@ -265,6 +265,14 @@ public final class QuickstepWidgetHolder extends LauncherWidgetHolder {
}
}
/**
* Clears all the internal widget views excluding the update listeners
*/
@Override
public void clearWidgetViews() {
mViews.clear();
}
private static class QuickstepWidgetHolderListener
implements AppWidgetHost.AppWidgetHostListener {
@@ -288,21 +296,21 @@ public final class QuickstepWidgetHolder extends LauncherWidgetHolder {
}
@Override
@WorkerThread
@AnyThread
public void onUpdateProviderInfo(@Nullable AppWidgetProviderInfo info) {
mRemoteViews = null;
executeOnMainExecutor(KEY_PROVIDER_UPDATE, info);
}
@Override
@WorkerThread
@AnyThread
public void updateAppWidget(@Nullable RemoteViews views) {
mRemoteViews = views;
executeOnMainExecutor(KEY_VIEWS_UPDATE, mRemoteViews);
}
@Override
@WorkerThread
@AnyThread
public void onViewDataChanged(int viewId) {
executeOnMainExecutor(KEY_VIEW_DATA_CHANGED, viewId);
}
+2 -1
View File
@@ -63,7 +63,8 @@ class ModelCallbacks(private var launcher: Launcher) : BgDataModel.Callbacks {
launcher.dragController.cancelDrag()
launcher.workspace.clearDropTargets()
launcher.workspace.removeAllWorkspaceScreens()
launcher.appWidgetHolder.clearViews()
// Avoid clearing the widget update listeners for staying up-to-date with widget info
launcher.appWidgetHolder.clearWidgetViews()
launcher.hotseat?.resetLayout(launcher.deviceProfile.isVerticalBarLayout)
TraceHelper.INSTANCE.endSection()
}
@@ -103,7 +103,7 @@ public class LauncherWidgetHolder {
if (WidgetsModel.GO_DISABLE_WIDGETS) {
return;
}
setListeningFlag(true);
try {
mWidgetHost.startListening();
} catch (Exception e) {
@@ -115,6 +115,8 @@ public class LauncherWidgetHolder {
// have been established by this point, and we will end up populating the
// widgets upon bind anyway. See issue 14255011 for more context.
}
// TODO: Investigate why widgetHost.startListening() always return non-empty updates
setListeningFlag(true);
updateDeferredView();
}
@@ -441,6 +443,13 @@ public class LauncherWidgetHolder {
mViews.clear();
}
/**
* Clears all the internal widget views
*/
public void clearWidgetViews() {
clearViews();
}
/**
* @return True if the host is listening to the updates, false otherwise
*/