mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 785945 - Load favicon images asynchronously in the All Pages tab (r=mfinkle)
This commit is contained in:
parent
c0b03818fc
commit
0a22ff83f9
@ -7,8 +7,10 @@ package org.mozilla.gecko;
|
|||||||
|
|
||||||
import org.mozilla.gecko.AwesomeBar.ContextMenuSubject;
|
import org.mozilla.gecko.AwesomeBar.ContextMenuSubject;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||||
|
import org.mozilla.gecko.db.BrowserContract.Images;
|
||||||
import org.mozilla.gecko.db.BrowserDB;
|
import org.mozilla.gecko.db.BrowserDB;
|
||||||
import org.mozilla.gecko.db.BrowserDB.URLColumns;
|
import org.mozilla.gecko.db.BrowserDB.URLColumns;
|
||||||
|
import org.mozilla.gecko.util.GeckoAsyncTask;
|
||||||
import org.mozilla.gecko.util.GeckoEventListener;
|
import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
@ -18,8 +20,13 @@ import org.json.JSONObject;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -49,6 +56,7 @@ import android.widget.TextView;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
||||||
public static final String LOGTAG = "ALL_PAGES";
|
public static final String LOGTAG = "ALL_PAGES";
|
||||||
@ -68,6 +76,11 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
|||||||
private LinearLayout mAllPagesView;
|
private LinearLayout mAllPagesView;
|
||||||
private boolean mAnimateSuggestions;
|
private boolean mAnimateSuggestions;
|
||||||
private View mSuggestionsOptInPrompt;
|
private View mSuggestionsOptInPrompt;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
|
private static final int MESSAGE_LOAD_FAVICONS = 1;
|
||||||
|
private static final int MESSAGE_UPDATE_FAVICONS = 2;
|
||||||
|
private static final int DELAY_SHOW_THUMBNAILS = 550;
|
||||||
|
|
||||||
private class SearchEntryViewHolder {
|
private class SearchEntryViewHolder {
|
||||||
public FlowLayout suggestionView;
|
public FlowLayout suggestionView;
|
||||||
@ -122,9 +135,14 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
|||||||
((Activity)mContext).registerForContextMenu(mView);
|
((Activity)mContext).registerForContextMenu(mView);
|
||||||
mView.setTag(TAG);
|
mView.setTag(TAG);
|
||||||
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
||||||
((ListView)mView).setAdapter(adapter);
|
|
||||||
mView.setOnTouchListener(mListListener);
|
ListView listView = (ListView) mView;
|
||||||
|
listView.setAdapter(adapter);
|
||||||
|
listView.setOnTouchListener(mListListener);
|
||||||
|
|
||||||
|
mHandler = new AllPagesHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ListView)mView;
|
return (ListView)mView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +156,10 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
|||||||
Cursor cursor = adapter.getCursor();
|
Cursor cursor = adapter.getCursor();
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
|
||||||
|
mHandler.removeMessages(MESSAGE_UPDATE_FAVICONS);
|
||||||
|
mHandler.removeMessages(MESSAGE_LOAD_FAVICONS);
|
||||||
|
mHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void filter(String searchTerm) {
|
public void filter(String searchTerm) {
|
||||||
@ -196,6 +218,8 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
|||||||
Cursor c = BrowserDB.filter(getContentResolver(), constraint, MAX_RESULTS);
|
Cursor c = BrowserDB.filter(getContentResolver(), constraint, MAX_RESULTS);
|
||||||
c.getCount();
|
c.getCount();
|
||||||
|
|
||||||
|
postLoadFavicons();
|
||||||
|
|
||||||
long end = SystemClock.uptimeMillis();
|
long end = SystemClock.uptimeMillis();
|
||||||
int time = (int)(end - start);
|
int time = (int)(end - start);
|
||||||
Log.i(LOGTAG, "Got cursor in " + time + "ms");
|
Log.i(LOGTAG, "Got cursor in " + time + "ms");
|
||||||
@ -398,8 +422,8 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
|||||||
|
|
||||||
updateTitle(viewHolder.titleView, cursor);
|
updateTitle(viewHolder.titleView, cursor);
|
||||||
updateUrl(viewHolder.urlView, cursor);
|
updateUrl(viewHolder.urlView, cursor);
|
||||||
updateFavicon(viewHolder.faviconView, cursor);
|
|
||||||
updateBookmarkIcon(viewHolder.bookmarkIconView, cursor);
|
updateBookmarkIcon(viewHolder.bookmarkIconView, cursor);
|
||||||
|
displayFavicon(viewHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
@ -706,4 +730,129 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
|||||||
private void unregisterEventListener(String event) {
|
private void unregisterEventListener(String event) {
|
||||||
GeckoAppShell.getEventDispatcher().unregisterEventListener(event, this);
|
GeckoAppShell.getEventDispatcher().unregisterEventListener(event, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> getUrlsWithoutFavicon() {
|
||||||
|
List<String> urls = new ArrayList<String>();
|
||||||
|
|
||||||
|
Cursor c = mCursorAdapter.getCursor();
|
||||||
|
if (c == null || !c.moveToFirst())
|
||||||
|
return urls;
|
||||||
|
|
||||||
|
do {
|
||||||
|
final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL));
|
||||||
|
|
||||||
|
// We only want to load favicons from DB if they are not in the
|
||||||
|
// memory cache yet.
|
||||||
|
Favicons favicons = GeckoApp.mAppContext.getFavicons();
|
||||||
|
if (favicons.getFaviconFromMemCache(url) != null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
urls.add(url);
|
||||||
|
} while (c.moveToNext());
|
||||||
|
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeFaviconsInMemCache(Cursor c) {
|
||||||
|
try {
|
||||||
|
if (c == null || !c.moveToFirst())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Favicons favicons = GeckoApp.mAppContext.getFavicons();
|
||||||
|
|
||||||
|
do {
|
||||||
|
final String url = c.getString(c.getColumnIndexOrThrow(Images.URL));
|
||||||
|
final byte[] b = c.getBlob(c.getColumnIndexOrThrow(Images.FAVICON));
|
||||||
|
if (b == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Bitmap favicon = BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||||
|
if (favicon == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Drawable faviconDrawable = new BitmapDrawable(getResources(), favicon);
|
||||||
|
favicons.putFaviconInMemCache(url, faviconDrawable);
|
||||||
|
} while (c.moveToNext());
|
||||||
|
} finally {
|
||||||
|
if (c != null)
|
||||||
|
c.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadFaviconsForCurrentResults() {
|
||||||
|
final List<String> urls = getUrlsWithoutFavicon();
|
||||||
|
if (urls.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(new GeckoAsyncTask<Void, Void, Cursor>(GeckoApp.mAppContext, GeckoAppShell.getHandler()) {
|
||||||
|
@Override
|
||||||
|
public Cursor doInBackground(Void... params) {
|
||||||
|
return BrowserDB.getFaviconsForUrls(getContentResolver(), urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostExecute(Cursor c) {
|
||||||
|
storeFaviconsInMemCache(c);
|
||||||
|
postUpdateFavicons();
|
||||||
|
}
|
||||||
|
}).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayFavicon(AwesomeEntryViewHolder viewHolder) {
|
||||||
|
final String url = viewHolder.urlView.getText().toString();
|
||||||
|
Favicons favicons = GeckoApp.mAppContext.getFavicons();
|
||||||
|
viewHolder.faviconView.setImageDrawable(favicons.getFaviconFromMemCache(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFavicons() {
|
||||||
|
ListView listView = (ListView) mView;
|
||||||
|
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||||
|
final View view = listView.getChildAt(i);
|
||||||
|
final Object tag = view.getTag();
|
||||||
|
|
||||||
|
if (tag == null || !(tag instanceof AwesomeEntryViewHolder))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
final AwesomeEntryViewHolder viewHolder = (AwesomeEntryViewHolder) tag;
|
||||||
|
displayFavicon(viewHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
mView.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postUpdateFavicons() {
|
||||||
|
if (mHandler == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Message msg = mHandler.obtainMessage(MESSAGE_UPDATE_FAVICONS,
|
||||||
|
AllPagesTab.this);
|
||||||
|
|
||||||
|
mHandler.removeMessages(MESSAGE_UPDATE_FAVICONS);
|
||||||
|
mHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postLoadFavicons() {
|
||||||
|
if (mHandler == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Message msg = mHandler.obtainMessage(MESSAGE_LOAD_FAVICONS,
|
||||||
|
AllPagesTab.this);
|
||||||
|
|
||||||
|
mHandler.removeMessages(MESSAGE_LOAD_FAVICONS);
|
||||||
|
mHandler.sendMessageDelayed(msg, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AllPagesHandler extends Handler {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MESSAGE_LOAD_FAVICONS:
|
||||||
|
loadFaviconsForCurrentResults();
|
||||||
|
break;
|
||||||
|
case MESSAGE_UPDATE_FAVICONS:
|
||||||
|
updateFavicons();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,6 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||||||
new String[] { Combined._ID,
|
new String[] { Combined._ID,
|
||||||
Combined.URL,
|
Combined.URL,
|
||||||
Combined.TITLE,
|
Combined.TITLE,
|
||||||
Combined.FAVICON,
|
|
||||||
Combined.DISPLAY,
|
Combined.DISPLAY,
|
||||||
Combined.BOOKMARK_ID,
|
Combined.BOOKMARK_ID,
|
||||||
Combined.HISTORY_ID },
|
Combined.HISTORY_ID },
|
||||||
|
Loading…
Reference in New Issue
Block a user