OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.cards; | 5 package org.chromium.chrome.browser.ntp.cards; |
6 | 6 |
7 import org.chromium.base.Callback; | 7 import org.chromium.base.Callback; |
8 import org.chromium.base.Log; | 8 import org.chromium.base.Log; |
9 import org.chromium.base.VisibleForTesting; | 9 import org.chromium.base.VisibleForTesting; |
10 import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver; | 10 import org.chromium.chrome.browser.ntp.NewTabPage.DestructionObserver; |
11 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; | 11 import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; |
12 import org.chromium.chrome.browser.ntp.snippets.CategoryInt; | 12 import org.chromium.chrome.browser.ntp.snippets.CategoryInt; |
13 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnu
m; | 13 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnu
m; |
14 import org.chromium.chrome.browser.ntp.snippets.SectionHeader; | 14 import org.chromium.chrome.browser.ntp.snippets.SectionHeader; |
15 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; | 15 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; |
16 import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; | 16 import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; |
17 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; | 17 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; |
18 import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; | 18 import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; |
19 import org.chromium.chrome.browser.offlinepages.ClientId; | 19 import org.chromium.chrome.browser.offlinepages.ClientId; |
20 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; | 20 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; |
21 import org.chromium.chrome.browser.offlinepages.OfflinePageItem; | 21 import org.chromium.chrome.browser.offlinepages.OfflinePageItem; |
| 22 import org.chromium.chrome.browser.suggestions.SuggestionsRanker; |
22 | 23 |
23 import java.util.ArrayList; | 24 import java.util.ArrayList; |
24 import java.util.Iterator; | 25 import java.util.Iterator; |
25 import java.util.List; | 26 import java.util.List; |
26 | 27 |
27 /** | 28 /** |
28 * A group of suggestions, with a header, a status card, and a progress indicato
r. This is | 29 * A group of suggestions, with a header, a status card, and a progress indicato
r. This is |
29 * responsible for tracking whether its suggestions have been saved offline. | 30 * responsible for tracking whether its suggestions have been saved offline. |
30 */ | 31 */ |
31 public class SuggestionsSection extends InnerNode { | 32 public class SuggestionsSection extends InnerNode { |
32 private static final String TAG = "NtpCards"; | 33 private static final String TAG = "NtpCards"; |
33 | 34 |
34 private final Delegate mDelegate; | 35 private final Delegate mDelegate; |
35 private final SuggestionsCategoryInfo mCategoryInfo; | 36 private final SuggestionsCategoryInfo mCategoryInfo; |
36 private final OfflinePageBridge mOfflinePageBridge; | 37 private final OfflinePageBridge mOfflinePageBridge; |
| 38 private final SuggestionsRanker mSuggestionsRanker; |
37 | 39 |
38 // Children | 40 // Children |
39 private final SectionHeader mHeader; | 41 private final SectionHeader mHeader; |
40 private final SuggestionsList mSuggestionsList; | 42 private final SuggestionsList mSuggestionsList; |
41 private final StatusItem mStatus; | 43 private final StatusItem mStatus; |
42 private final ActionItem mMoreButton; | 44 private final ActionItem mMoreButton; |
43 private final ProgressItem mProgressIndicator; | 45 private final ProgressItem mProgressIndicator; |
44 | 46 |
45 private boolean mIsNtpDestroyed; | 47 private boolean mIsNtpDestroyed; |
46 | 48 |
47 // Keep track of impressions of the suggestions so that we replace only sugg
estions that | 49 // Keep track of impressions of the suggestions so that we replace only sugg
estions that |
48 // have not been impressed, yet. We keep track of the first suggestion separ
ately as the | 50 // have not been impressed, yet. We keep track of the first suggestion separ
ately as the |
49 // first is often impressed in the form of a peeking card and we still want
to be able to | 51 // first is often impressed in the form of a peeking card and we still want
to be able to |
50 // replace something in this case. | 52 // replace something in this case. |
51 private boolean mFirstSuggestionSeen; | 53 private boolean mFirstSuggestionSeen; |
52 private boolean mSubsequentSuggestionsSeen; | 54 private boolean mSubsequentSuggestionsSeen; |
53 | 55 |
54 /** | 56 /** |
55 * Delegate interface that allows dismissing this section without introducin
g | 57 * Delegate interface that allows dismissing this section without introducin
g |
56 * a circular dependency. | 58 * a circular dependency. |
57 */ | 59 */ |
58 public interface Delegate { | 60 public interface Delegate { |
59 void dismissSection(SuggestionsSection section); | 61 void dismissSection(SuggestionsSection section); |
60 } | 62 } |
61 | 63 |
62 public SuggestionsSection(Delegate delegate, NewTabPageManager manager, | 64 public SuggestionsSection(Delegate delegate, NewTabPageManager manager, |
63 OfflinePageBridge offlinePageBridge, SuggestionsCategoryInfo info) { | 65 SuggestionsRanker ranker, OfflinePageBridge offlinePageBridge, |
| 66 SuggestionsCategoryInfo info) { |
64 mDelegate = delegate; | 67 mDelegate = delegate; |
65 mCategoryInfo = info; | 68 mCategoryInfo = info; |
66 mOfflinePageBridge = offlinePageBridge; | 69 mOfflinePageBridge = offlinePageBridge; |
| 70 mSuggestionsRanker = ranker; |
67 | 71 |
68 mHeader = new SectionHeader(info.getTitle()); | 72 mHeader = new SectionHeader(info.getTitle()); |
69 mSuggestionsList = new SuggestionsList(manager, info); | 73 mSuggestionsList = new SuggestionsList(manager, info); |
70 mStatus = StatusItem.createNoSuggestionsItem(info); | 74 mStatus = StatusItem.createNoSuggestionsItem(info); |
71 mMoreButton = new ActionItem(this); | 75 mMoreButton = new ActionItem(this, ranker); |
72 mProgressIndicator = new ProgressItem(); | 76 mProgressIndicator = new ProgressItem(); |
73 addChildren(mHeader, mSuggestionsList, mStatus, mMoreButton, mProgressIn
dicator); | 77 addChildren(mHeader, mSuggestionsList, mStatus, mMoreButton, mProgressIn
dicator); |
74 | 78 |
75 setupOfflinePageBridgeObserver(manager); | 79 setupOfflinePageBridgeObserver(manager); |
76 refreshChildrenVisibility(); | 80 refreshChildrenVisibility(); |
77 } | 81 } |
78 | 82 |
79 private static class SuggestionsList extends ChildNode implements Iterable<S
nippetArticle> { | 83 private static class SuggestionsList extends ChildNode implements Iterable<S
nippetArticle> { |
80 private final List<SnippetArticle> mSuggestions = new ArrayList<>(); | 84 private final List<SnippetArticle> mSuggestions = new ArrayList<>(); |
81 private final NewTabPageManager mNewTabPageManager; | 85 private final NewTabPageManager mNewTabPageManager; |
82 private final SuggestionsCategoryInfo mCategoryInfo; | 86 private final SuggestionsCategoryInfo mCategoryInfo; |
83 private int mCategoryIndex; | |
84 | 87 |
85 public SuggestionsList(NewTabPageManager newTabPageManager, | 88 public SuggestionsList(NewTabPageManager newTabPageManager, |
86 SuggestionsCategoryInfo categoryInfo) { | 89 SuggestionsCategoryInfo categoryInfo) { |
87 mNewTabPageManager = newTabPageManager; | 90 mNewTabPageManager = newTabPageManager; |
88 mCategoryInfo = categoryInfo; | 91 mCategoryInfo = categoryInfo; |
89 } | 92 } |
90 | 93 |
91 public void setCategoryIndex(int categoryIndex) { | |
92 mCategoryIndex = categoryIndex; | |
93 } | |
94 | |
95 public int getCategoryIndex() { | |
96 return mCategoryIndex; | |
97 } | |
98 | |
99 @Override | 94 @Override |
100 public int getItemCount() { | 95 public int getItemCount() { |
101 return mSuggestions.size(); | 96 return mSuggestions.size(); |
102 } | 97 } |
103 | 98 |
104 @Override | 99 @Override |
105 @ItemViewType | 100 @ItemViewType |
106 public int getItemViewType(int position) { | 101 public int getItemViewType(int position) { |
107 checkIndex(position); | 102 checkIndex(position); |
108 return ItemViewType.SNIPPET; | 103 return ItemViewType.SNIPPET; |
109 } | 104 } |
110 | 105 |
111 @Override | 106 @Override |
112 public void onBindViewHolder( | 107 public void onBindViewHolder( |
113 NewTabPageViewHolder holder, int position, List<Object> payloads
) { | 108 NewTabPageViewHolder holder, int position, List<Object> payloads
) { |
114 checkIndex(position); | 109 checkIndex(position); |
115 assert holder instanceof SnippetArticleViewHolder; | 110 assert holder instanceof SnippetArticleViewHolder; |
116 ((SnippetArticleViewHolder) holder) | 111 ((SnippetArticleViewHolder) holder) |
117 .onBindViewHolder( | 112 .onBindViewHolder(getSuggestionAt(position), mCategoryInfo,
payloads); |
118 getSuggestionAt(position), mCategoryInfo, payloads,
mCategoryIndex); | |
119 } | 113 } |
120 | 114 |
121 @Override | 115 @Override |
122 public SnippetArticle getSuggestionAt(int position) { | 116 public SnippetArticle getSuggestionAt(int position) { |
123 return mSuggestions.get(position); | 117 return mSuggestions.get(position); |
124 } | 118 } |
125 | 119 |
126 @Override | 120 @Override |
127 public int getDismissSiblingPosDelta(int position) { | 121 public int getDismissSiblingPosDelta(int position) { |
128 checkIndex(position); | 122 checkIndex(position); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 Log.d(TAG, "setSuggestions: removing all suggestions"); | 346 Log.d(TAG, "setSuggestions: removing all suggestions"); |
353 mSuggestionsList.clear(); | 347 mSuggestionsList.clear(); |
354 } | 348 } |
355 } | 349 } |
356 | 350 |
357 mProgressIndicator.setVisible(SnippetsBridge.isCategoryLoading(status)); | 351 mProgressIndicator.setVisible(SnippetsBridge.isCategoryLoading(status)); |
358 | 352 |
359 mSuggestionsList.addAll(suggestions); | 353 mSuggestionsList.addAll(suggestions); |
360 | 354 |
361 for (SnippetArticle article : suggestions) { | 355 for (SnippetArticle article : suggestions) { |
| 356 mSuggestionsRanker.rankSuggestion(article); |
362 if (!article.requiresExactOfflinePage()) { | 357 if (!article.requiresExactOfflinePage()) { |
363 updateSnippetOfflineAvailability(article); | 358 updateSnippetOfflineAvailability(article); |
364 } | 359 } |
365 } | 360 } |
366 | 361 |
367 refreshChildrenVisibility(); | 362 refreshChildrenVisibility(); |
368 } | 363 } |
369 | 364 |
370 private void updateSnippetOfflineAvailability(final SnippetArticle article)
{ | 365 private void updateSnippetOfflineAvailability(final SnippetArticle article)
{ |
371 // This method is not applicable to articles for which the exact offline
id must specified. | 366 // This method is not applicable to articles for which the exact offline
id must specified. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 // The sibling of the status card is the more button when it exists, sho
uld be right below. | 424 // The sibling of the status card is the more button when it exists, sho
uld be right below. |
430 if (child == mStatus) return 1; | 425 if (child == mStatus) return 1; |
431 | 426 |
432 return 0; | 427 return 0; |
433 } | 428 } |
434 | 429 |
435 public SuggestionsCategoryInfo getCategoryInfo() { | 430 public SuggestionsCategoryInfo getCategoryInfo() { |
436 return mCategoryInfo; | 431 return mCategoryInfo; |
437 } | 432 } |
438 | 433 |
439 public int getCategoryIndex() { | |
440 return mSuggestionsList.getCategoryIndex(); | |
441 } | |
442 | |
443 public void setCategoryIndex(int categoryIndex) { | |
444 mSuggestionsList.setCategoryIndex(categoryIndex); | |
445 } | |
446 | |
447 public String getHeaderText() { | 434 public String getHeaderText() { |
448 return mHeader.getHeaderText(); | 435 return mHeader.getHeaderText(); |
449 } | 436 } |
450 | 437 |
451 /** | 438 /** |
452 * @return The progress indicator. | 439 * @return The progress indicator. |
453 */ | 440 */ |
454 @VisibleForTesting | 441 @VisibleForTesting |
455 ProgressItem getProgressItemForTesting() { | 442 ProgressItem getProgressItemForTesting() { |
456 return mProgressIndicator; | 443 return mProgressIndicator; |
457 } | 444 } |
458 | 445 |
459 @VisibleForTesting | 446 @VisibleForTesting |
460 ActionItem getActionItem() { | 447 ActionItem getActionItem() { |
461 return mMoreButton; | 448 return mMoreButton; |
462 } | 449 } |
463 | 450 |
464 @VisibleForTesting | 451 @VisibleForTesting |
465 StatusItem getStatusItem() { | 452 StatusItem getStatusItem() { |
466 return mStatus; | 453 return mStatus; |
467 } | 454 } |
468 } | 455 } |
OLD | NEW |