Bug 1257345 - Implement reading list smartfolder r?mcomella
MozReview-Commit-ID: 7AuWRAZ7Sq5
--- a/mobile/android/base/java/org/mozilla/gecko/db/BrowserContract.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/BrowserContract.java
@@ -45,16 +45,17 @@ public class BrowserContract {
public static final String PARAM_SUGGESTEDSITES_LIMIT = "suggestedsites_limit";
public static final String PARAM_IS_SYNC = "sync";
public static final String PARAM_SHOW_DELETED = "show_deleted";
public static final String PARAM_IS_TEST = "test";
public static final String PARAM_INSERT_IF_NEEDED = "insert_if_needed";
public static final String PARAM_INCREMENT_VISITS = "increment_visits";
public static final String PARAM_EXPIRE_PRIORITY = "priority";
public static final String PARAM_DATASET_ID = "dataset_id";
+ public static final String PARAM_GROUP_BY = "group_by";
static public enum ExpirePriority {
NORMAL,
AGGRESSIVE
}
static public String getFrecencySortOrder(boolean includesBookmarks, boolean asc) {
final String age = "(" + Combined.DATE_LAST_VISITED + " - " + System.currentTimeMillis() + ") / 86400000";
@@ -152,26 +153,28 @@ public class BrowserContract {
public static final String VIEW_WITH_ANNOTATIONS = "bookmarks_with_annotations";
public static final int FIXED_ROOT_ID = 0;
public static final int FAKE_DESKTOP_FOLDER_ID = -1;
public static final int FIXED_READING_LIST_ID = -2;
public static final int FIXED_PINNED_LIST_ID = -3;
public static final int FIXED_SCREENSHOT_FOLDER_ID = -4;
+ public static final int FAKE_READINGLIST_SMARTFOLDER_ID = -5;
public static final String MOBILE_FOLDER_GUID = "mobile";
public static final String PLACES_FOLDER_GUID = "places";
public static final String MENU_FOLDER_GUID = "menu";
public static final String TAGS_FOLDER_GUID = "tags";
public static final String TOOLBAR_FOLDER_GUID = "toolbar";
public static final String UNFILED_FOLDER_GUID = "unfiled";
public static final String FAKE_DESKTOP_FOLDER_GUID = "desktop";
public static final String PINNED_FOLDER_GUID = "pinned";
public static final String SCREENSHOT_FOLDER_GUID = "screenshots";
+ public static final String FAKE_READINGLIST_SMARTFOLDER_GUID = "readinglist";
public static final int TYPE_FOLDER = 0;
public static final int TYPE_BOOKMARK = 1;
public static final int TYPE_SEPARATOR = 2;
public static final int TYPE_LIVEMARK = 3;
public static final int TYPE_QUERY = 4;
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "bookmarks");
--- a/mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
@@ -65,16 +65,17 @@ public class BrowserProvider extends Sha
static final String TABLE_HISTORY = History.TABLE_NAME;
static final String TABLE_FAVICONS = Favicons.TABLE_NAME;
static final String TABLE_THUMBNAILS = Thumbnails.TABLE_NAME;
static final String TABLE_TABS = Tabs.TABLE_NAME;
static final String TABLE_URL_ANNOTATIONS = UrlAnnotations.TABLE_NAME;
static final String VIEW_COMBINED = Combined.VIEW_NAME;
static final String VIEW_BOOKMARKS_WITH_FAVICONS = Bookmarks.VIEW_WITH_FAVICONS;
+ static final String VIEW_BOOKMARKS_WITH_ANNOTATIONS = Bookmarks.VIEW_WITH_ANNOTATIONS;
static final String VIEW_HISTORY_WITH_FAVICONS = History.VIEW_WITH_FAVICONS;
static final String VIEW_COMBINED_WITH_FAVICONS = Combined.VIEW_WITH_FAVICONS;
// Bookmark matches
static final int BOOKMARKS = 100;
static final int BOOKMARKS_ID = 101;
static final int BOOKMARKS_FOLDER_ID = 102;
static final int BOOKMARKS_PARENT = 103;
@@ -996,20 +997,25 @@ public class BrowserProvider extends Sha
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER;
} else {
debug("Using sort order " + sortOrder + ".");
}
qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
- if (hasFaviconsInProjection(projection))
+ if (hasFaviconsInProjection(projection)) {
qb.setTables(VIEW_BOOKMARKS_WITH_FAVICONS);
- else
+ } else if (selection.contains(Bookmarks.ANNOTATION_KEY)) {
+ qb.setTables(VIEW_BOOKMARKS_WITH_ANNOTATIONS);
+
+ groupBy = uri.getQueryParameter(BrowserContract.PARAM_GROUP_BY);
+ } else {
qb.setTables(TABLE_BOOKMARKS);
+ }
break;
}
case HISTORY_ID:
selection = DBUtils.concatenateWhere(selection, History._ID + " = ?");
selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
@@ -778,86 +778,115 @@ public class LocalBrowserDB implements B
}
}
@Override
@RobocopTarget
public Cursor getBookmarksInFolder(ContentResolver cr, long folderId) {
final boolean addDesktopFolder;
final boolean addScreenshotsFolder;
+ final boolean addReadingListFolder;
// We always want to show mobile bookmarks in the root view.
if (folderId == Bookmarks.FIXED_ROOT_ID) {
folderId = getFolderIdFromGuid(cr, Bookmarks.MOBILE_FOLDER_GUID);
// We'll add a fake "Desktop Bookmarks" folder to the root view if desktop
// bookmarks exist, so that the user can still access non-mobile bookmarks.
addDesktopFolder = desktopBookmarksExist(cr);
addScreenshotsFolder = AppConstants.SCREENSHOTS_IN_BOOKMARKS_ENABLED;
+ addReadingListFolder = true;
} else {
addDesktopFolder = false;
addScreenshotsFolder = false;
+ addReadingListFolder = false;
}
final Cursor c;
+
+ // (You can't switch on a long in Java, hence the if statements)
if (folderId == Bookmarks.FAKE_DESKTOP_FOLDER_ID) {
// Since the "Desktop Bookmarks" folder doesn't actually exist, we
// just fake it by querying specifically certain known desktop folders.
c = cr.query(mBookmarksUriWithProfile,
DEFAULT_BOOKMARK_COLUMNS,
Bookmarks.GUID + " = ? OR " +
Bookmarks.GUID + " = ? OR " +
Bookmarks.GUID + " = ?",
new String[] { Bookmarks.TOOLBAR_FOLDER_GUID,
Bookmarks.MENU_FOLDER_GUID,
Bookmarks.UNFILED_FOLDER_GUID },
null);
} else if (folderId == Bookmarks.FIXED_SCREENSHOT_FOLDER_ID) {
c = getUrlAnnotations().getScreenshots(cr);
+ } else if (folderId == Bookmarks.FAKE_READINGLIST_SMARTFOLDER_ID) {
+ // group by URL to avoid having duplicate bookmarks listed. It's possible to have multiple
+ // bookmarks pointing to the same URL (this would most commonly happen by manually
+ // copying bookmarks on desktop, followed by syncing with mobile), and we don't want
+ // to show the same URL multiple times in the reading list folder.
+ final Uri bookmarksGroupedByUri = mBookmarksUriWithProfile.buildUpon()
+ .appendQueryParameter(BrowserContract.PARAM_GROUP_BY, Bookmarks.URL)
+ .build();
+
+ c = cr.query(bookmarksGroupedByUri,
+ DEFAULT_BOOKMARK_COLUMNS,
+ Bookmarks.ANNOTATION_KEY + " == ? AND " +
+ Bookmarks.ANNOTATION_VALUE + " == ? AND " +
+ "(" + Bookmarks.TYPE + " = ? AND " + Bookmarks.URL + " IS NOT NULL)",
+ new String[] {
+ BrowserContract.UrlAnnotations.Key.READER_VIEW.getDbValue(),
+ Boolean.toString(true),
+ String.valueOf(Bookmarks.TYPE_BOOKMARK) },
+ null);
} else {
// Right now, we only support showing folder and bookmark type of
// entries. We should add support for other types though (bug 737024)
c = cr.query(mBookmarksUriWithProfile,
DEFAULT_BOOKMARK_COLUMNS,
Bookmarks.PARENT + " = ? AND " +
"(" + Bookmarks.TYPE + " = ? OR " +
"(" + Bookmarks.TYPE + " = ? AND " + Bookmarks.URL + " IS NOT NULL))",
new String[] { String.valueOf(folderId),
String.valueOf(Bookmarks.TYPE_FOLDER),
String.valueOf(Bookmarks.TYPE_BOOKMARK) },
null);
}
- final List<Cursor> cursorsToMerge = getSpecialFoldersCursorList(addDesktopFolder, addScreenshotsFolder);
+ final List<Cursor> cursorsToMerge = getSpecialFoldersCursorList(addDesktopFolder, addScreenshotsFolder, addReadingListFolder);
if (cursorsToMerge.size() >= 1) {
cursorsToMerge.add(c);
final Cursor[] arr = (Cursor[]) Array.newInstance(Cursor.class, cursorsToMerge.size());
return new MergeCursor(cursorsToMerge.toArray(arr));
} else {
return c;
}
}
@CheckResult
- private ArrayList<Cursor> getSpecialFoldersCursorList(final boolean addDesktopFolder, final boolean addScreenshotsFolder) {
+ private ArrayList<Cursor> getSpecialFoldersCursorList(final boolean addDesktopFolder,
+ final boolean addScreenshotsFolder, final boolean addReadermodeFolder) {
if (addDesktopFolder || addScreenshotsFolder) {
// Avoid calling this twice.
assertDefaultBookmarkColumnOrdering();
}
// Capacity is number of cursors added below plus one for non-special data.
- final ArrayList<Cursor> out = new ArrayList<>(3);
+ final ArrayList<Cursor> out = new ArrayList<>(4);
if (addDesktopFolder) {
out.add(getSpecialFolderCursor(Bookmarks.FAKE_DESKTOP_FOLDER_ID, Bookmarks.FAKE_DESKTOP_FOLDER_GUID));
}
if (addScreenshotsFolder) {
out.add(getSpecialFolderCursor(Bookmarks.FIXED_SCREENSHOT_FOLDER_ID, Bookmarks.SCREENSHOT_FOLDER_GUID));
}
+ if (addReadermodeFolder) {
+ out.add(getSpecialFolderCursor(Bookmarks.FAKE_READINGLIST_SMARTFOLDER_ID, Bookmarks.FAKE_READINGLIST_SMARTFOLDER_GUID));
+ }
+
return out;
}
@CheckResult
private MatrixCursor getSpecialFolderCursor(final int folderId, final String folderGuid) {
final MatrixCursor out = new MatrixCursor(DEFAULT_BOOKMARK_COLUMNS);
out.addRow(new Object[] {
folderId,
--- a/mobile/android/base/java/org/mozilla/gecko/home/BookmarksListAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/BookmarksListAdapter.java
@@ -272,16 +272,18 @@ class BookmarksListAdapter extends Multi
} else if (guid.equals(Bookmarks.MENU_FOLDER_GUID)) {
return res.getString(R.string.bookmarks_folder_menu);
} else if (guid.equals(Bookmarks.TOOLBAR_FOLDER_GUID)) {
return res.getString(R.string.bookmarks_folder_toolbar);
} else if (guid.equals(Bookmarks.UNFILED_FOLDER_GUID)) {
return res.getString(R.string.bookmarks_folder_unfiled);
} else if (guid.equals(Bookmarks.SCREENSHOT_FOLDER_GUID)) {
return res.getString(R.string.screenshot_folder_label_in_bookmarks);
+ } else if (guid.equals(Bookmarks.FAKE_READINGLIST_SMARTFOLDER_GUID)) {
+ return res.getString(R.string.readinglist_smartfolder_label_in_bookmarks);
}
// If for some reason we have a folder with a special GUID, but it's not one of
// the special folders we expect in the UI, just return the title from the DB.
return c.getString(c.getColumnIndexOrThrow(Bookmarks.TITLE));
}
/**
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -62,16 +62,17 @@
<!ENTITY bookmark_removed "Bookmark removed">
<!ENTITY bookmark_updated "Bookmark updated">
<!ENTITY bookmark_options "Options">
<!ENTITY screenshot_added_to_bookmarks "Screenshot added to bookmarks">
<!-- Localization note (screenshot_folder_label_in_bookmarks): We save links to screenshots
the user takes. The folder we store these links in is located in the bookmarks list
and is labeled by this String. -->
<!ENTITY screenshot_folder_label_in_bookmarks "Screenshots">
+<!ENTITY readinglist_smartfolder_label_in_bookmarks "Reading List">
<!ENTITY history_today_section "Today">
<!ENTITY history_yesterday_section "Yesterday">
<!ENTITY history_week_section3 "Last 7 days">
<!ENTITY history_older_section3 "Older than 6 months">
<!ENTITY search "Search">
<!ENTITY reload "Reload">
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -93,16 +93,17 @@
<string name="bookmark_remove">&bookmark_remove;</string>
<string name="bookmark_added">&bookmark_added;</string>
<string name="bookmark_already_added">&bookmark_already_added;</string>
<string name="bookmark_removed">&bookmark_removed;</string>
<string name="bookmark_updated">&bookmark_updated;</string>
<string name="bookmark_options">&bookmark_options;</string>
<string name="screenshot_added_to_bookmarks">&screenshot_added_to_bookmarks;</string>
<string name="screenshot_folder_label_in_bookmarks">&screenshot_folder_label_in_bookmarks;</string>
+ <string name="readinglist_smartfolder_label_in_bookmarks">&readinglist_smartfolder_label_in_bookmarks;</string>
<string name="history_today_section">&history_today_section;</string>
<string name="history_yesterday_section">&history_yesterday_section;</string>
<string name="history_week_section">&history_week_section3;</string>
<string name="history_older_section">&history_older_section3;</string>
<string name="share">&share;</string>
<string name="share_title">&share_title;</string>