Commit 6c65a58b authored by bauerb's avatar bauerb Committed by Commit bot

[Android NTP] Reduce API surface of NewTabPageAdapter.

Remove:
* getSignInPromoPosition()
* getSuggestionPosition()

Change to default visibility:
* getBottomSpacerPosition()
* getLastContentItemPosition()

Change to private:
* hasAllBeenDismissed()
* getSuggestionsSection()
* getChildPositionOffset()

Two methods are added for tests:
* getSectionForTesting()
* getRootForTesting()

BUG=616090

Review-Url: https://codereview.chromium.org/2532953002
Cr-Commit-Position: refs/heads/master@{#436327}
parent 78660e87
...@@ -32,7 +32,6 @@ import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; ...@@ -32,7 +32,6 @@ import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -118,10 +117,10 @@ public class NewTabPageAdapter ...@@ -118,10 +117,10 @@ public class NewTabPageAdapter
// We use our own implementation of the dismissal animation, so we don't call the // We use our own implementation of the dismissal animation, so we don't call the
// parent implementation. (by default it changes the translation-X and elevation) // parent implementation. (by default it changes the translation-X and elevation)
mRecyclerView.updateViewStateForDismiss(dX, viewHolder); mRecyclerView.updateViewStateForDismiss(dX, (NewTabPageViewHolder) viewHolder);
// If there is another item that should be animated at the same time, do the same to it. // If there is another item that should be animated at the same time, do the same to it.
ViewHolder siblingViewHolder = getDismissSibling(viewHolder); NewTabPageViewHolder siblingViewHolder = getDismissSibling(viewHolder);
if (siblingViewHolder != null) { if (siblingViewHolder != null) {
mRecyclerView.updateViewStateForDismiss(dX, siblingViewHolder); mRecyclerView.updateViewStateForDismiss(dX, siblingViewHolder);
} }
...@@ -388,26 +387,14 @@ public class NewTabPageAdapter ...@@ -388,26 +387,14 @@ public class NewTabPageAdapter
return RecyclerView.NO_POSITION; return RecyclerView.NO_POSITION;
} }
public int getSignInPromoPosition() { int getBottomSpacerPosition() {
return getChildPositionOffset(mSigninPromo);
}
public int getBottomSpacerPosition() {
return getChildPositionOffset(mBottomSpacer); return getChildPositionOffset(mBottomSpacer);
} }
public int getLastContentItemPosition() { int getLastContentItemPosition() {
return getChildPositionOffset(hasAllBeenDismissed() ? mAllDismissed : mFooter); return getChildPositionOffset(hasAllBeenDismissed() ? mAllDismissed : mFooter);
} }
public int getSuggestionPosition(SnippetArticle article) {
for (int i = 0; i < mRoot.getItemCount(); i++) {
SnippetArticle articleToCheck = mRoot.getSuggestionAt(i);
if (articleToCheck != null && articleToCheck.equals(article)) return i;
}
return RecyclerView.NO_POSITION;
}
private void setSuggestions(@CategoryInt int category, List<SnippetArticle> suggestions, private void setSuggestions(@CategoryInt int category, List<SnippetArticle> suggestions,
@CategoryStatusEnum int status) { @CategoryStatusEnum int status) {
// Count the number of suggestions before this category. // Count the number of suggestions before this category.
...@@ -560,24 +547,16 @@ public class NewTabPageAdapter ...@@ -560,24 +547,16 @@ public class NewTabPageAdapter
/** /**
* Returns another view holder that should be dismissed at the same time as the provided one. * Returns another view holder that should be dismissed at the same time as the provided one.
*/ */
public ViewHolder getDismissSibling(ViewHolder viewHolder) { public NewTabPageViewHolder getDismissSibling(ViewHolder viewHolder) {
int swipePos = viewHolder.getAdapterPosition(); int swipePos = viewHolder.getAdapterPosition();
int siblingPosDelta = mRoot.getDismissSiblingPosDelta(swipePos); int siblingPosDelta = mRoot.getDismissSiblingPosDelta(swipePos);
if (siblingPosDelta == 0) return null; if (siblingPosDelta == 0) return null;
return mRecyclerView.findViewHolderForAdapterPosition(siblingPosDelta + swipePos); return (NewTabPageViewHolder) mRecyclerView.findViewHolderForAdapterPosition(
siblingPosDelta + swipePos);
} }
/** private boolean hasAllBeenDismissed() {
* @return The info associated to the provided category.
* @throws NullPointerException if {@code category} isn't currently registered with the adapter.
* */
public SuggestionsCategoryInfo getCategoryInfo(@CategoryInt int category) {
return mSections.get(category).getCategoryInfo();
}
@VisibleForTesting
public boolean hasAllBeenDismissed() {
return mSections.isEmpty() && !mSigninPromo.isVisible(); return mSections.isEmpty() && !mSigninPromo.isVisible();
} }
...@@ -601,20 +580,13 @@ public class NewTabPageAdapter ...@@ -601,20 +580,13 @@ public class NewTabPageAdapter
* @return Returns the {@link SuggestionsSection} that contains the item at * @return Returns the {@link SuggestionsSection} that contains the item at
* {@code itemPosition}, or null if the item is not part of one. * {@code itemPosition}, or null if the item is not part of one.
*/ */
@VisibleForTesting private SuggestionsSection getSuggestionsSection(int itemPosition) {
SuggestionsSection getSuggestionsSection(int itemPosition) {
TreeNode child = mRoot.getChildForPosition(itemPosition); TreeNode child = mRoot.getChildForPosition(itemPosition);
if (!(child instanceof SuggestionsSection)) return null; if (!(child instanceof SuggestionsSection)) return null;
return (SuggestionsSection) child; return (SuggestionsSection) child;
} }
@VisibleForTesting private int getChildPositionOffset(TreeNode child) {
List<TreeNode> getChildren() {
return Collections.unmodifiableList(mChildren);
}
@VisibleForTesting
int getChildPositionOffset(TreeNode child) {
return mRoot.getStartingOffsetForChild(child); return mRoot.getStartingOffsetForChild(child);
} }
...@@ -632,12 +604,20 @@ public class NewTabPageAdapter ...@@ -632,12 +604,20 @@ public class NewTabPageAdapter
return RecyclerView.NO_POSITION; return RecyclerView.NO_POSITION;
} }
private void announceItemRemoved(String suggestionTitle) { SuggestionsSection getSectionForTesting(@CategoryInt int category) {
return mSections.get(category);
}
InnerNode getRootForTesting() {
return mRoot;
}
private void announceItemRemoved(String itemTitle) {
// In tests the RecyclerView can be null. // In tests the RecyclerView can be null.
if (mRecyclerView == null) return; if (mRecyclerView == null) return;
mRecyclerView.announceForAccessibility(mRecyclerView.getResources().getString( mRecyclerView.announceForAccessibility(mRecyclerView.getResources().getString(
R.string.ntp_accessibility_item_removed, suggestionTitle)); R.string.ntp_accessibility_item_removed, itemTitle));
} }
private void announceItemRemoved(@StringRes int stringToAnnounce) { private void announceItemRemoved(@StringRes int stringToAnnounce) {
......
...@@ -185,7 +185,7 @@ public class NewTabPageRecyclerView extends RecyclerView implements TouchDisable ...@@ -185,7 +185,7 @@ public class NewTabPageRecyclerView extends RecyclerView implements TouchDisable
* Updates the space added at the end of the list to make sure the above/below the fold * Updates the space added at the end of the list to make sure the above/below the fold
* distinction can be preserved. * distinction can be preserved.
*/ */
public void refreshBottomSpacing() { private void refreshBottomSpacing() {
ViewHolder bottomSpacingViewHolder = findBottomSpacer(); ViewHolder bottomSpacingViewHolder = findBottomSpacer();
// It might not be in the layout yet if it's not visible or ready to be displayed. // It might not be in the layout yet if it's not visible or ready to be displayed.
...@@ -536,8 +536,8 @@ public class NewTabPageRecyclerView extends RecyclerView implements TouchDisable ...@@ -536,8 +536,8 @@ public class NewTabPageRecyclerView extends RecyclerView implements TouchDisable
* @param dX The amount of horizontal displacement caused by user's action. * @param dX The amount of horizontal displacement caused by user's action.
* @param viewHolder The view holder containing the view to be updated. * @param viewHolder The view holder containing the view to be updated.
*/ */
public void updateViewStateForDismiss(float dX, ViewHolder viewHolder) { public void updateViewStateForDismiss(float dX, NewTabPageViewHolder viewHolder) {
if (!((NewTabPageViewHolder) viewHolder).isDismissable()) return; if (!viewHolder.isDismissable()) return;
viewHolder.itemView.setTranslationX(dX); viewHolder.itemView.setTranslationX(dX);
......
...@@ -50,7 +50,7 @@ public class SuggestionsSection extends InnerNode { ...@@ -50,7 +50,7 @@ public class SuggestionsSection extends InnerNode {
mOfflinePageBridge = offlinePageBridge; mOfflinePageBridge = offlinePageBridge;
mHeader = new SectionHeader(info.getTitle()); mHeader = new SectionHeader(info.getTitle());
mSuggestionsList = new SuggestionsList(this); mSuggestionsList = new SuggestionsList(this, info);
mStatus = StatusItem.createNoSuggestionsItem(this); mStatus = StatusItem.createNoSuggestionsItem(this);
mMoreButton = new ActionItem(this); mMoreButton = new ActionItem(this);
mProgressIndicator = new ProgressItem(this); mProgressIndicator = new ProgressItem(this);
...@@ -61,9 +61,11 @@ public class SuggestionsSection extends InnerNode { ...@@ -61,9 +61,11 @@ public class SuggestionsSection extends InnerNode {
private static class SuggestionsList extends ChildNode implements Iterable<SnippetArticle> { private static class SuggestionsList extends ChildNode implements Iterable<SnippetArticle> {
private final List<SnippetArticle> mSuggestions = new ArrayList<>(); private final List<SnippetArticle> mSuggestions = new ArrayList<>();
private final SuggestionsCategoryInfo mCategoryInfo;
public SuggestionsList(NodeParent parent) { public SuggestionsList(NodeParent parent, SuggestionsCategoryInfo categoryInfo) {
super(parent); super(parent);
mCategoryInfo = categoryInfo;
} }
@Override @Override
...@@ -80,7 +82,8 @@ public class SuggestionsSection extends InnerNode { ...@@ -80,7 +82,8 @@ public class SuggestionsSection extends InnerNode {
@Override @Override
public void onBindViewHolder(NewTabPageViewHolder holder, int position) { public void onBindViewHolder(NewTabPageViewHolder holder, int position) {
assert holder instanceof SnippetArticleViewHolder; assert holder instanceof SnippetArticleViewHolder;
((SnippetArticleViewHolder) holder).onBindViewHolder(getSuggestionAt(position)); ((SnippetArticleViewHolder) holder)
.onBindViewHolder(getSuggestionAt(position), mCategoryInfo);
} }
@Override @Override
......
...@@ -66,6 +66,7 @@ public class SnippetArticleViewHolder ...@@ -66,6 +66,7 @@ public class SnippetArticleViewHolder
private FetchImageCallback mImageCallback; private FetchImageCallback mImageCallback;
private SnippetArticle mArticle; private SnippetArticle mArticle;
private SuggestionsCategoryInfo mCategoryInfo;
private int mPublisherFaviconSizePx; private int mPublisherFaviconSizePx;
private final boolean mUseFaviconService; private final boolean mUseFaviconService;
...@@ -149,10 +150,9 @@ public class SnippetArticleViewHolder ...@@ -149,10 +150,9 @@ public class SnippetArticleViewHolder
* Updates the layout taking into account screen dimensions and the type of snippet displayed. * Updates the layout taking into account screen dimensions and the type of snippet displayed.
*/ */
private void updateLayout() { private void updateLayout() {
SuggestionsCategoryInfo info =
mRecyclerView.getNewTabPageAdapter().getCategoryInfo(mArticle.mCategory);
boolean narrow = mUiConfig.getCurrentDisplayStyle() == UiConfig.DISPLAY_STYLE_NARROW; boolean narrow = mUiConfig.getCurrentDisplayStyle() == UiConfig.DISPLAY_STYLE_NARROW;
boolean minimal = info.getCardLayout() == ContentSuggestionsCardLayout.MINIMAL_CARD; boolean minimal =
mCategoryInfo.getCardLayout() == ContentSuggestionsCardLayout.MINIMAL_CARD;
// If the screen is narrow or we are using the minimal layout, hide the article snippet. // If the screen is narrow or we are using the minimal layout, hide the article snippet.
boolean hideSnippet = narrow || minimal; boolean hideSnippet = narrow || minimal;
...@@ -185,13 +185,14 @@ public class SnippetArticleViewHolder ...@@ -185,13 +185,14 @@ public class SnippetArticleViewHolder
mPublisherBar.setLayoutParams(params); mPublisherBar.setLayoutParams(params);
} }
public void onBindViewHolder(SnippetArticle article) { public void onBindViewHolder(SnippetArticle article, SuggestionsCategoryInfo categoryInfo) {
super.onBindViewHolder(); super.onBindViewHolder();
// No longer listen for offline status changes to the old article. // No longer listen for offline status changes to the old article.
if (mArticle != null) mArticle.setOfflineStatusChangeRunnable(null); if (mArticle != null) mArticle.setOfflineStatusChangeRunnable(null);
mArticle = article; mArticle = article;
mCategoryInfo = categoryInfo;
updateLayout(); updateLayout();
mHeadlineTextView.setText(mArticle.mTitle); mHeadlineTextView.setText(mArticle.mTitle);
......
...@@ -117,7 +117,7 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase { ...@@ -117,7 +117,7 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase {
// Scroll the last suggestion into view and click it. // Scroll the last suggestion into view and click it.
SnippetArticle suggestion = suggestions.get(suggestions.size() - 1); SnippetArticle suggestion = suggestions.get(suggestions.size() - 1);
int suggestionPosition = getAdapter().getSuggestionPosition(suggestion); int suggestionPosition = getSuggestionPosition(suggestion);
scrollToPosition(suggestionPosition); scrollToPosition(suggestionPosition);
final View suggestionView = waitForView(suggestionPosition); final View suggestionView = waitForView(suggestionPosition);
ChromeTabUtils.waitForTabPageLoaded(mTab, new Runnable() { ChromeTabUtils.waitForTabPageLoaded(mTab, new Runnable() {
...@@ -135,12 +135,13 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase { ...@@ -135,12 +135,13 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase {
public void testAllDismissed() throws InterruptedException, TimeoutException { public void testAllDismissed() throws InterruptedException, TimeoutException {
setSuggestionsAndWaitForUpdate(3); setSuggestionsAndWaitForUpdate(3);
assertEquals(3, mSource.getSuggestionsForCategory(KnownCategories.ARTICLES).size()); assertEquals(3, mSource.getSuggestionsForCategory(KnownCategories.ARTICLES).size());
assertFalse(getAdapter().hasAllBeenDismissed()); assertEquals(RecyclerView.NO_POSITION,
getAdapter().getFirstPositionForType(ItemViewType.ALL_DISMISSED));
assertEquals(1, mSource.getCategories().length); assertEquals(1, mSource.getCategories().length);
assertEquals(KnownCategories.ARTICLES, mSource.getCategories()[0]); assertEquals(KnownCategories.ARTICLES, mSource.getCategories()[0]);
// Dismiss the sign in promo. // Dismiss the sign in promo.
int signinPromoPosition = getAdapter().getSignInPromoPosition(); int signinPromoPosition = getAdapter().getFirstPositionForType(ItemViewType.PROMO);
scrollToPosition(signinPromoPosition); scrollToPosition(signinPromoPosition);
View signinPromoView = waitForView(signinPromoPosition); View signinPromoView = waitForView(signinPromoPosition);
getAdapter().dismissItem(signinPromoPosition); getAdapter().dismissItem(signinPromoPosition);
...@@ -155,11 +156,11 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase { ...@@ -155,11 +156,11 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase {
waitForViewToDetach(cardView); waitForViewToDetach(cardView);
cardPosition = getAdapter().getFirstCardPosition(); cardPosition = getAdapter().getFirstCardPosition();
} }
assertTrue(getAdapter().hasAllBeenDismissed());
assertEquals(0, mSource.getCategories().length); assertEquals(0, mSource.getCategories().length);
// Click the refresh button on the all dismissed item. // Click the refresh button on the all dismissed item.
int allDismissedPosition = getAdapter().getLastContentItemPosition(); int allDismissedPosition = getAdapter().getFirstPositionForType(ItemViewType.ALL_DISMISSED);
assertTrue(allDismissedPosition != RecyclerView.NO_POSITION);
scrollToPosition(allDismissedPosition); scrollToPosition(allDismissedPosition);
View allDismissedView = waitForView(allDismissedPosition); View allDismissedView = waitForView(allDismissedPosition);
singleClickView(allDismissedView.findViewById(R.id.action_button)); singleClickView(allDismissedView.findViewById(R.id.action_button));
...@@ -178,8 +179,7 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase { ...@@ -178,8 +179,7 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase {
assertEquals(10, suggestions.size()); assertEquals(10, suggestions.size());
// Scroll a suggestion into view. // Scroll a suggestion into view.
int suggestionPosition = int suggestionPosition = getSuggestionPosition(suggestions.get(suggestions.size() - 1));
getAdapter().getSuggestionPosition(suggestions.get(suggestions.size() - 1));
scrollToPosition(suggestionPosition); scrollToPosition(suggestionPosition);
View suggestionView = waitForView(suggestionPosition); View suggestionView = waitForView(suggestionPosition);
...@@ -246,6 +246,15 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase { ...@@ -246,6 +246,15 @@ public class NewTabPageRecyclerViewTest extends ChromeTabbedActivityTestBase {
return getRecyclerView().getNewTabPageAdapter(); return getRecyclerView().getNewTabPageAdapter();
} }
private int getSuggestionPosition(SnippetArticle article) {
NewTabPageAdapter adapter = getAdapter();
for (int i = 0; i < adapter.getItemCount(); i++) {
SnippetArticle articleToCheck = adapter.getSuggestionAt(i);
if (articleToCheck != null && articleToCheck.equals(article)) return i;
}
return RecyclerView.NO_POSITION;
}
private void scrollToPosition(final int position) { private void scrollToPosition(final int position) {
final NewTabPageRecyclerView recyclerView = getRecyclerView(); final NewTabPageRecyclerView recyclerView = getRecyclerView();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment