Bug 1040806 - Default bookmark favicons are not displayed after browser restart. r=margaret

This commit is contained in:
Richard Newman 2014-07-21 12:30:45 -07:00
parent 9a71300c19
commit 7213c2f407
2 changed files with 80 additions and 10 deletions

View File

@ -682,6 +682,11 @@ public final class GeckoProfile {
final ContentResolver cr = context.getContentResolver();
// We pass the number of added bookmarks to ensure that the
// indices of the distribution and default bookmarks are
// contiguous. Because there are always at least as many
// bookmarks as there are favicons, we can also guarantee that
// the favicon IDs won't overlap.
final int offset = BrowserDB.addDistributionBookmarks(cr, distribution, 0);
BrowserDB.addDefaultBookmarks(context, cr, offset);
}

View File

@ -10,8 +10,8 @@ import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
@ -113,14 +113,43 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
}
/**
* Not thread safe. A helper to allocate new IDs for arbitrary strings.
*/
private static class NameCounter {
private final HashMap<String, Integer> names = new HashMap<String, Integer>();
private int counter = 0;
private final int increment;
public NameCounter(int start, int increment) {
this.counter = start;
this.increment = increment;
}
public int get(final String name) {
Integer mapping = names.get(name);
if (mapping == null) {
int ours = counter;
counter += increment;
names.put(name, ours);
return ours;
}
return mapping.intValue();
}
public boolean has(final String name) {
return names.containsKey(name);
}
}
/**
* Add default bookmarks to the database.
* Takes an offset; returns a new offset.
*/
@Override
public int addDefaultBookmarks(Context context, ContentResolver cr, final int offset) {
long folderId = getFolderIdFromGuid(cr, Bookmarks.MOBILE_FOLDER_GUID);
if (folderId == -1L) {
long folderID = getFolderIdFromGuid(cr, Bookmarks.MOBILE_FOLDER_GUID);
if (folderID == -1L) {
Log.e(LOGTAG, "No mobile folder: cannot add default bookmarks.");
return offset;
}
@ -136,6 +165,10 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
final ArrayList<ContentValues> bookmarkValues = new ArrayList<ContentValues>();
final ArrayList<ContentValues> faviconValues = new ArrayList<ContentValues>();
// Count down from -offset into negative values to get new favicon IDs.
final NameCounter faviconIDs = new NameCounter((-1 - offset), -1);
for (int i = 0; i < fields.length; i++) {
final String name = fields[i].getName();
final Matcher m = p.matcher(name);
@ -144,14 +177,15 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
}
try {
final int titleid = fields[i].getInt(null);
final String title = context.getString(titleid);
final int titleID = fields[i].getInt(null);
final String title = context.getString(titleID);
final Field urlField = stringsClass.getField(name.replace("_title_", "_url_"));
final int urlId = urlField.getInt(null);
final String url = context.getString(urlId);
final int urlID = urlField.getInt(null);
final String url = context.getString(urlID);
bookmarkValues.add(createBookmark(now, title, url, pos++, folderId));
final ContentValues bookmarkValue = createBookmark(now, title, url, pos++, folderID);
bookmarkValues.add(bookmarkValue);
Bitmap icon = getDefaultFaviconFromPath(context, name);
if (icon == null) {
@ -162,7 +196,14 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
}
final ContentValues iconValue = createFavicon(url, icon);
// Assign a reserved negative _id to each new favicon.
// For now, each name is expected to be unique, and duplicate
// icons will be duplicated in the DB. See Bug 1040806 Comment 8.
if (iconValue != null) {
final int faviconID = faviconIDs.get(name);
iconValue.put("_id", faviconID);
bookmarkValue.put(Bookmarks.FAVICON_ID, faviconID);
faviconValues.add(iconValue);
}
} catch (IllegalAccessException e) {
@ -224,6 +265,10 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
final ArrayList<ContentValues> bookmarkValues = new ArrayList<ContentValues>();
final ArrayList<ContentValues> faviconValues = new ArrayList<ContentValues>();
// Count down from -offset into negative values to get new favicon IDs.
final NameCounter faviconIDs = new NameCounter((-1 - offset), -1);
for (int i = 0; i < bookmarks.length(); i++) {
try {
final JSONObject bookmark = bookmarks.getJSONObject(i);
@ -240,7 +285,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
pos = mobilePos++;
}
bookmarkValues.add(createBookmark(now, title, url, pos, parent));
final ContentValues bookmarkValue = createBookmark(now, title, url, pos, parent);
bookmarkValues.add(bookmarkValue);
// Return early if there is no icon for this bookmark.
if (!bookmark.has("icon")) {
@ -253,8 +299,27 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
if (icon == null) {
continue;
}
final ContentValues iconValue = createFavicon(url, icon);
if (iconValue != null) {
if (iconValue == null) {
continue;
}
/*
* Find out if this icon is a duplicate. If it is, don't try
* to insert it again, but reuse the shared ID.
* Otherwise, assign a new reserved negative _id.
* Duplicates won't be detected in default bookmarks, or
* those already in the database.
*/
final boolean seen = faviconIDs.has(iconData);
final int faviconID = faviconIDs.get(iconData);
iconValue.put("_id", faviconID);
bookmarkValue.put(Bookmarks.FAVICON_ID, faviconID);
if (!seen) {
faviconValues.add(iconValue);
}
} catch (JSONException e) {