Bug 1380808 - Rename some "Item" classes to be more descriptive. r?mcomella draft
authorChenxia Liu <liuche@mozilla.com>
Wed, 16 Aug 2017 18:38:50 -0700
changeset 652850 b0339dce6f690471a5cacedf4fc8d530f422d159
parent 652849 b25fd9e199b1151bb81c2f9ae8b8680029e7955e
child 652851 335a1f808b239db9c8cabdc8755afb2701a18335
push id76170
push usercliu@mozilla.com
push dateFri, 25 Aug 2017 08:33:06 +0000
reviewersmcomella
bugs1380808
milestone57.0a1
Bug 1380808 - Rename some "Item" classes to be more descriptive. r?mcomella MozReview-Commit-ID: GlPbKuQPr8g
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/ActivityStreamContextMenu.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/BottomSheetContextMenu.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/PopupContextMenu.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/Highlight.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/Item.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/RowModel.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/TopSite.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/WebpageModel.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/HighlightItem.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/HighlightsTitle.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/StreamItem.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/StreamViewHolder.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanel.java
mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/WelcomePanel.java
mobile/android/base/moz.build
mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
@@ -12,56 +12,53 @@ import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
 import org.mozilla.gecko.activitystream.homepanel.menu.ActivityStreamContextMenu;
+import org.mozilla.gecko.activitystream.homepanel.model.RowModel;
 import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.activitystream.homepanel.model.Highlight;
 import org.mozilla.gecko.activitystream.homepanel.stream.HighlightItem;
 import org.mozilla.gecko.activitystream.homepanel.stream.HighlightsTitle;
-import org.mozilla.gecko.activitystream.homepanel.stream.StreamItem;
+import org.mozilla.gecko.activitystream.homepanel.stream.StreamViewHolder;
 import org.mozilla.gecko.activitystream.homepanel.stream.TopPanel;
 import org.mozilla.gecko.activitystream.homepanel.stream.WelcomePanel;
 import org.mozilla.gecko.util.StringUtils;
 import org.mozilla.gecko.widget.RecyclerViewClickSupport;
 
 import java.util.EnumSet;
 import java.util.LinkedList;
 import java.util.List;
 
 /**
  * The adapter for the Activity Stream panel.
  *
  * Every item is in a single adapter: Top Sites, Welcome panel, Highlights.
  */
-public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> implements RecyclerViewClickSupport.OnItemClickListener,
+public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamViewHolder> implements RecyclerViewClickSupport.OnItemClickListener,
         RecyclerViewClickSupport.OnItemLongClickListener, StreamHighlightItemContextMenuListener {
 
     private static final String LOGTAG = StringUtils.safeSubstring("Gecko" + StreamRecyclerAdapter.class.getSimpleName(), 0, 23);
 
     private Cursor topSitesCursor;
-    private List<RowItem> recyclerViewModel; // List of item types backing this RecyclerView.
+    private List<RowModel> recyclerViewModel; // List of item types backing this RecyclerView.
 
     private final RowItemType[] FIXED_ROWS = {RowItemType.TOP_PANEL, RowItemType.WELCOME, RowItemType.HIGHLIGHTS_TITLE};
     private static final int HIGHLIGHTS_OFFSET = 3; // Topsites, Welcome, Highlights Title
 
     private HomePager.OnUrlOpenListener onUrlOpenListener;
     private HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener;
 
     private int tiles;
     private int tilesSize;
 
-    public interface RowItem {
-        RowItemType getRowItemType();
-    }
-
     public enum RowItemType {
         TOP_PANEL (-2), // RecyclerView.NO_ID is -1, so start hard-coded stableIds at -2.
         WELCOME (-3),
         HIGHLIGHTS_TITLE (-4),
         HIGHLIGHT_ITEM (-1); // There can be multiple Highlight Items so caller should handle as a special case.
 
         public final int stableId;
 
@@ -69,30 +66,30 @@ public class StreamRecyclerAdapter exten
             this.stableId = stableId;
         }
 
         int getViewType() {
             return this.ordinal();
         }
     }
 
-    private static RowItem makeRowItemFromType(final RowItemType type) {
-        return new RowItem() {
+    private static RowModel makeRowModelFromType(final RowItemType type) {
+        return new RowModel() {
             @Override
             public RowItemType getRowItemType() {
                 return type;
             }
         };
     }
 
     public StreamRecyclerAdapter() {
         setHasStableIds(true);
         recyclerViewModel = new LinkedList<>();
         for (RowItemType type : FIXED_ROWS) {
-            recyclerViewModel.add(makeRowItemFromType(type));
+            recyclerViewModel.add(makeRowModelFromType(type));
         }
     }
 
     void setOnUrlOpenListeners(HomePager.OnUrlOpenListener onUrlOpenListener, HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener) {
         this.onUrlOpenListener = onUrlOpenListener;
         this.onUrlOpenInBackgroundListener = onUrlOpenInBackgroundListener;
     }
 
@@ -107,17 +104,17 @@ public class StreamRecyclerAdapter exten
     public int getItemViewType(int position) {
         if (position >= recyclerViewModel.size()) {
             throw new IllegalArgumentException("Requested position does not exist");
         }
         return recyclerViewModel.get(position).getRowItemType().getViewType();
     }
 
     @Override
-    public StreamItem onCreateViewHolder(ViewGroup parent, final int type) {
+    public StreamViewHolder onCreateViewHolder(ViewGroup parent, final int type) {
         final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
 
         if (type == RowItemType.TOP_PANEL.getViewType()) {
             return new TopPanel(inflater.inflate(TopPanel.LAYOUT_ID, parent, false), onUrlOpenListener, onUrlOpenInBackgroundListener);
         } else if (type == RowItemType.WELCOME.getViewType()) {
             return new WelcomePanel(inflater.inflate(WelcomePanel.LAYOUT_ID, parent, false), this);
         } else if (type == RowItemType.HIGHLIGHT_ITEM.getViewType()) {
             return new HighlightItem(inflater.inflate(HighlightItem.LAYOUT_ID, parent, false), this);
@@ -128,17 +125,17 @@ public class StreamRecyclerAdapter exten
         }
     }
 
     private int getHighlightsOffsetFromRVPosition(int position) {
         return position - HIGHLIGHTS_OFFSET;
     }
 
     @Override
-    public void onBindViewHolder(StreamItem holder, int position) {
+    public void onBindViewHolder(StreamViewHolder holder, int position) {
         int type = getItemViewType(position);
         if (type == RowItemType.HIGHLIGHT_ITEM.getViewType()) {
             final Highlight highlight = (Highlight) recyclerViewModel.get(position);
             ((HighlightItem) holder).bind(highlight, position, tilesSize);
         } else if (type == RowItemType.TOP_PANEL.getViewType()) {
             ((TopPanel) holder).bind(topSitesCursor, tiles, tilesSize);
         }
     }
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/ActivityStreamContextMenu.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/ActivityStreamContextMenu.java
@@ -12,20 +12,20 @@ import android.view.MenuItem;
 import android.view.View;
 
 import org.mozilla.gecko.GeckoApplication;
 import org.mozilla.gecko.IntentHelper;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
+import org.mozilla.gecko.activitystream.homepanel.model.WebpageModel;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.home.HomePager;
-import org.mozilla.gecko.activitystream.homepanel.model.Item;
 import org.mozilla.gecko.reader.SavedReaderViewHelper;
 import org.mozilla.gecko.util.Clipboard;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.UIAsyncTask;
 
 import java.util.EnumSet;
 
@@ -34,17 +34,17 @@ public abstract class ActivityStreamCont
         implements NavigationView.OnNavigationItemSelectedListener {
 
     public enum MenuMode {
         HIGHLIGHT,
         TOPSITE
     }
 
     private final Context context;
-    private final Item item;
+    private final WebpageModel item;
 
     private final ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder;
 
     private final HomePager.OnUrlOpenListener onUrlOpenListener;
     private final HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener;
 
     public abstract MenuItem getItemByID(int id);
 
@@ -52,17 +52,17 @@ public abstract class ActivityStreamCont
 
     public abstract void dismiss();
 
     private final MenuMode mode;
 
     /* package-private */ ActivityStreamContextMenu(final Context context,
                                                     final ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder,
                                                     final MenuMode mode,
-                                                    final Item item,
+                                                    final WebpageModel item,
                                                     HomePager.OnUrlOpenListener onUrlOpenListener,
                                                     HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener) {
         this.context = context;
         this.item = item;
         this.telemetryExtraBuilder = telemetryExtraBuilder;
 
         this.mode = mode;
 
@@ -143,17 +143,17 @@ public abstract class ActivityStreamCont
 
         // Only show the "remove from history" item if a page actually has history
         final MenuItem deleteHistoryItem = getItemByID(R.id.delete);
         deleteHistoryItem.setVisible(false);
 
         (new UIAsyncTask.WithoutParams<Boolean>(ThreadUtils.getBackgroundHandler()) {
             @Override
             protected Boolean doInBackground() {
-                final Item item = ActivityStreamContextMenu.this.item;
+                final WebpageModel item = ActivityStreamContextMenu.this.item;
 
                 final Cursor cursor = BrowserDB.from(context).getHistoryForURL(context.getContentResolver(), item.getUrl());
                 // It's tempting to throw here, but crashing because of a (hopefully) inconsequential
                 // oddity is somewhat questionable.
                 if (cursor == null) {
                     return false;
                 }
                 try {
@@ -309,17 +309,17 @@ public abstract class ActivityStreamCont
 
     /**
      * @param shouldOverrideIconWithImageProvider true if the favicon should be replaced with an image provider,
      *                                            if applicable, false otherwise.
      */
     @RobocopTarget
     public static ActivityStreamContextMenu show(Context context,
                                                       View anchor, ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder,
-                                                      final MenuMode menuMode, final Item item,
+                                                      final MenuMode menuMode, final WebpageModel item,
                                                       final boolean shouldOverrideIconWithImageProvider,
                                                       HomePager.OnUrlOpenListener onUrlOpenListener,
                                                       HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener,
                                                       final int tilesWidth, final int tilesHeight) {
         final ActivityStreamContextMenu menu;
 
         if (!HardwareUtils.isTablet()) {
             menu = new BottomSheetContextMenu(context,
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/BottomSheetContextMenu.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/BottomSheetContextMenu.java
@@ -16,18 +16,18 @@ import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.TextView;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
-import org.mozilla.gecko.activitystream.homepanel.model.Item;
 import org.mozilla.gecko.activitystream.homepanel.stream.StreamOverridablePageIconLayout;
+import org.mozilla.gecko.activitystream.homepanel.model.WebpageModel;
 import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.util.StringUtils;
 import org.mozilla.gecko.util.URIUtils;
 
 import java.lang.ref.WeakReference;
 import java.net.URI;
 import java.net.URISyntaxException;
 
@@ -44,17 +44,17 @@ import java.net.URISyntaxException;
     private final View activityView;
 
     /** A reference, that represents the page domain, that allows a return value from an async task. */
     private String[] pageDomainTextReference = new String[] { "" };
 
     public BottomSheetContextMenu(final Context context,
                                   final ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder,
                                   final MenuMode mode,
-                                  final Item item,
+                                  final WebpageModel item,
                                   final boolean shouldOverrideIconWithImageProvider,
                                   HomePager.OnUrlOpenListener onUrlOpenListener,
                                   HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener,
                                   final int tilesWidth, final int tilesHeight) {
 
         super(context,
                 telemetryExtraBuilder,
                 mode,
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/PopupContextMenu.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/menu/PopupContextMenu.java
@@ -13,31 +13,31 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.PopupWindow;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
 import org.mozilla.gecko.home.HomePager;
-import org.mozilla.gecko.activitystream.homepanel.model.Item;
+import org.mozilla.gecko.activitystream.homepanel.model.WebpageModel;
 
 /* package-private */ class PopupContextMenu
         extends ActivityStreamContextMenu {
 
     private final PopupWindow popupWindow;
     private final NavigationView navigationView;
 
     private final View anchor;
 
     public PopupContextMenu(final Context context,
                             View anchor,
                             final ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder,
                             final MenuMode mode,
-                            final Item item,
+                            final WebpageModel item,
                             HomePager.OnUrlOpenListener onUrlOpenListener,
                             HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener) {
         super(context,
                 telemetryExtraBuilder,
                 mode,
                 item,
                 onUrlOpenListener,
                 onUrlOpenInBackgroundListener);
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/Highlight.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/Highlight.java
@@ -13,17 +13,17 @@ import android.text.TextUtils;
 import org.mozilla.gecko.activitystream.Utils;
 import org.mozilla.gecko.activitystream.homepanel.StreamRecyclerAdapter;
 import org.mozilla.gecko.activitystream.ranking.HighlightCandidateCursorIndices;
 import org.mozilla.gecko.activitystream.ranking.HighlightsRanking;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class Highlight implements Item, StreamRecyclerAdapter.RowItem {
+public class Highlight implements WebpageModel, RowModel {
 
     /**
      * A pattern matching a json object containing the key "image_url" and extracting the value. afaik, these urls
      * are not encoded so it's entirely possible that the url will contain a quote and we will not extract the whole
      * url. However, given these are coming from websites providing favicon-like images, it's not likely a quote will
      * appear and since these urls are only being used to compare against one another (as imageURLs in Highlight items),
      * a partial URL may actually have the same behavior: good enough for me!
      */
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/RowModel.java
@@ -0,0 +1,11 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.mozilla.gecko.activitystream.homepanel.model;
+
+import org.mozilla.gecko.activitystream.homepanel.StreamRecyclerAdapter;
+
+public interface RowModel {
+    StreamRecyclerAdapter.RowItemType getRowItemType();
+}
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/TopSite.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/TopSite.java
@@ -6,17 +6,17 @@
 package org.mozilla.gecko.activitystream.homepanel.model;
 
 import android.database.Cursor;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 import org.mozilla.gecko.db.BrowserContract;
 
-public class TopSite implements Item {
+public class TopSite implements WebpageModel {
     private final long id;
     private final String url;
     private final String title;
     private @Nullable Boolean isBookmarked;
     private final @Nullable boolean isPinned;
     private @BrowserContract.TopSites.TopSiteType final int type;
     private final Metadata metadata;
 
rename from mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/Item.java
rename to mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/WebpageModel.java
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/Item.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/model/WebpageModel.java
@@ -1,17 +1,22 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 package org.mozilla.gecko.activitystream.homepanel.model;
 
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 /**
- * Shared interface for activity stream item models.
+ * Shared interface for activity stream items that model a url/link item.
  */
-public interface Item {
+public interface WebpageModel {
     String getTitle();
 
     String getUrl();
 
     /**
      * Returns the image URL associated with this stream item.
      *
      * Some implementations may be slow due to lazy loading: see {@link Highlight#getImageUrl()}.
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/HighlightItem.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/HighlightItem.java
@@ -23,17 +23,17 @@ import org.mozilla.gecko.util.TouchTarge
 import org.mozilla.gecko.util.URIUtils;
 import org.mozilla.gecko.util.ViewUtil;
 
 import java.lang.ref.WeakReference;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.UUID;
 
-public class HighlightItem extends StreamItem {
+public class HighlightItem extends StreamViewHolder {
     private static final String LOGTAG = "GeckoHighlightItem";
 
     public static final int LAYOUT_ID = R.layout.activity_stream_card_history_item;
     private static final double SIZE_RATIO = 0.75;
 
     private int position;
 
     private final StreamOverridablePageIconLayout pageIconLayout;
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/HighlightsTitle.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/HighlightsTitle.java
@@ -4,16 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.activitystream.homepanel.stream;
 
 import android.view.View;
 
 import org.mozilla.gecko.R;
 
-public class HighlightsTitle extends StreamItem {
+public class HighlightsTitle extends StreamViewHolder {
     public static final int LAYOUT_ID = R.layout.activity_stream_main_highlightstitle;
 
     public HighlightsTitle(final View itemView) {
         super(itemView);
     }
 }
 
rename from mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/StreamItem.java
rename to mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/StreamViewHolder.java
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/StreamItem.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/StreamViewHolder.java
@@ -3,13 +3,13 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.activitystream.homepanel.stream;
 
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
 
-public abstract class StreamItem extends RecyclerView.ViewHolder {
-    public StreamItem(View itemView) {
+public abstract class StreamViewHolder extends RecyclerView.ViewHolder {
+    public StreamViewHolder(View itemView) {
         super(itemView);
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanel.java
@@ -12,17 +12,17 @@ import android.view.View;
 import android.view.ViewGroup;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.activitystream.homepanel.topsites.TopSitesPagerAdapter;
 import org.mozilla.gecko.home.HomePager;
 
-public class TopPanel extends StreamItem {
+public class TopPanel extends StreamViewHolder {
     public static final int LAYOUT_ID = R.layout.activity_stream_main_toppanel;
 
     private final ViewPager topSitesPager;
 
     private static class SwipeListener extends ViewPager.SimpleOnPageChangeListener {
         int currentPosition = 0;
 
         @Override
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/WelcomePanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/WelcomePanel.java
@@ -10,25 +10,25 @@ import android.content.SharedPreferences
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
 import android.view.ViewStub;
 import android.widget.Button;
 
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.R;
 
-public class WelcomePanel extends StreamItem implements View.OnClickListener {
+public class WelcomePanel extends StreamViewHolder implements View.OnClickListener {
     public static final int LAYOUT_ID = R.layout.activity_stream_main_welcomepanel;
 
     public static final String PREF_WELCOME_DISMISSED = "activitystream.welcome_dismissed";
 
-    private final RecyclerView.Adapter<StreamItem> adapter;
+    private final RecyclerView.Adapter<StreamViewHolder> adapter;
     private final Context context;
 
-    public WelcomePanel(final View itemView, final RecyclerView.Adapter<StreamItem> adapter) {
+    public WelcomePanel(final View itemView, final RecyclerView.Adapter<StreamViewHolder> adapter) {
         super(itemView);
 
         this.adapter = adapter;
         this.context = itemView.getContext();
 
         final SharedPreferences sharedPrefs = GeckoSharedPrefs.forApp(itemView.getContext());
 
         if (!sharedPrefs.getBoolean(PREF_WELCOME_DISMISSED, false)) {
@@ -42,17 +42,17 @@ public class WelcomePanel extends Stream
         }
     }
 
     @Override
     public void onClick(View v) {
         // To animate between item changes, RecyclerView keeps around the old version of the view,
         // and creates a new equivalent item (which is bound using the new data) - followed by
         // animating between those two versions. Hence we just need to make sure that
-        // any future calls to onCreateViewHolder create a version of the Header Item
+        // any future calls to onCreateViewHolder create a version of the Header StreamViewHolder
         // with the welcome panel hidden (i.e. we don't need to care about animations ourselves).
         // We communicate this state change via the pref.
 
         final SharedPreferences sharedPrefs = GeckoSharedPrefs.forApp(context);
 
         sharedPrefs.edit()
                 .putBoolean(WelcomePanel.PREF_WELCOME_DISMISSED, true)
                 .apply();
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -508,23 +508,24 @@ gbjar.sources += ['java/org/mozilla/geck
     'activitystream/homepanel/ActivityStreamHomeScreen.java',
     'activitystream/homepanel/ActivityStreamPanel.java',
     'activitystream/homepanel/HighlightsDividerItemDecoration.java',
     'activitystream/homepanel/HighlightsLoader.java',
     'activitystream/homepanel/menu/ActivityStreamContextMenu.java',
     'activitystream/homepanel/menu/BottomSheetContextMenu.java',
     'activitystream/homepanel/menu/PopupContextMenu.java',
     'activitystream/homepanel/model/Highlight.java',
-    'activitystream/homepanel/model/Item.java',
     'activitystream/homepanel/model/Metadata.java',
+    'activitystream/homepanel/model/RowModel.java',
     'activitystream/homepanel/model/TopSite.java',
+    'activitystream/homepanel/model/WebpageModel.java',
     'activitystream/homepanel/stream/HighlightItem.java',
     'activitystream/homepanel/stream/HighlightsTitle.java',
-    'activitystream/homepanel/stream/StreamItem.java',
     'activitystream/homepanel/stream/StreamOverridablePageIconLayout.java',
+    'activitystream/homepanel/stream/StreamViewHolder.java',
     'activitystream/homepanel/stream/TopPanel.java',
     'activitystream/homepanel/stream/WelcomePanel.java',
     'activitystream/homepanel/StreamHighlightItemContextMenuListener.java',
     'activitystream/homepanel/StreamItemAnimator.java',
     'activitystream/homepanel/StreamRecyclerAdapter.java',
     'activitystream/homepanel/topsites/TopSitesCard.java',
     'activitystream/homepanel/topsites/TopSitesPage.java',
     'activitystream/homepanel/topsites/TopSitesPageAdapter.java',
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testActivityStreamContextMenu.java
@@ -12,23 +12,23 @@ import android.net.Uri;
 import android.view.MenuItem;
 import android.view.View;
 
 import com.robotium.solo.Condition;
 
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
+import org.mozilla.gecko.activitystream.homepanel.model.WebpageModel;
 import org.mozilla.gecko.activitystream.ranking.HighlightCandidateCursorIndices;
 import org.mozilla.gecko.db.BrowserContract;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.db.DBUtils;
 import org.mozilla.gecko.activitystream.homepanel.menu.ActivityStreamContextMenu;
 import org.mozilla.gecko.activitystream.homepanel.model.Highlight;
-import org.mozilla.gecko.activitystream.homepanel.model.Item;
 import org.mozilla.gecko.activitystream.homepanel.model.TopSite;
 
 /**
  * This test is unfortunately closely coupled to the current implementation, however it is still
  * useful in that it tests the bookmark/history/pinned state specific menu items for correctness.
  */
 public class testActivityStreamContextMenu extends BaseTest {
     private static final String TEST_URL = "http://example.com/test/url";
@@ -223,17 +223,17 @@ public class testActivityStreamContextMe
 
         testMenuForItem(topSite, bookmarked, pinned, visited);
     }
 
     /**
      * Test that the menu shows the expected menu items for a given URL, and that these items have
      * the correct state.
      */
-    private void testMenuForItem(Item item, boolean bookmarked, boolean pinned, boolean visited) {
+    private void testMenuForItem(WebpageModel item, boolean bookmarked, boolean pinned, boolean visited) {
         final View anchor = new View(getActivity());
         final ActivityStreamContextMenu menu = ActivityStreamContextMenu.show(
                 getActivity(), anchor, ActivityStreamTelemetry.Extras.builder(),
                 ActivityStreamContextMenu.MenuMode.HIGHLIGHT, item,
                 false, null, null, 100, 100);
 
         final int expectedBookmarkString;
         if (bookmarked) {