Support Agassi (Search Engine choice) in Android R
Test:
1) set your preferred search provider using `adb shell settings put global SEARCH_PROVIDER_PACKAGE_NAME <value>`.(eg: com.duckduckgo.mobile.android)
2) install the package name and confirm search widget on launcher is updated
3) uninstalled the package and confirm widget is replaced with placeholder on launcher.
Bug:137653564
Change-Id: I8904d5915a8c03ea6068fb5950af15ca786b8ad7
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index 857ea05..09c6c36 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -32,12 +32,15 @@
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
@@ -55,6 +58,8 @@
*/
public class QsbContainerView extends FrameLayout {
+ public static final String SEARCH_PROVIDER_SETTINGS_KEY = "SEARCH_PROVIDER_PACKAGE_NAME";
+
public QsbContainerView(Context context) {
super(context);
}
@@ -101,7 +106,7 @@
protected QsbWidgetHost createHost() {
return new QsbWidgetHost(getContext(), QSB_WIDGET_HOST_ID,
- (c) -> new QsbWidgetHostView(c));
+ (c) -> new QsbWidgetHostView(c), this::rebindFragment);
}
private FrameLayout mWrapper;
@@ -111,7 +116,6 @@
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mWrapper = new FrameLayout(getContext());
-
// Only add the view when enabled
if (isQsbEnabled()) {
mWrapper.addView(createQsb(mWrapper));
@@ -247,20 +251,36 @@
}
/**
+ * returns the package name string from global settings or from system search service.
+ *
+ * @return String (package name) or null if neither exist
+ */
+ @Nullable
+ protected String getSearchProviderPackageName() {
+ String providerPkg = Settings.Global.getString(getContext().getContentResolver(),
+ SEARCH_PROVIDER_SETTINGS_KEY);
+ if (providerPkg == null) {
+ SearchManager searchManager = getContext().getSystemService(SearchManager.class);
+ ComponentName componentName = searchManager.getGlobalSearchActivity();
+ if (componentName != null) {
+ providerPkg = searchManager.getGlobalSearchActivity().getPackageName();
+ }
+ }
+ return providerPkg;
+ }
+
+ /**
* Returns a widget with category {@link AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}
- * provided by the same package which is set to be global search activity.
+ * provided by the package from getSearchProviderPackageName
* If widgetCategory is not supported, or no such widget is found, returns the first widget
* provided by the package.
*/
protected AppWidgetProviderInfo getSearchWidgetProvider() {
- SearchManager searchManager =
- (SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE);
- ComponentName searchComponent = searchManager.getGlobalSearchActivity();
- if (searchComponent == null) return null;
- String providerPkg = searchComponent.getPackageName();
-
+ String providerPkg = getSearchProviderPackageName();
+ if (providerPkg == null) {
+ return null;
+ }
AppWidgetProviderInfo defaultWidgetForSearchPackage = null;
-
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getContext());
for (AppWidgetProviderInfo info : appWidgetManager.getInstalledProviders()) {
if (info.provider.getPackageName().equals(providerPkg) && info.configure == null) {
@@ -279,10 +299,17 @@
public static class QsbWidgetHost extends AppWidgetHost {
private final WidgetViewFactory mViewFactory;
+ private final WidgetProvidersUpdateCallback mWidgetsUpdateCallback;
- public QsbWidgetHost(Context context, int hostId, WidgetViewFactory viewFactory) {
+ public QsbWidgetHost(Context context, int hostId, WidgetViewFactory viewFactory,
+ WidgetProvidersUpdateCallback widgetProvidersUpdateCallback) {
super(context, hostId);
mViewFactory = viewFactory;
+ mWidgetsUpdateCallback = widgetProvidersUpdateCallback;
+ }
+
+ public QsbWidgetHost(Context context, int hostId, WidgetViewFactory viewFactory) {
+ this(context, hostId, viewFactory, null);
}
@Override
@@ -290,6 +317,14 @@
Context context, int appWidgetId, AppWidgetProviderInfo appWidget) {
return mViewFactory.newView(context);
}
+
+ @Override
+ protected void onProvidersChanged() {
+ super.onProvidersChanged();
+ if (mWidgetsUpdateCallback != null) {
+ mWidgetsUpdateCallback.onProvidersUpdated();
+ }
+ }
}
public interface WidgetViewFactory {
@@ -298,6 +333,17 @@
}
/**
+ * Callback interface for packages list update.
+ */
+ @FunctionalInterface
+ public interface WidgetProvidersUpdateCallback {
+ /**
+ * Gets called when widget providers list changes
+ */
+ void onProvidersUpdated();
+ }
+
+ /**
* Returns true if {@param original} contains all entries defined in {@param updates} and
* have the same value.
* The comparison uses {@link Object#equals(Object)} to compare the values.