mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 697987 - Remove race when downloading favicons [r=sriram]
Multiple DownloadFaviconTasks could get queued and run simultaneously, making the tab's final favicon anybody's guess. Instead, this patch ensures that existing favicon downloaders for a particular tab are cancelled before new ones are queued, eliminating the race condition.
This commit is contained in:
parent
1bdc567283
commit
368bd3af0d
@ -43,7 +43,6 @@ package org.mozilla.gecko;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
@ -905,7 +904,7 @@ abstract public class GeckoApp
|
||||
|
||||
tab.updateTitle(title);
|
||||
if (tab.getFavicon() == null)
|
||||
downloadDefaultFavicon(tabId);
|
||||
tab.downloadFavicon(null);
|
||||
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
@ -934,73 +933,18 @@ abstract public class GeckoApp
|
||||
|
||||
void handleLinkAdded(final int tabId, String rel, final String href) {
|
||||
if (rel.indexOf("icon") != -1) {
|
||||
new DownloadFaviconTask(tabId).execute(href);
|
||||
Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
if (tab != null)
|
||||
tab.downloadFavicon(href);
|
||||
}
|
||||
}
|
||||
|
||||
void downloadDefaultFavicon(final int tabId) {
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
URL url = new URL(tab.getURL());
|
||||
String faviconUrl = url.getProtocol() + "://" + url.getAuthority() + "/favicon.ico";
|
||||
new DownloadFaviconTask(tabId).execute(faviconUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
// Optional so not a real error
|
||||
}
|
||||
void faviconUpdated(Tab tab) {
|
||||
if (Tabs.getInstance().isSelectedTab(tab))
|
||||
mBrowserToolbar.setFavicon(tab.getFavicon());
|
||||
onTabsChanged();
|
||||
}
|
||||
|
||||
private class DownloadFaviconTask extends AsyncTask<String, Void, Drawable> {
|
||||
private final int mTabId;
|
||||
|
||||
public DownloadFaviconTask(int tabId) {
|
||||
mTabId = tabId;
|
||||
}
|
||||
|
||||
protected Drawable doInBackground(String... args) {
|
||||
Drawable image = null;
|
||||
|
||||
try {
|
||||
URL url = new URL(args[0]);
|
||||
|
||||
InputStream is = (InputStream) url.getContent();
|
||||
image = Drawable.createFromStream(is, "src");
|
||||
} catch (IOException e) {
|
||||
Log.d(LOG_NAME, "Error loading favicon: " + e);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Drawable image) {
|
||||
if (image != null) {
|
||||
Tab tab = Tabs.getInstance().getTab(mTabId);
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
tab.updateFavicon(image);
|
||||
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
onTabsChanged();
|
||||
}
|
||||
});
|
||||
|
||||
if (!Tabs.getInstance().isSelectedTab(tab))
|
||||
return;
|
||||
|
||||
final Drawable postImage = image;
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mBrowserToolbar.setFavicon(postImage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addPluginView(final View view,
|
||||
final double x, final double y,
|
||||
final double w, final double h) {
|
||||
|
@ -49,6 +49,10 @@ import android.util.Log;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -64,6 +68,7 @@ public class Tab {
|
||||
private int mHistoryIndex;
|
||||
private boolean mLoading;
|
||||
private boolean mBookmark;
|
||||
private DownloadFaviconTask mFaviconDownloader;
|
||||
|
||||
static class HistoryEntry {
|
||||
public final String mUri;
|
||||
@ -252,6 +257,55 @@ public class Tab {
|
||||
}
|
||||
}
|
||||
|
||||
void downloadFavicon(String url) {
|
||||
if (url == null) {
|
||||
try {
|
||||
URL urlObj = new URL(mUrl);
|
||||
url = urlObj.getProtocol() + "://" + urlObj.getAuthority() + "/favicon.ico";
|
||||
} catch (MalformedURLException e) {
|
||||
// Optional so not a real error
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
URL urlObj = new URL(url);
|
||||
// note that the above line may throw a MalformedURLException,
|
||||
// in which case we abort and don't cancel the old download task.
|
||||
if (mFaviconDownloader != null) {
|
||||
mFaviconDownloader.cancel(false);
|
||||
Log.d(LOG_NAME, "Cancelled old favicon downloader");
|
||||
}
|
||||
|
||||
mFaviconDownloader = new DownloadFaviconTask();
|
||||
mFaviconDownloader.execute(urlObj);
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private class DownloadFaviconTask extends AsyncTask<URL, Void, Drawable> {
|
||||
protected Drawable doInBackground(URL... args) {
|
||||
Drawable image = null;
|
||||
try {
|
||||
URL url = args[0];
|
||||
InputStream is = (InputStream) url.getContent();
|
||||
image = Drawable.createFromStream(is, "src");
|
||||
} catch (IOException e) {
|
||||
Log.d(LOG_NAME, "Error loading favicon: " + e);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Drawable image) {
|
||||
if (image == null)
|
||||
return;
|
||||
|
||||
updateFavicon(image);
|
||||
GeckoApp.mAppContext.faviconUpdated(Tab.this);
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckBookmarkTask extends AsyncTask<Void, Void, Boolean> {
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... unused) {
|
||||
|
Loading…
Reference in New Issue
Block a user