Add a placeholder empty state message for the bookmarks widget
This CL introduces an 'empty_message' TextView to bookmark_widget.xml and uses partiallyUpdateAppWidget() to efficiently control its visibility based on folder content.
A temporary string is shown in the screenshot, but not checked in. The final string will be provided by UX in a subsequent CL.
https://screenshot.googleplex.com/9FeZimGczYrquZ8
Bug:403557617
Change-Id: Ib006c6eba3b0d5a72d557c7220002fdcfa779866
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6340708
Reviewed-by: Sky Malice <skym@chromium.org>
Commit-Queue: Gang Wu <gangwu@chromium.org>
Reviewed-by: Brandon Wylie <wylieb@google.com>
Cr-Commit-Position: refs/heads/main@{#1432988}
diff --git a/chrome/android/java/res/layout/bookmark_widget.xml b/chrome/android/java/res/layout/bookmark_widget.xml
index b49b71c..e3e5460 100644
--- a/chrome/android/java/res/layout/bookmark_widget.xml
+++ b/chrome/android/java/res/layout/bookmark_widget.xml
@@ -5,14 +5,31 @@
found in the LICENSE file.
-->
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/bookmarks_list"
- style="@style/DarkModeCompatibleVerticalScrolling"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/bookmark_widget_background"
- android:divider="@null"
- android:drawSelectorOnTop="true"
- android:listSelector="@drawable/bookmark_widget_list_selector"
- android:alpha="0.9"
- android:theme="@style/Theme.Chromium.Widget" />
+ android:theme="@style/Theme.Chromium.Widget"
+ tools:ignore="MergeRootFrame">
+
+ <ListView
+ android:id="@+id/bookmarks_list"
+ style="@style/DarkModeCompatibleVerticalScrolling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/bookmark_widget_background"
+ android:divider="@null"
+ android:drawSelectorOnTop="true"
+ android:listSelector="@drawable/bookmark_widget_list_selector"
+ android:alpha="0.9" />
+
+ <TextView
+ android:id="@+id/empty_message"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:text="@null"
+ android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+ android:visibility="gone" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetProvider.java
index f5b11ac..59d2e5a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetProvider.java
@@ -140,7 +140,7 @@
}
}
- private boolean shouldShowIconsOnly(AppWidgetManager appWidgetManager, int appWidgetId) {
+ public static boolean shouldShowIconsOnly(AppWidgetManager appWidgetManager, int appWidgetId) {
int widthDp =
appWidgetManager
.getAppWidgetOptions(appWidgetId)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
index 6d3a3a8e1..293a1f6d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
@@ -282,6 +282,7 @@
private final Context mContext;
private final int mWidgetId;
private final SharedPreferences mPreferences;
+ private final RemoteViews mBookmarkWidgeRemoteView;
private int mIconColor;
// Accessed only on the UI thread
@@ -297,6 +298,8 @@
mPreferences = getWidgetState(mWidgetId);
mIconColor = getIconColor(mContext);
SystemNightModeMonitor.getInstance().addObserver(this);
+ mBookmarkWidgeRemoteView =
+ new RemoteViews(mContext.getPackageName(), R.layout.bookmark_widget);
}
@UiThread
@@ -376,7 +379,13 @@
BookmarkId folderId =
BookmarkId.getBookmarkIdFromString(
mPreferences.getString(PREF_CURRENT_FOLDER, null));
+
+ // Blocks until bookmarks are loaded from the UI thread.
mCurrentFolder = loadBookmarks(folderId);
+
+ // Update empty message visibility right after mCurrentFolder is updated.
+ updateFolderEmptyMessageVisibility();
+
mPreferences
.edit()
.putString(PREF_CURRENT_FOLDER, mCurrentFolder.folder.id.toString())
@@ -384,6 +393,27 @@
}
@BinderThread
+ private void updateFolderEmptyMessageVisibility() {
+ AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
+ if (!BookmarkWidgetProvider.shouldShowIconsOnly(appWidgetManager, mWidgetId)) {
+ boolean folderIsEmpty = mCurrentFolder != null && mCurrentFolder.children.isEmpty();
+ mBookmarkWidgeRemoteView.setViewVisibility(
+ R.id.empty_message, folderIsEmpty ? View.VISIBLE : View.GONE);
+
+ // Directly update the widget on the UI thread.
+ PostTask.runOrPostTask(
+ TaskTraits.UI_DEFAULT,
+ () -> {
+ // Use AppWidgetManager#partiallyUpdateAppWidget to update only the
+ // empty_message visibility, avoiding full widget redraws and redundant
+ // intent setup from BookmarkWidgetProvider#performUpdate.
+ appWidgetManager.partiallyUpdateAppWidget(
+ mWidgetId, mBookmarkWidgeRemoteView);
+ });
+ }
+ }
+
+ @BinderThread
private BookmarkFolder loadBookmarks(final BookmarkId folderId) {
final LinkedBlockingQueue<BookmarkFolder> resultQueue = new LinkedBlockingQueue<>(1);
// A reference of BookmarkLoader is needed in binder thread to