Federate SliveLiveData for Search results
Instead of every slice result creating its own live data, we should manage a single SliceLiveData per url that SliceViews can observe.
Bug: 173022319
Test: Manual
Change-Id: Ieaf599aadfac40450be4f39657d3cefb70644e0c
diff --git a/src/com/android/launcher3/allapps/search/LiveSearchManager.java b/src/com/android/launcher3/allapps/search/LiveSearchManager.java
index e8a00d9..ec33908 100644
--- a/src/com/android/launcher3/allapps/search/LiveSearchManager.java
+++ b/src/com/android/launcher3/allapps/search/LiveSearchManager.java
@@ -23,9 +23,14 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
+import androidx.lifecycle.LiveData;
+import androidx.slice.Slice;
+import androidx.slice.widget.SliceLiveData;
+
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.util.ComponentKey;
@@ -42,7 +47,9 @@
private final Launcher mLauncher;
private final AppWidgetManager mAppWidgetManger;
- private HashMap<ComponentKey, SearchWidgetInfoContainer> mWidgetPlaceholders = new HashMap<>();
+ private final HashMap<ComponentKey, SearchWidgetInfoContainer> mWidgetPlaceholders =
+ new HashMap<>();
+ private final HashMap<Uri, LiveData<Slice>> mUriSliceMap = new HashMap<>();
private SearchWidgetHost mSearchWidgetHost;
public LiveSearchManager(Launcher launcher) {
@@ -88,6 +95,20 @@
}
/**
+ * Creates {@link LiveData<Slice>} from Slice Uri. Caches created live data to be reused
+ * within the same search session. Removes previous observers when new SliceView request a
+ * live data for observation.
+ */
+ public LiveData<Slice> getSliceForUri(Uri sliceUri) {
+ LiveData<Slice> sliceLiveData = mUriSliceMap.getOrDefault(sliceUri, null);
+ if (sliceLiveData == null) {
+ sliceLiveData = SliceLiveData.fromUri(mLauncher, sliceUri);
+ mUriSliceMap.put(sliceUri, sliceLiveData);
+ }
+ return sliceLiveData;
+ }
+
+ /**
* Start search session
*/
public void start() {
@@ -109,6 +130,10 @@
mWidgetPlaceholders.clear();
mSearchWidgetHost = null;
}
+ for (LiveData<Slice> liveData : mUriSliceMap.values()) {
+ liveData.removeObservers(mLauncher);
+ }
+ mUriSliceMap.clear();
}
static class SearchWidgetHost extends AppWidgetHost {
diff --git a/src/com/android/launcher3/views/SearchResultSettingsSlice.java b/src/com/android/launcher3/views/SearchResultSettingsSlice.java
index 2d726e7..29e6c1b 100644
--- a/src/com/android/launcher3/views/SearchResultSettingsSlice.java
+++ b/src/com/android/launcher3/views/SearchResultSettingsSlice.java
@@ -28,7 +28,6 @@
import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.widget.EventInfo;
-import androidx.slice.widget.SliceLiveData;
import androidx.slice.widget.SliceView;
import com.android.launcher3.Launcher;
@@ -54,7 +53,7 @@
private View mIcon;
private LiveData<Slice> mSliceLiveData;
private SearchTarget mSearchTarget;
- private Launcher mLauncher;
+ private final Launcher mLauncher;
public SearchResultSettingsSlice(Context context) {
this(context, null, 0);
@@ -84,7 +83,7 @@
reset();
mSearchTarget = searchTarget;
try {
- mSliceLiveData = SliceLiveData.fromUri(mLauncher, getSliceUri());
+ mSliceLiveData = mLauncher.getLiveSearchManager().getSliceForUri(getSliceUri());
mSliceLiveData.observe(mLauncher, mSliceView);
} catch (Exception ex) {
Log.e(TAG, "unable to bind slice", ex);