Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(819)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java

Issue 1840193002: Rename "BookmarkThumbnailWidget" to "BookmarkWidget". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix lint Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java
deleted file mode 100644
index 50de3d912f0db768512f70706adeb6c894f6be3b..0000000000000000000000000000000000000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.bookmarkswidget;
-
-import android.appwidget.AppWidgetManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.support.annotation.BinderThread;
-import android.support.annotation.UiThread;
-import android.text.TextUtils;
-import android.widget.RemoteViews;
-import android.widget.RemoteViewsService;
-
-import com.google.android.apps.chrome.appwidget.bookmarks.BookmarkThumbnailWidgetProvider;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.base.Log;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.SuppressFBWarnings;
-import org.chromium.base.library_loader.ProcessInitException;
-import org.chromium.base.metrics.RecordUserAction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
-import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
-import org.chromium.chrome.browser.bookmarks.BookmarkModel;
-import org.chromium.chrome.browser.favicon.LargeIconBridge;
-import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback;
-import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.util.IntentUtils;
-import org.chromium.chrome.browser.widget.RoundedIconGenerator;
-import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkType;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import javax.annotation.Nullable;
-
-/**
- * Service to support the bookmarks widget.
- *
- * This provides the list of bookmarks to show in the widget via a RemoteViewsFactory (the
- * RemoteViews equivalent of an Adapter), and updates the widget when the bookmark model changes.
- *
- * Threading note: Be careful! Android calls some methods in this class on the UI thread and others
- * on (multiple) binder threads. Additionally, all interaction with the BookmarkModel must happen on
- * the UI thread. To keep the situation clear, every non-static method is annotated with either
- * {@link UiThread} or {@link BinderThread}.
- */
-public class BookmarkThumbnailWidgetService extends RemoteViewsService {
-
- private static final String TAG = "BookmarkWidget";
- private static final String ACTION_CHANGE_FOLDER_SUFFIX = ".CHANGE_FOLDER";
- private static final String PREF_CURRENT_FOLDER = "current_folder";
- private static final String EXTRA_FOLDER_ID = "folderId";
-
- @UiThread
- @Override
- public RemoteViewsFactory onGetViewFactory(Intent intent) {
- int widgetId = IntentUtils.safeGetIntExtra(intent, AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
- if (widgetId < 0) {
- Log.w(TAG, "Missing EXTRA_APPWIDGET_ID!");
- return null;
- }
- return new BookmarkAdapter(this, widgetId);
- }
-
- static String getChangeFolderAction(Context context) {
- return context.getPackageName() + ACTION_CHANGE_FOLDER_SUFFIX;
- }
-
- static SharedPreferences getWidgetState(Context context, int widgetId) {
- return context.getSharedPreferences(
- String.format("widgetState-%d", widgetId),
- Context.MODE_PRIVATE);
- }
-
- static void deleteWidgetState(Context context, int widgetId) {
- SharedPreferences preferences = getWidgetState(context, widgetId);
- if (preferences != null) preferences.edit().clear().apply();
- }
-
- static void changeFolder(Context context, Intent intent) {
- int widgetId = IntentUtils.safeGetIntExtra(intent, AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
- long folderId = IntentUtils.safeGetLongExtra(intent, EXTRA_FOLDER_ID, -1);
- if (widgetId >= 0 && folderId >= 0) {
- SharedPreferences prefs = getWidgetState(context, widgetId);
- prefs.edit().putLong(PREF_CURRENT_FOLDER, folderId).apply();
- AppWidgetManager.getInstance(context)
- .notifyAppWidgetViewDataChanged(widgetId, R.id.bookmarks_list);
- }
- }
-
- /**
- * Holds data describing a bookmark or bookmark folder.
- */
- private static class Bookmark {
- public String title;
- public String url;
- public BookmarkId id;
- public BookmarkId parentId;
- public boolean isFolder;
- public Bitmap favicon;
-
- public static Bookmark fromBookmarkItem(BookmarkItem item) {
- if (item == null) return null;
-
- // The bookmarks widget doesn't support showing partner bookmarks. The main hurdle is
- // that the current folder ID is stored in shared prefs as a long, not a BookmarkId.
- // This support could be added if there's a strong desire.
- if (item.getId().getType() == BookmarkType.PARTNER) return null;
-
- Bookmark bookmark = new Bookmark();
- bookmark.title = item.getTitle();
- bookmark.url = item.getUrl();
- bookmark.id = item.getId();
- bookmark.parentId = item.getParentId();
- bookmark.isFolder = item.isFolder();
- return bookmark;
- }
- }
-
- /**
- * Holds the list of bookmarks in a folder, as well as information about the folder itself and
- * its parent folder, if any.
- */
- private static class BookmarkFolder {
- public Bookmark folder;
- @Nullable public Bookmark parent;
- public final List<Bookmark> children = new ArrayList<>();
- }
-
- /**
- * Called when the BookmarkLoader has finished loading the bookmark folder.
- */
- private interface BookmarkLoaderCallback {
- @UiThread
- void onBookmarksLoaded(BookmarkFolder folder);
- }
-
- /**
- * Loads a BookmarkFolder asynchronously, and returns the result via BookmarkLoaderCallback.
- *
- * This class must be used only on the UI thread.
- */
- @UiThread
- private static class BookmarkLoader {
- private BookmarkLoaderCallback mCallback;
- private BookmarkFolder mFolder;
- private BookmarkModel mBookmarkModel;
- private LargeIconBridge mLargeIconBridge;
- private RoundedIconGenerator mIconGenerator;
- private int mMinIconSizeDp;
- private int mDisplayedIconSize;
- private int mCornerRadius;
- private int mRemainingTaskCount;
-
- BookmarkLoader(Context context, final BookmarkId folderId,
- BookmarkLoaderCallback callback) {
- mCallback = callback;
-
- Resources res = context.getResources();
- mLargeIconBridge = new LargeIconBridge(
- Profile.getLastUsedProfile().getOriginalProfile());
- mMinIconSizeDp = (int) res.getDimension(R.dimen.bookmark_item_min_icon_size);
- mDisplayedIconSize = res.getDimensionPixelSize(R.dimen.bookmark_item_icon_size);
- mCornerRadius = res.getDimensionPixelSize(R.dimen.bookmark_item_corner_radius);
- int textSize = res.getDimensionPixelSize(R.dimen.bookmark_item_icon_text_size);
- int iconColor = ApiCompatibilityUtils.getColor(res,
- R.color.bookmark_icon_background_color);
- mIconGenerator = new RoundedIconGenerator(mDisplayedIconSize, mDisplayedIconSize,
- mCornerRadius, iconColor, textSize);
-
- mRemainingTaskCount = 1;
- mBookmarkModel = new BookmarkModel();
- mBookmarkModel.runAfterBookmarkModelLoaded(new Runnable() {
- @Override
- public void run() {
- loadBookmarks(folderId);
- }
- });
- }
-
- private void loadBookmarks(BookmarkId folderId) {
- mFolder = new BookmarkFolder();
-
- // Load the requested folder if it exists. Otherwise, fall back to the default folder.
- if (folderId != null) {
- mFolder.folder = Bookmark.fromBookmarkItem(mBookmarkModel.getBookmarkById(
- folderId));
- }
- if (mFolder.folder == null) {
- folderId = mBookmarkModel.getDefaultFolder();
- mFolder.folder = Bookmark.fromBookmarkItem(mBookmarkModel.getBookmarkById(
- folderId));
- }
-
- mFolder.parent = Bookmark.fromBookmarkItem(mBookmarkModel.getBookmarkById(
- mFolder.folder.parentId));
-
- List<BookmarkItem> items = mBookmarkModel.getBookmarksForFolder(folderId);
-
- // Move folders to the beginning of the list.
- Collections.sort(items, new Comparator<BookmarkItem>() {
- @Override
- public int compare(BookmarkItem lhs, BookmarkItem rhs) {
- return lhs.isFolder() == rhs.isFolder() ? 0 : lhs.isFolder() ? -1 : 1;
- }
- });
-
- for (BookmarkItem item : items) {
- Bookmark bookmark = Bookmark.fromBookmarkItem(item);
- loadFavicon(bookmark);
- mFolder.children.add(bookmark);
- }
-
- taskFinished();
- }
-
- private void loadFavicon(final Bookmark bookmark) {
- if (bookmark.isFolder) return;
-
- mRemainingTaskCount++;
- LargeIconCallback callback = new LargeIconCallback() {
- @Override
- public void onLargeIconAvailable(Bitmap icon, int fallbackColor) {
- if (icon == null) {
- mIconGenerator.setBackgroundColor(fallbackColor);
- icon = mIconGenerator.generateIconForUrl(bookmark.url);
- } else {
- icon = Bitmap.createScaledBitmap(icon, mDisplayedIconSize,
- mDisplayedIconSize, true);
- }
- bookmark.favicon = icon;
- taskFinished();
- }
- };
- mLargeIconBridge.getLargeIconForUrl(bookmark.url, mMinIconSizeDp, callback);
- }
-
- private void taskFinished() {
- mRemainingTaskCount--;
- if (mRemainingTaskCount == 0) {
- mCallback.onBookmarksLoaded(mFolder);
- destroy();
- }
- }
-
- private void destroy() {
- mBookmarkModel.destroy();
- mLargeIconBridge.destroy();
- }
- }
-
- /**
- * Provides the RemoteViews, one per bookmark, to be shown in the widget.
- */
- private static class BookmarkAdapter implements RemoteViewsService.RemoteViewsFactory {
-
- // Can be accessed on any thread
- private final Context mContext;
- private final int mWidgetId;
- private final SharedPreferences mPreferences;
-
- // Accessed only on the UI thread
- private BookmarkModel mBookmarkModel;
-
- // Accessed only on binder threads.
- private BookmarkFolder mCurrentFolder;
-
- @UiThread
- public BookmarkAdapter(Context context, int widgetId) {
- mContext = context;
- mWidgetId = widgetId;
- mPreferences = getWidgetState(mContext, mWidgetId);
- }
-
- @UiThread
- @SuppressFBWarnings("DM_EXIT")
- @Override
- public void onCreate() {
- // Required to be applied here redundantly to prevent crashes in the cases where the
- // package data is deleted or the Chrome application forced to stop.
- try {
- ChromeBrowserInitializer.getInstance(mContext).handleSynchronousStartup();
- } catch (ProcessInitException e) {
- Log.e(TAG, "Failed to start browser process.", e);
- // Since the library failed to initialize nothing in the application
- // can work, so kill the whole application not just the activity
- System.exit(-1);
- }
- if (isWidgetNewlyCreated()) {
- RecordUserAction.record("BookmarkNavigatorWidgetAdded");
- }
-
- // Partner bookmarks need to be loaded explicitly.
- PartnerBookmarksShim.kickOffReading(mContext);
-
- mBookmarkModel = new BookmarkModel();
- mBookmarkModel.addObserver(new BookmarkModelObserver() {
- @Override
- public void bookmarkModelLoaded() {
- // Do nothing. No need to refresh.
- }
-
- @Override
- public void bookmarkModelChanged() {
- refreshWidget();
- }
- });
- }
-
- @UiThread
- private boolean isWidgetNewlyCreated() {
- // This method relies on the fact that PREF_CURRENT_FOLDER is not yet
- // set when onCreate is called for a newly created widget.
- long currentFolder = mPreferences.getLong(PREF_CURRENT_FOLDER, Tab.INVALID_BOOKMARK_ID);
- return currentFolder == Tab.INVALID_BOOKMARK_ID;
- }
-
- @UiThread
- private void refreshWidget() {
- mContext.sendBroadcast(new Intent(
- BookmarkThumbnailWidgetProviderBase.getBookmarkAppWidgetUpdateAction(mContext),
- null, mContext, BookmarkThumbnailWidgetProvider.class)
- .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId));
- }
-
- // ---------------------------------------------------------------- //
- // Methods below this line are called on binder threads. //
- // ---------------------------------------------------------------- //
- // Different methods may be called on *different* binder threads, //
- // but the system ensures that the effects of each method call will //
- // be visible before the next method is called. Thus, additional //
- // synchronization is not needed when accessing mCurrentFolder. //
- // ---------------------------------------------------------------- //
-
- @BinderThread
- @Override
- public void onDestroy() {
- ThreadUtils.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (mBookmarkModel != null) mBookmarkModel.destroy();
- }
- });
- deleteWidgetState(mContext, mWidgetId);
- }
-
- @BinderThread
- @Override
- public void onDataSetChanged() {
- updateBookmarkList();
- }
-
- @BinderThread
- private void updateBookmarkList() {
- long folderIdLong = mPreferences.getLong(PREF_CURRENT_FOLDER, Tab.INVALID_BOOKMARK_ID);
- BookmarkId folderId = folderIdLong != Tab.INVALID_BOOKMARK_ID
- ? new BookmarkId(folderIdLong, BookmarkType.NORMAL)
- : null;
-
- mCurrentFolder = loadBookmarks(folderId);
-
- mPreferences.edit()
- .putLong(PREF_CURRENT_FOLDER, mCurrentFolder != null
- ? mCurrentFolder.folder.id.getId()
- : Tab.INVALID_BOOKMARK_ID)
- .apply();
- }
-
- @BinderThread
- private BookmarkFolder loadBookmarks(final BookmarkId folderId) {
- final LinkedBlockingQueue<BookmarkFolder> resultQueue = new LinkedBlockingQueue<>(1);
- ThreadUtils.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- new BookmarkLoader(mContext, folderId, new BookmarkLoaderCallback() {
- @Override
- public void onBookmarksLoaded(BookmarkFolder folder) {
- resultQueue.add(folder);
- }
- });
- }
- });
- try {
- return resultQueue.take();
- } catch (InterruptedException e) {
- return null;
- }
- }
-
- @BinderThread
- private Bookmark getBookmarkForPosition(int position) {
- if (mCurrentFolder == null) return null;
-
- // The position 0 is saved for an entry of the current folder used to go up.
- // This is not the case when the current node has no parent (it's the root node).
- if (mCurrentFolder.parent != null) {
- if (position == 0) return mCurrentFolder.folder;
- position--;
- }
- return mCurrentFolder.children.get(position);
- }
-
- @BinderThread
- @Override
- public int getViewTypeCount() {
- return 2;
- }
-
- @BinderThread
- @Override
- public boolean hasStableIds() {
- return false;
- }
-
- @BinderThread
- @Override
- public int getCount() {
- if (mCurrentFolder == null) return 0;
- return mCurrentFolder.children.size() + (mCurrentFolder.parent != null ? 1 : 0);
- }
-
- @BinderThread
- @Override
- public long getItemId(int position) {
- return getBookmarkForPosition(position).id.getId();
- }
-
- @BinderThread
- @Override
- public RemoteViews getLoadingView() {
- return new RemoteViews(mContext.getPackageName(),
- R.layout.bookmark_thumbnail_widget_item);
- }
-
- @BinderThread
- @Override
- public RemoteViews getViewAt(int position) {
- if (mCurrentFolder == null) {
- Log.w(TAG, "No current folder data available.");
- return null;
- }
-
- Bookmark bookmark = getBookmarkForPosition(position);
- if (bookmark == null) {
- Log.w(TAG, "Couldn't get bookmark for position %d", position);
- return null;
- }
-
- String title = bookmark.title;
- String url = bookmark.url;
- long id = (bookmark == mCurrentFolder.folder)
- ? mCurrentFolder.parent.id.getId()
- : bookmark.id.getId();
-
- RemoteViews views = new RemoteViews(mContext.getPackageName(),
- R.layout.bookmark_thumbnail_widget_item);
-
- // Set the title of the bookmark. Use the url as a backup.
- views.setTextViewText(R.id.title, TextUtils.isEmpty(title) ? url : title);
-
- if (bookmark == mCurrentFolder.folder) {
- views.setImageViewResource(R.id.favicon, R.drawable.bookmark_back_normal);
- } else if (bookmark.isFolder) {
- views.setImageViewResource(R.id.favicon, R.drawable.bookmark_folder);
- } else {
- views.setImageViewBitmap(R.id.favicon, bookmark.favicon);
- }
-
- Intent fillIn;
- if (bookmark.isFolder) {
- fillIn = new Intent(getChangeFolderAction(mContext))
- .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
- .putExtra(EXTRA_FOLDER_ID, id);
- } else {
- fillIn = new Intent(Intent.ACTION_VIEW);
- if (!TextUtils.isEmpty(url)) {
- fillIn = fillIn.addCategory(Intent.CATEGORY_BROWSABLE)
- .setData(Uri.parse(url));
- } else {
- fillIn = fillIn.addCategory(Intent.CATEGORY_LAUNCHER);
- }
- }
- views.setOnClickFillInIntent(R.id.list_item, fillIn);
- return views;
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698