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

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

Issue 1206673003: Merge java_staging/src into java/src. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 6 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_staging/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java
deleted file mode 100644
index 8ba1827d1e0883215f9c04849187da555fccbe67..0000000000000000000000000000000000000000
--- a/chrome/android/java_staging/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkThumbnailWidgetService.java
+++ /dev/null
@@ -1,388 +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.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapFactory.Options;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Binder;
-import android.provider.Browser.BookmarkColumns;
-import android.text.TextUtils;
-import android.util.Log;
-import android.widget.RemoteViews;
-import android.widget.RemoteViewsService;
-
-import com.google.android.apps.chrome.appwidget.bookmarks.BookmarkThumbnailWidgetProvider;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.SuppressFBWarnings;
-import org.chromium.base.library_loader.ProcessInitException;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeBrowserProvider.BookmarkNode;
-import org.chromium.chrome.browser.ChromeBrowserProviderClient;
-import org.chromium.chrome.browser.ChromiumApplication;
-import org.chromium.chrome.browser.util.IntentUtils;
-import org.chromium.sync.AndroidSyncSettings;
-
-/**
- * Service to support bookmarks on the Android home screen
- */
-public class BookmarkThumbnailWidgetService extends RemoteViewsService {
-
- static final String TAG = "BookmarkThumbnailWidgetService";
- static final String ACTION_CHANGE_FOLDER_SUFFIX = ".CHANGE_FOLDER";
- static final String STATE_CURRENT_FOLDER = "current_folder";
-
- @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 BookmarkFactory(this, widgetId);
- }
-
- static String getChangeFolderAction(Context context) {
- return context.getPackageName() + ACTION_CHANGE_FOLDER_SUFFIX;
- }
-
- private 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) {
- // Android Browser's widget used private API methods to access the shared prefs
- // files and deleted them. This is the best we can do with the public API.
- SharedPreferences preferences = getWidgetState(context, widgetId);
- if (preferences != null) preferences.edit().clear().commit();
- }
-
- static void changeFolder(Context context, Intent intent) {
- int widgetId = IntentUtils.safeGetIntExtra(intent, AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
- long folderId = IntentUtils.safeGetLongExtra(intent, BookmarkColumns._ID,
- ChromeBrowserProviderClient.INVALID_BOOKMARK_ID);
- if (widgetId >= 0 && folderId >= 0) {
- SharedPreferences prefs = getWidgetState(context, widgetId);
- prefs.edit().putLong(STATE_CURRENT_FOLDER, folderId).commit();
- AppWidgetManager.getInstance(context)
- .notifyAppWidgetViewDataChanged(widgetId, R.id.bookmarks_list);
- }
- }
-
- static class BookmarkFactory implements RemoteViewsService.RemoteViewsFactory,
- BookmarkWidgetUpdateListener.UpdateListener {
-
- private final ChromiumApplication mContext;
- private final int mWidgetId;
- private final SharedPreferences mPreferences;
- private BookmarkWidgetUpdateListener mUpdateListener;
- private BookmarkNode mCurrentFolder;
- private final Object mLock = new Object();
-
- public BookmarkFactory(Context context, int widgetId) {
- mContext = (ChromiumApplication) context.getApplicationContext();
- mWidgetId = widgetId;
- mPreferences = getWidgetState(mContext, mWidgetId);
- }
-
- private static long getFolderId(BookmarkNode folder) {
- return folder != null ? folder.id() : ChromeBrowserProviderClient.INVALID_BOOKMARK_ID;
- }
-
- @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 {
- mContext.startBrowserProcessesAndLoadLibrariesSync(true);
- } 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);
- }
- mUpdateListener = new BookmarkWidgetUpdateListener(mContext, this);
- }
-
- @Override
- public void onDestroy() {
- if (mUpdateListener != null) mUpdateListener.destroy();
- deleteWidgetState(mContext, mWidgetId);
- }
-
- @Override
- public void onBookmarkModelUpdated() {
- refreshWidget();
- }
-
- @Override
- public void onSyncEnabledStatusUpdated(boolean enabled) {
- synchronized (mLock) {
- // Need to operate in a separate thread as it involves queries to our provider.
- new SyncEnabledStatusUpdatedTask(enabled, getFolderId(mCurrentFolder)).execute();
- }
- }
-
- @Override
- public void onThumbnailUpdated(String url) {
- synchronized (mLock) {
- if (mCurrentFolder == null) return;
-
- for (BookmarkNode child : mCurrentFolder.children()) {
- if (child.isUrl() && url.equals(child.url())) {
- refreshWidget();
- break;
- }
- }
- }
- }
-
- void refreshWidget() {
- mContext.sendBroadcast(new Intent(
- BookmarkThumbnailWidgetProviderBase.getBookmarkAppWidgetUpdateAction(mContext),
- null, mContext, BookmarkThumbnailWidgetProvider.class)
- .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId));
- }
-
- void requestFolderChange(long folderId) {
- mContext.sendBroadcast(new Intent(getChangeFolderAction(mContext))
- .setClass(mContext, BookmarkWidgetProxy.class)
- .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
- .putExtra(BookmarkColumns._ID, folderId));
- }
-
- // Performs the required checks to trigger an update of the widget after changing the sync
- // enable settings. The required provider methods cannot be accessed in the UI thread.
- private class SyncEnabledStatusUpdatedTask extends AsyncTask<Void, Void, Void> {
- private final boolean mEnabled;
- private final long mCurrentFolderId;
-
- public SyncEnabledStatusUpdatedTask(boolean enabled, long currentFolderId) {
- mEnabled = enabled;
- mCurrentFolderId = currentFolderId;
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- // If we're in the Mobile Bookmarks folder the icon to go up the hierarchy
- // will either appear or disappear. Need to refresh.
- long mobileBookmarksFolderId =
- ChromeBrowserProviderClient.getMobileBookmarksFolderId(mContext);
- if (mCurrentFolderId == mobileBookmarksFolderId) {
- refreshWidget();
- return null;
- }
-
- // If disabling sync, we need to move to the Mobile Bookmarks folder if we're
- // not inside that branch of the bookmark hierarchy (will become not accessible).
- if (!mEnabled && !ChromeBrowserProviderClient.isBookmarkInMobileBookmarksBranch(
- mContext, mCurrentFolderId)) {
- requestFolderChange(mobileBookmarksFolderId);
- }
-
- return null;
- }
- }
-
- // ---------------------------------------------------------------- //
- // ------- Methods below this line run in different thread -------- //
- // ---------------------------------------------------------------- //
-
- private void syncState() {
- long currentFolderId = mPreferences.getLong(STATE_CURRENT_FOLDER,
- ChromeBrowserProviderClient.INVALID_BOOKMARK_ID);
-
- // Keep outside the synchronized block to avoid deadlocks in case loading the folder
- // triggers an update that locks when trying to read mCurrentFolder.
- BookmarkNode newFolder = loadBookmarkFolder(currentFolderId);
-
- synchronized (mLock) {
- mCurrentFolder =
- getFolderId(newFolder) != ChromeBrowserProviderClient.INVALID_BOOKMARK_ID
- ? newFolder : null;
- }
-
- mPreferences.edit()
- .putLong(STATE_CURRENT_FOLDER, getFolderId(mCurrentFolder))
- .apply();
- }
-
- private BookmarkNode loadBookmarkFolder(long folderId) {
- if (ThreadUtils.runningOnUiThread()) {
- Log.e(TAG, "Trying to load bookmark folder from the UI thread.");
- return null;
- }
-
- // If the current folder id doesn't exist (it was deleted) try the current parent.
- // If this fails too then fallback to Mobile Bookmarks.
- if (!ChromeBrowserProviderClient.bookmarkNodeExists(mContext, folderId)) {
- folderId = mCurrentFolder != null ? getFolderId(mCurrentFolder.parent())
- : ChromeBrowserProviderClient.INVALID_BOOKMARK_ID;
- if (!ChromeBrowserProviderClient.bookmarkNodeExists(mContext, folderId)) {
- folderId = ChromeBrowserProviderClient.INVALID_BOOKMARK_ID;
- }
- }
-
- // Need to verify this always because the package data might be cleared while the
- // widget is in the Mobile Bookmarks folder with sync enabled. In that case the
- // hierarchy up folder would still work (we can't update the widget) but the parent
- // folders should not be accessible because sync has been reset when clearing data.
- if (folderId != ChromeBrowserProviderClient.INVALID_BOOKMARK_ID
- && !AndroidSyncSettings.isSyncEnabled(mContext)
- && !ChromeBrowserProviderClient.isBookmarkInMobileBookmarksBranch(
- mContext, folderId)) {
- folderId = ChromeBrowserProviderClient.INVALID_BOOKMARK_ID;
- }
-
- // Use the Mobile Bookmarks folder by default.
- if (folderId < 0 || folderId == ChromeBrowserProviderClient.INVALID_BOOKMARK_ID) {
- folderId = ChromeBrowserProviderClient.getMobileBookmarksFolderId(mContext);
- if (folderId == ChromeBrowserProviderClient.INVALID_BOOKMARK_ID) return null;
- }
-
- return ChromeBrowserProviderClient.getBookmarkNode(mContext, folderId,
- ChromeBrowserProviderClient.GET_PARENT
- | ChromeBrowserProviderClient.GET_CHILDREN
- | ChromeBrowserProviderClient.GET_FAVICONS
- | ChromeBrowserProviderClient.GET_THUMBNAILS);
- }
-
- private BookmarkNode 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).
- return (mCurrentFolder.parent() == null)
- ? mCurrentFolder.children().get(position)
- : (position == 0
- ? mCurrentFolder : mCurrentFolder.children().get(position - 1));
- }
-
- @Override
- public void onDataSetChanged() {
- long token = Binder.clearCallingIdentity();
- syncState();
- Binder.restoreCallingIdentity(token);
- }
-
- @Override
- public int getViewTypeCount() {
- return 2;
- }
-
- @Override
- public boolean hasStableIds() {
- return false;
- }
-
- @Override
- public int getCount() {
- if (mCurrentFolder == null) return 0;
- return mCurrentFolder.children().size() + (mCurrentFolder.parent() != null ? 1 : 0);
- }
-
- @Override
- public long getItemId(int position) {
- return getFolderId(getBookmarkForPosition(position));
- }
-
- @Override
- public RemoteViews getLoadingView() {
- return new RemoteViews(mContext.getPackageName(),
- R.layout.bookmark_thumbnail_widget_item);
- }
-
- @Override
- public RemoteViews getViewAt(int position) {
- if (mCurrentFolder == null) {
- Log.w(TAG, "No current folder data available.");
- return null;
- }
-
- BookmarkNode bookmark = getBookmarkForPosition(position);
- if (bookmark == null) {
- Log.w(TAG, "Couldn't get bookmark for position " + position);
- return null;
- }
-
- if (bookmark == mCurrentFolder && bookmark.parent() == null) {
- Log.w(TAG, "Invalid bookmark data: loop detected.");
- return null;
- }
-
- String title = bookmark.name();
- String url = bookmark.url();
- long id = (bookmark == mCurrentFolder) ? bookmark.parent().id() : bookmark.id();
-
- // Two layouts are needed because RemoteView does not supporting changing the scale type
- // of an ImageView: boomarks crop their thumbnails, while folders stretch their icon.
- RemoteViews views = !bookmark.isUrl()
- ? new RemoteViews(mContext.getPackageName(),
- R.layout.bookmark_thumbnail_widget_item_folder)
- : 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.label, TextUtils.isEmpty(title) ? url : title);
-
- if (!bookmark.isUrl()) {
- int thumbId = (bookmark == mCurrentFolder)
- ? R.drawable.thumb_bookmark_widget_folder_back_holo
- : R.drawable.thumb_bookmark_widget_folder_holo;
- views.setImageViewResource(R.id.thumb, thumbId);
- views.setImageViewResource(R.id.favicon,
- R.drawable.ic_bookmark_widget_bookmark_holo_dark);
- } else {
- // RemoteViews require a valid bitmap config.
- Options options = new Options();
- options.inPreferredConfig = Config.ARGB_8888;
-
- byte[] favicon = bookmark.favicon();
- if (favicon != null && favicon.length > 0) {
- views.setImageViewBitmap(R.id.favicon,
- BitmapFactory.decodeByteArray(favicon, 0, favicon.length, options));
- } else {
- views.setImageViewResource(R.id.favicon,
- org.chromium.chrome.R.drawable.globe_favicon);
- }
-
- byte[] thumbnail = bookmark.thumbnail();
- if (thumbnail != null && thumbnail.length > 0) {
- views.setImageViewBitmap(R.id.thumb,
- BitmapFactory.decodeByteArray(thumbnail, 0, thumbnail.length, options));
- } else {
- views.setImageViewResource(R.id.thumb, R.drawable.browser_thumbnail);
- }
- }
-
- Intent fillIn;
- if (!bookmark.isUrl()) {
- fillIn = new Intent(getChangeFolderAction(mContext))
- .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
- .putExtra(BookmarkColumns._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