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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java

Issue 2623993007: 🏠 Extract the ContentSuggestionManager interface from NTP (Closed)
Patch Set: Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.ntp.snippets; 5 package org.chromium.chrome.browser.ntp.snippets;
6 6
7 import android.annotation.SuppressLint; 7 import android.annotation.SuppressLint;
8 import android.content.res.Resources; 8 import android.content.res.Resources;
9 import android.graphics.Bitmap; 9 import android.graphics.Bitmap;
10 import android.graphics.drawable.BitmapDrawable; 10 import android.graphics.drawable.BitmapDrawable;
(...skipping 13 matching lines...) Expand all
24 import org.chromium.base.ApiCompatibilityUtils; 24 import org.chromium.base.ApiCompatibilityUtils;
25 import org.chromium.base.Callback; 25 import org.chromium.base.Callback;
26 import org.chromium.base.metrics.RecordHistogram; 26 import org.chromium.base.metrics.RecordHistogram;
27 import org.chromium.chrome.R; 27 import org.chromium.chrome.R;
28 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; 28 import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
29 import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallbac k; 29 import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallbac k;
30 import org.chromium.chrome.browser.ntp.ContextMenuManager; 30 import org.chromium.chrome.browser.ntp.ContextMenuManager;
31 import org.chromium.chrome.browser.ntp.ContextMenuManager.ContextMenuItemId; 31 import org.chromium.chrome.browser.ntp.ContextMenuManager.ContextMenuItemId;
32 import org.chromium.chrome.browser.ntp.ContextMenuManager.Delegate; 32 import org.chromium.chrome.browser.ntp.ContextMenuManager.Delegate;
33 import org.chromium.chrome.browser.ntp.DisplayStyleObserver; 33 import org.chromium.chrome.browser.ntp.DisplayStyleObserver;
34 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
35 import org.chromium.chrome.browser.ntp.UiConfig; 34 import org.chromium.chrome.browser.ntp.UiConfig;
36 import org.chromium.chrome.browser.ntp.cards.CardViewHolder; 35 import org.chromium.chrome.browser.ntp.cards.CardViewHolder;
37 import org.chromium.chrome.browser.ntp.cards.CardsVariationParameters; 36 import org.chromium.chrome.browser.ntp.cards.CardsVariationParameters;
38 import org.chromium.chrome.browser.ntp.cards.DisplayStyleObserverAdapter; 37 import org.chromium.chrome.browser.ntp.cards.DisplayStyleObserverAdapter;
39 import org.chromium.chrome.browser.ntp.cards.ImpressionTracker; 38 import org.chromium.chrome.browser.ntp.cards.ImpressionTracker;
40 import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView; 39 import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView;
41 import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo; 40 import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo;
41 import org.chromium.chrome.browser.suggestions.ContentSuggestionsManager;
42 import org.chromium.ui.mojom.WindowOpenDisposition; 42 import org.chromium.ui.mojom.WindowOpenDisposition;
43 43
44 import java.net.URI; 44 import java.net.URI;
45 import java.net.URISyntaxException; 45 import java.net.URISyntaxException;
46 import java.util.List; 46 import java.util.List;
47 import java.util.concurrent.TimeUnit; 47 import java.util.concurrent.TimeUnit;
48 48
49 /** 49 /**
50 * A class that represents the view for a single card snippet. 50 * A class that represents the view for a single card snippet.
51 */ 51 */
52 public class SnippetArticleViewHolder 52 public class SnippetArticleViewHolder
53 extends CardViewHolder implements ImpressionTracker.Listener, ContextMen uManager.Delegate { 53 extends CardViewHolder implements ImpressionTracker.Listener, ContextMen uManager.Delegate {
54 private static final String PUBLISHER_FORMAT_STRING = "%s - %s"; 54 private static final String PUBLISHER_FORMAT_STRING = "%s - %s";
55 private static final int FADE_IN_ANIMATION_TIME_MS = 300; 55 private static final int FADE_IN_ANIMATION_TIME_MS = 300;
56 private static final int[] FAVICON_SERVICE_SUPPORTED_SIZES = {16, 24, 32, 48 , 64}; 56 private static final int[] FAVICON_SERVICE_SUPPORTED_SIZES = {16, 24, 32, 48 , 64};
57 private static final String FAVICON_SERVICE_FORMAT = 57 private static final String FAVICON_SERVICE_FORMAT =
58 "https://s2.googleusercontent.com/s2/favicons?domain=%s&src=chrome_n ewtab_mobile&sz=%d&alt=404"; 58 "https://s2.googleusercontent.com/s2/favicons?domain=%s&src=chrome_n ewtab_mobile&sz=%d&alt=404";
59 59
60 public static final int PARTIAL_UPDATE_OFFLINE_ID = 1; 60 public static final int PARTIAL_UPDATE_OFFLINE_ID = 1;
61 61
62 private final NewTabPageManager mNewTabPageManager; 62 private final ContentSuggestionsManager mContentSuggestionsManager;
63 private final TextView mHeadlineTextView; 63 private final TextView mHeadlineTextView;
64 private final TextView mPublisherTextView; 64 private final TextView mPublisherTextView;
65 private final TextView mArticleSnippetTextView; 65 private final TextView mArticleSnippetTextView;
66 private final ImageView mThumbnailView; 66 private final ImageView mThumbnailView;
67 private final ImageView mOfflineBadge; 67 private final ImageView mOfflineBadge;
68 private final View mPublisherBar; 68 private final View mPublisherBar;
69 69
70 private FetchImageCallback mImageCallback; 70 private FetchImageCallback mImageCallback;
71 private SnippetArticle mArticle; 71 private SnippetArticle mArticle;
72 private SuggestionsCategoryInfo mCategoryInfo; 72 private SuggestionsCategoryInfo mCategoryInfo;
73 private int mPublisherFaviconSizePx; 73 private int mPublisherFaviconSizePx;
74 74
75 private final boolean mUseFaviconService; 75 private final boolean mUseFaviconService;
76 private final UiConfig mUiConfig; 76 private final UiConfig mUiConfig;
77 77
78 /** 78 /**
79 * Constructs a {@link SnippetArticleViewHolder} item used to display snippe ts. 79 * Constructs a {@link SnippetArticleViewHolder} item used to display snippe ts.
80 * 80 * @param parent The NewTabPageRecyclerView that is going to contain the ne wly created view.
81 * @param parent The NewTabPageRecyclerView that is going to contain the new ly created view. 81 * @param contextMenuManager
82 * @param manager The NewTabPageManager object used to open an article. 82 * @param manager The NewTabPageManager object used to open an article.
83 * @param uiConfig The NTP UI configuration object used to adjust the articl e UI. 83 * @param uiConfig The NTP UI configuration object used to adjust the articl e UI.
84 */ 84 */
85 public SnippetArticleViewHolder(NewTabPageRecyclerView parent, NewTabPageMan ager manager, 85 public SnippetArticleViewHolder(NewTabPageRecyclerView parent,
86 ContextMenuManager contextMenuManager, ContentSuggestionsManager man ager,
86 UiConfig uiConfig) { 87 UiConfig uiConfig) {
87 super(R.layout.new_tab_page_snippets_card, parent, uiConfig, manager); 88 super(R.layout.new_tab_page_snippets_card, parent, uiConfig, contextMenu Manager);
88 89
89 mNewTabPageManager = manager; 90 mContentSuggestionsManager = manager;
90 mThumbnailView = (ImageView) itemView.findViewById(R.id.article_thumbnai l); 91 mThumbnailView = (ImageView) itemView.findViewById(R.id.article_thumbnai l);
91 mHeadlineTextView = (TextView) itemView.findViewById(R.id.article_headli ne); 92 mHeadlineTextView = (TextView) itemView.findViewById(R.id.article_headli ne);
92 mPublisherTextView = (TextView) itemView.findViewById(R.id.article_publi sher); 93 mPublisherTextView = (TextView) itemView.findViewById(R.id.article_publi sher);
93 mArticleSnippetTextView = (TextView) itemView.findViewById(R.id.article_ snippet); 94 mArticleSnippetTextView = (TextView) itemView.findViewById(R.id.article_ snippet);
94 mPublisherBar = itemView.findViewById(R.id.publisher_bar); 95 mPublisherBar = itemView.findViewById(R.id.publisher_bar);
95 mOfflineBadge = (ImageView) itemView.findViewById(R.id.offline_icon); 96 mOfflineBadge = (ImageView) itemView.findViewById(R.id.offline_icon);
96 97
97 new ImpressionTracker(itemView, this); 98 new ImpressionTracker(itemView, this);
98 99
99 mUiConfig = uiConfig; 100 mUiConfig = uiConfig;
100 new DisplayStyleObserverAdapter(itemView, uiConfig, new DisplayStyleObse rver() { 101 new DisplayStyleObserverAdapter(itemView, uiConfig, new DisplayStyleObse rver() {
101 @Override 102 @Override
102 public void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisp layStyle) { 103 public void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisp layStyle) {
103 updateLayout(); 104 updateLayout();
104 } 105 }
105 }); 106 });
106 107
107 mUseFaviconService = CardsVariationParameters.isFaviconServiceEnabled(); 108 mUseFaviconService = CardsVariationParameters.isFaviconServiceEnabled();
108 } 109 }
109 110
110 @Override 111 @Override
111 public void onImpression() { 112 public void onImpression() {
112 if (mArticle != null && mArticle.trackImpression()) { 113 if (mArticle != null && mArticle.trackImpression()) {
113 mNewTabPageManager.trackSnippetImpression(mArticle); 114 mContentSuggestionsManager.trackSnippetImpression(mArticle);
114 mRecyclerView.onSnippetImpression(); 115 mRecyclerView.onSnippetImpression();
115 } 116 }
116 } 117 }
117 118
118 @Override 119 @Override
119 public void onCardTapped() { 120 public void onCardTapped() {
120 mNewTabPageManager.openSnippet(WindowOpenDisposition.CURRENT_TAB, mArtic le); 121 mContentSuggestionsManager.openSnippet(WindowOpenDisposition.CURRENT_TAB , mArticle);
121 } 122 }
122 123
123 @Override 124 @Override
124 public void openItem(int windowDisposition) { 125 public void openItem(int windowDisposition) {
125 mNewTabPageManager.openSnippet(windowDisposition, mArticle); 126 mContentSuggestionsManager.openSnippet(windowDisposition, mArticle);
126 } 127 }
127 128
128 @Override 129 @Override
129 public void removeItem() { 130 public void removeItem() {
130 getRecyclerView().dismissItemWithAnimation(this); 131 getRecyclerView().dismissItemWithAnimation(this);
131 } 132 }
132 133
133 @Override 134 @Override
134 public String getUrl() { 135 public String getUrl() {
135 return mArticle.mUrl; 136 return mArticle.mUrl;
136 } 137 }
137 138
138 @Override 139 @Override
139 public boolean isItemSupported(@ContextMenuItemId int menuItemId) { 140 public boolean isItemSupported(@ContextMenuItemId int menuItemId) {
140 if (mArticle.isDownload()) { 141 if (mArticle.isDownload()) {
141 if (menuItemId == ContextMenuManager.ID_OPEN_IN_INCOGNITO_TAB) retur n false; 142 if (menuItemId == ContextMenuManager.ID_OPEN_IN_INCOGNITO_TAB) retur n false;
142 if (menuItemId == ContextMenuManager.ID_SAVE_FOR_OFFLINE) return fal se; 143 if (menuItemId == ContextMenuManager.ID_SAVE_FOR_OFFLINE) return fal se;
143 return true; 144 return true;
144 } 145 }
145 if (mArticle.isRecentTab()) { 146 if (mArticle.isRecentTab()) {
146 if (menuItemId == ContextMenuManager.ID_REMOVE) return true; 147 if (menuItemId == ContextMenuManager.ID_REMOVE) return true;
147 return false; 148 return false;
148 } 149 }
149 return true; 150 return true;
150 } 151 }
151 152
152 @Override 153 @Override
153 public void onContextMenuCreated() { 154 public void onContextMenuCreated() {
154 mNewTabPageManager.trackSnippetMenuOpened(mArticle); 155 mContentSuggestionsManager.trackSnippetMenuOpened(mArticle);
155 } 156 }
156 157
157 @Override 158 @Override
158 protected Delegate getContextMenuDelegate() { 159 protected Delegate getContextMenuDelegate() {
159 return this; 160 return this;
160 } 161 }
161 162
162 /** 163 /**
163 * Updates the layout taking into account screen dimensions and the type of snippet displayed. 164 * Updates the layout taking into account screen dimensions and the type of snippet displayed.
164 */ 165 */
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 cancelImageFetch(); 252 cancelImageFetch();
252 253
253 // If the article has a thumbnail already, reuse it. Otherwise start a f etch. 254 // If the article has a thumbnail already, reuse it. Otherwise start a f etch.
254 // mThumbnailView's visibility is modified in updateLayout(). 255 // mThumbnailView's visibility is modified in updateLayout().
255 if (mThumbnailView.getVisibility() == View.VISIBLE) { 256 if (mThumbnailView.getVisibility() == View.VISIBLE) {
256 if (mArticle.getThumbnailBitmap() != null) { 257 if (mArticle.getThumbnailBitmap() != null) {
257 mThumbnailView.setImageBitmap(mArticle.getThumbnailBitmap()); 258 mThumbnailView.setImageBitmap(mArticle.getThumbnailBitmap());
258 } else { 259 } else {
259 mThumbnailView.setImageResource(R.drawable.ic_snippet_thumbnail_ placeholder); 260 mThumbnailView.setImageResource(R.drawable.ic_snippet_thumbnail_ placeholder);
260 mImageCallback = new FetchImageCallback(this, mArticle); 261 mImageCallback = new FetchImageCallback(this, mArticle);
261 mNewTabPageManager.getSuggestionsSource() 262 mContentSuggestionsManager.getSuggestionsSource().fetchSuggestio nImage(
262 .fetchSuggestionImage(mArticle, mImageCallback); 263 mArticle, mImageCallback);
263 } 264 }
264 } 265 }
265 266
266 // Set the favicon of the publisher. 267 // Set the favicon of the publisher.
267 try { 268 try {
268 fetchFaviconFromLocalCache(new URI(mArticle.mUrl), true); 269 fetchFaviconFromLocalCache(new URI(mArticle.mUrl), true);
269 } catch (URISyntaxException e) { 270 } catch (URISyntaxException e) {
270 setDefaultFaviconOnView(); 271 setDefaultFaviconOnView();
271 } 272 }
272 273
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 // image may have transparency and we don't want the previous image show ing up behind. 338 // image may have transparency and we don't want the previous image show ing up behind.
338 Drawable[] layers = {mThumbnailView.getDrawable(), 339 Drawable[] layers = {mThumbnailView.getDrawable(),
339 new BitmapDrawable(mThumbnailView.getResources(), scaledThumbnai l)}; 340 new BitmapDrawable(mThumbnailView.getResources(), scaledThumbnai l)};
340 TransitionDrawable transitionDrawable = new TransitionDrawable(layers); 341 TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
341 mThumbnailView.setImageDrawable(transitionDrawable); 342 mThumbnailView.setImageDrawable(transitionDrawable);
342 transitionDrawable.setCrossFadeEnabled(true); 343 transitionDrawable.setCrossFadeEnabled(true);
343 transitionDrawable.startTransition(FADE_IN_ANIMATION_TIME_MS); 344 transitionDrawable.startTransition(FADE_IN_ANIMATION_TIME_MS);
344 } 345 }
345 346
346 private void fetchFaviconFromLocalCache(final URI snippetUri, final boolean fallbackToService) { 347 private void fetchFaviconFromLocalCache(final URI snippetUri, final boolean fallbackToService) {
347 mNewTabPageManager.getLocalFaviconImageForURL( 348 mContentSuggestionsManager.getLocalFaviconImageForURL(
348 getSnippetDomain(snippetUri), mPublisherFaviconSizePx, new Favic onImageCallback() { 349 getSnippetDomain(snippetUri), mPublisherFaviconSizePx, new Favic onImageCallback() {
349 @Override 350 @Override
350 public void onFaviconAvailable(Bitmap image, String iconUrl) { 351 public void onFaviconAvailable(Bitmap image, String iconUrl) {
351 if (image == null && fallbackToService) { 352 if (image == null && fallbackToService) {
352 fetchFaviconFromService(snippetUri); 353 fetchFaviconFromService(snippetUri);
353 return; 354 return;
354 } 355 }
355 setFaviconOnView(image); 356 setFaviconOnView(image);
356 } 357 }
357 }); 358 });
358 } 359 }
359 360
360 // TODO(crbug.com/635567): Fix this properly. 361 // TODO(crbug.com/635567): Fix this properly.
361 @SuppressLint("DefaultLocale") 362 @SuppressLint("DefaultLocale")
362 private void fetchFaviconFromService(final URI snippetUri) { 363 private void fetchFaviconFromService(final URI snippetUri) {
363 // Show the default favicon immediately. 364 // Show the default favicon immediately.
364 setDefaultFaviconOnView(); 365 setDefaultFaviconOnView();
365 366
366 if (!mUseFaviconService) return; 367 if (!mUseFaviconService) return;
367 int sizePx = getFaviconServiceSupportedSize(); 368 int sizePx = getFaviconServiceSupportedSize();
368 if (sizePx == 0) return; 369 if (sizePx == 0) return;
369 370
370 // Replace the default icon by another one from the service when it is f etched. 371 // Replace the default icon by another one from the service when it is f etched.
371 mNewTabPageManager.ensureIconIsAvailable( 372 mContentSuggestionsManager.ensureIconIsAvailable(
372 getSnippetDomain(snippetUri), // Store to the cache for the whol e domain. 373 getSnippetDomain(snippetUri), // Store to the cache for the whol e domain.
373 String.format(FAVICON_SERVICE_FORMAT, snippetUri.getHost(), size Px), 374 String.format(FAVICON_SERVICE_FORMAT, snippetUri.getHost(), size Px),
374 /*useLargeIcon=*/false, /*isTemporary=*/true, new IconAvailabili tyCallback() { 375 /*useLargeIcon=*/false, /*isTemporary=*/true, new IconAvailabili tyCallback() {
375 @Override 376 @Override
376 public void onIconAvailabilityChecked(boolean newlyAvailable ) { 377 public void onIconAvailabilityChecked(boolean newlyAvailable ) {
377 if (!newlyAvailable) return; 378 if (!newlyAvailable) return;
378 // The download succeeded, the favicon is in the cache; fetch it. 379 // The download succeeded, the favicon is in the cache; fetch it.
379 fetchFaviconFromLocalCache(snippetUri, /*fallbackToServi ce=*/false); 380 fetchFaviconFromLocalCache(snippetUri, /*fallbackToServi ce=*/false);
380 } 381 }
381 }); 382 });
(...skipping 29 matching lines...) Expand all
411 ApiCompatibilityUtils.setCompoundDrawablesRelative( 412 ApiCompatibilityUtils.setCompoundDrawablesRelative(
412 mPublisherTextView, drawable, null, null, null); 413 mPublisherTextView, drawable, null, null, null);
413 mPublisherTextView.setVisibility(View.VISIBLE); 414 mPublisherTextView.setVisibility(View.VISIBLE);
414 } 415 }
415 416
416 @Override 417 @Override
417 public boolean isDismissable() { 418 public boolean isDismissable() {
418 return !isPeeking(); 419 return !isPeeking();
419 } 420 }
420 } 421 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698