Bug 1328937 - Extract TopSite model from stream adapter. r?grisha
MozReview-Commit-ID: IfSgvPooI9F
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
@@ -139,28 +139,29 @@ public class ActivityStreamTelemetry {
this.set(Contract.SOURCE_SUBTYPE, Contract.SUBTYPE_BOOKMARKED);
break;
default:
throw new IllegalStateException("Unknown highlight source: " + source);
}
return this;
}
- public Builder forTopSiteType(int type) {
+ public Builder forTopSiteType(@BrowserContract.TopSites.TopSiteType int type) {
switch (type) {
case BrowserContract.TopSites.TYPE_PINNED:
this.set(Contract.SOURCE_SUBTYPE, Contract.SUBTYPE_PINNED);
break;
case BrowserContract.TopSites.TYPE_SUGGESTED:
this.set(Contract.SOURCE_SUBTYPE, Contract.SUBTYPE_SUGGESTED);
break;
case BrowserContract.TopSites.TYPE_TOP:
this.set(Contract.SOURCE_SUBTYPE, Contract.SUBTYPE_TOP);
break;
// While we also have a "blank" type, it is not used by Activity Stream.
+ case BrowserContract.TopSites.TYPE_BLANK:
default:
throw new IllegalStateException("Unknown top site type: " + type);
}
return this;
}
public String build() {
return data.toString();
--- a/mobile/android/base/java/org/mozilla/gecko/db/BrowserContract.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/BrowserContract.java
@@ -3,16 +3,17 @@
* 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.db;
import org.mozilla.gecko.AppConstants;
import android.net.Uri;
+import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import org.mozilla.gecko.annotation.RobocopTarget;
@RobocopTarget
public class BrowserContract {
public static final String AUTHORITY = AppConstants.ANDROID_PACKAGE_NAME + ".db.browser";
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
@@ -590,16 +591,19 @@ public class BrowserContract {
public static final class TopSites implements CommonColumns, URLColumns {
private TopSites() {}
public static final int TYPE_BLANK = 0;
public static final int TYPE_TOP = 1;
public static final int TYPE_PINNED = 2;
public static final int TYPE_SUGGESTED = 3;
+ @IntDef({TYPE_BLANK, TYPE_TOP, TYPE_PINNED, TYPE_SUGGESTED})
+ public @interface TopSiteType {}
+
public static final String BOOKMARK_ID = "bookmark_id";
public static final String HISTORY_ID = "history_id";
public static final String TYPE = "type";
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "topsites");
}
public static final class Highlights {
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/model/TopSite.java
@@ -0,0 +1,70 @@
+/* -*- 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.home.activitystream.model;
+
+import android.database.Cursor;
+import android.support.annotation.Nullable;
+
+import org.mozilla.gecko.db.BrowserContract;
+
+public class TopSite {
+ private final long id;
+ private final String url;
+ private final String title;
+ private @Nullable final Boolean isBookmarked;
+ private @BrowserContract.TopSites.TopSiteType final int type;
+
+ public static TopSite fromCursor(Cursor cursor) {
+ // The Combined View only contains pages that have been visited at least once, i.e. any
+ // page in the TopSites query will contain a HISTORY_ID. _ID however will be 0 for all rows.
+ final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Combined.HISTORY_ID));
+ final String url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
+ final String title = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.TITLE));
+ final int type = cursor.getInt(cursor.getColumnIndexOrThrow(BrowserContract.TopSites.TYPE));
+
+ // We can't figure out bookmark state of a pin, so we leave it as unknown to be queried later.
+ Boolean isBookmarked = null;
+ if (type != BrowserContract.TopSites.TYPE_PINNED) {
+ isBookmarked = !cursor.isNull(cursor.getColumnIndexOrThrow(BrowserContract.Combined.BOOKMARK_ID));
+ }
+
+ return new TopSite(id, url, title, isBookmarked, type);
+ }
+
+ private TopSite(long id, String url, String title, @Nullable Boolean isBookmarked, int type) {
+ this.id = id;
+ this.url = url;
+ this.title = title;
+ this.isBookmarked = isBookmarked;
+ this.type = type;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ @Nullable
+ public Boolean isBookmarked() {
+ return isBookmarked;
+ }
+
+ @BrowserContract.TopSites.TopSiteType
+ public int getType() {
+ return type;
+ }
+
+ public boolean isPinned() {
+ return type == BrowserContract.TopSites.TYPE_PINNED;
+ }
+}
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesCard.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesCard.java
@@ -16,16 +16,17 @@ import android.widget.TextView;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.activitystream.ActivityStream;
import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.home.HomePager;
import org.mozilla.gecko.home.activitystream.menu.ActivityStreamContextMenu;
+import org.mozilla.gecko.home.activitystream.model.TopSite;
import org.mozilla.gecko.icons.IconCallback;
import org.mozilla.gecko.icons.IconResponse;
import org.mozilla.gecko.icons.Icons;
import org.mozilla.gecko.util.DrawableUtil;
import org.mozilla.gecko.util.ViewUtil;
import org.mozilla.gecko.util.TouchTargetUtil;
import org.mozilla.gecko.widget.FaviconView;
@@ -35,19 +36,17 @@ import java.util.concurrent.Future;
class TopSitesCard extends RecyclerView.ViewHolder
implements IconCallback, View.OnClickListener {
private final FaviconView faviconView;
private final TextView title;
private final ImageView menuButton;
private Future<IconResponse> ongoingIconLoad;
- private String url;
- private int type;
- @Nullable private Boolean isBookmarked;
+ private TopSite topSite;
private final HomePager.OnUrlOpenListener onUrlOpenListener;
private final HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener;
public TopSitesCard(FrameLayout card, final HomePager.OnUrlOpenListener onUrlOpenListener, final HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener) {
super(card);
faviconView = (FaviconView) card.findViewById(R.id.favicon);
@@ -61,39 +60,37 @@ class TopSitesCard extends RecyclerView.
card.setOnClickListener(this);
TouchTargetUtil.ensureTargetHitArea(menuButton, card);
menuButton.setOnClickListener(this);
ViewUtil.enableTouchRipple(menuButton);
}
- void bind(final TopSitesPageAdapter.TopSite topSite) {
- ActivityStream.extractLabel(itemView.getContext(), topSite.url, true, new ActivityStream.LabelCallback() {
+ void bind(final TopSite topSite) {
+ this.topSite = topSite;
+
+ ActivityStream.extractLabel(itemView.getContext(), topSite.getUrl(), true, new ActivityStream.LabelCallback() {
@Override
public void onLabelExtracted(String label) {
title.setText(label);
}
});
- this.url = topSite.url;
- this.type = topSite.type;
- this.isBookmarked = topSite.isBookmarked;
-
if (ongoingIconLoad != null) {
ongoingIconLoad.cancel(true);
}
ongoingIconLoad = Icons.with(itemView.getContext())
- .pageUrl(topSite.url)
+ .pageUrl(topSite.getUrl())
.skipNetwork()
.build()
.execute(this);
- final int pinResourceId = (isPinned(this.type) ? R.drawable.pin : 0);
+ final int pinResourceId = (topSite.isPinned() ? R.drawable.pin : 0);
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(title, pinResourceId, 0, 0, 0);
}
@Override
public void onIconResponse(IconResponse response) {
faviconView.updateImage(response);
final int tintColor = !response.hasColor() || response.getColor() == Color.WHITE ? Color.LTGRAY : Color.WHITE;
@@ -101,42 +98,38 @@ class TopSitesCard extends RecyclerView.
menuButton.setImageDrawable(
DrawableUtil.tintDrawable(menuButton.getContext(), R.drawable.menu, tintColor));
}
@Override
public void onClick(View clickedView) {
ActivityStreamTelemetry.Extras.Builder extras = ActivityStreamTelemetry.Extras.builder()
.set(ActivityStreamTelemetry.Contract.SOURCE_TYPE, ActivityStreamTelemetry.Contract.TYPE_TOPSITES)
- .forTopSiteType(type);
+ .forTopSiteType(topSite.getType());
if (clickedView == itemView) {
- onUrlOpenListener.onUrlOpen(url, EnumSet.noneOf(HomePager.OnUrlOpenListener.Flags.class));
+ onUrlOpenListener.onUrlOpen(topSite.getUrl(), EnumSet.noneOf(HomePager.OnUrlOpenListener.Flags.class));
Telemetry.sendUIEvent(
TelemetryContract.Event.LOAD_URL,
TelemetryContract.Method.LIST_ITEM,
extras.build()
);
} else if (clickedView == menuButton) {
ActivityStreamContextMenu.show(clickedView.getContext(),
menuButton,
extras,
ActivityStreamContextMenu.MenuMode.TOPSITE,
- title.getText().toString(), url,
+ title.getText().toString(), topSite.getUrl(),
- isBookmarked, isPinned(type),
+ topSite.isBookmarked(), topSite.isPinned(),
onUrlOpenListener, onUrlOpenInBackgroundListener,
faviconView.getWidth(), faviconView.getHeight());
Telemetry.sendUIEvent(
TelemetryContract.Event.SHOW,
TelemetryContract.Method.CONTEXT_MENU,
extras.build()
);
}
}
-
- private boolean isPinned(int type) {
- return type == BrowserContract.TopSites.TYPE_PINNED;
- }
}
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesPageAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/topsites/TopSitesPageAdapter.java
@@ -12,37 +12,22 @@ import android.support.v7.widget.Recycle
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import org.mozilla.gecko.R;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.home.HomePager;
+import org.mozilla.gecko.home.activitystream.model.TopSite;
import java.util.ArrayList;
import java.util.List;
public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
- static final class TopSite {
- public final long id;
- public final String url;
- public final String title;
- @Nullable public final Boolean isBookmarked;
- public final int type;
-
- TopSite(long id, String url, String title, @Nullable Boolean isBookmarked, int type) {
- this.id = id;
- this.url = url;
- this.title = title;
- this.isBookmarked = isBookmarked;
- this.type = type;
- }
- }
-
private List<TopSite> topSites;
private int tiles;
private int tilesWidth;
private int tilesHeight;
private int textHeight;
private final HomePager.OnUrlOpenListener onUrlOpenListener;
private final HomePager.OnUrlOpenInBackgroundListener onUrlOpenInBackgroundListener;
@@ -57,44 +42,30 @@ public class TopSitesPageAdapter extends
this.tilesHeight = tilesHeight;
this.textHeight = context.getResources().getDimensionPixelSize(R.dimen.activity_stream_top_sites_text_height);
this.onUrlOpenListener = onUrlOpenListener;
this.onUrlOpenInBackgroundListener = onUrlOpenInBackgroundListener;
}
/**
- *
- * @param cursor
* @param startIndex The first item that this topsites group should show. This item, and the following
* 3 items will be displayed by this adapter.
*/
public void swapCursor(Cursor cursor, int startIndex) {
topSites.clear();
if (cursor == null) {
return;
}
for (int i = 0; i < tiles && startIndex + i < cursor.getCount(); i++) {
cursor.moveToPosition(startIndex + i);
- // The Combined View only contains pages that have been visited at least once, i.e. any
- // page in the TopSites query will contain a HISTORY_ID. _ID however will be 0 for all rows.
- final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Combined.HISTORY_ID));
- final String url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
- final String title = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.TITLE));
- final int type = cursor.getInt(cursor.getColumnIndexOrThrow(BrowserContract.TopSites.TYPE));
-
- // We can't figure out bookmark state of a pin, so we leave it as unknown to be queried later.
- Boolean isBookmarked = null;
- if (type != BrowserContract.TopSites.TYPE_PINNED) {
- isBookmarked = !cursor.isNull(cursor.getColumnIndexOrThrow(BrowserContract.Combined.BOOKMARK_ID));
- }
- topSites.add(new TopSite(id, url, title, isBookmarked, type));
+ topSites.add(TopSite.fromCursor(cursor));
}
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(TopSitesCard holder, int position) {
holder.bind(topSites.get(position));
@@ -118,11 +89,11 @@ public class TopSitesPageAdapter extends
@Override
public int getItemCount() {
return topSites.size();
}
@Override
@UiThread
public long getItemId(int position) {
- return topSites.get(position).id;
+ return topSites.get(position).getId();
}
}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -467,16 +467,17 @@ gbjar.sources += ['java/org/mozilla/geck
'home/activitystream/ActivityStream.java',
'home/activitystream/ActivityStreamHomeFragment.java',
'home/activitystream/ActivityStreamHomeScreen.java',
'home/activitystream/menu/ActivityStreamContextMenu.java',
'home/activitystream/menu/BottomSheetContextMenu.java',
'home/activitystream/menu/PopupContextMenu.java',
'home/activitystream/model/Highlight.java',
'home/activitystream/model/Metadata.java',
+ 'home/activitystream/model/TopSite.java',
'home/activitystream/stream/HighlightItem.java',
'home/activitystream/stream/HighlightsTitle.java',
'home/activitystream/stream/StreamItem.java',
'home/activitystream/stream/TopPanel.java',
'home/activitystream/stream/WelcomePanel.java',
'home/activitystream/StreamRecyclerAdapter.java',
'home/activitystream/topsites/CirclePageIndicator.java',
'home/activitystream/topsites/TopSitesCard.java',