Fix large icons by caching two icon urls per app in the DB

This commit is contained in:
Daniel Martí 2015-06-09 17:44:18 +02:00
parent f0c00c144c
commit 4895e2d790
5 changed files with 89 additions and 55 deletions

View File

@ -363,10 +363,6 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
fdroidApp = ((FDroidApp) getApplication());
fdroidApp.applyTheme(this);
/* TODO:
AppProvider.updateIconUrls(1.5);
*/
super.onCreate(savedInstanceState);
// Must be called *after* super.onCreate(), as that is where the action bar
@ -553,9 +549,6 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
}
inProcessOfChangingConfiguration = false;
/* TODO
AppProvider.updateIconUrls(1.0);
*/
super.onDestroy();
}
@ -1492,7 +1485,8 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
// Set the icon...
ImageView iv = (ImageView) view.findViewById(R.id.icon);
ImageLoader.getInstance().displayImage(getApp().iconUrl, iv, displayImageOptions);
ImageLoader.getInstance().displayImage(getApp().iconUrlLarge, iv,
displayImageOptions);
// Set the title
TextView tv = (TextView) view.findViewById(R.id.title);

View File

@ -79,6 +79,14 @@ public final class Utils {
private static final SimpleDateFormat LOG_DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
public static final String FALLBACK_ICONS_DIR = "/icons/";
/*
* @param dpiMultiplier Lets you grab icons for densities larger or
* smaller than that of your device by some fraction. Useful, for example,
* if you want to display a 48dp image at twice the size, 96dp, in which
* case you'd use a dpiMultiplier of 2.0 to get an image twice as big.
*/
public static String getIconsDir(final Context context, final double dpiMultiplier) {
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
final double dpi = metrics.densityDpi * dpiMultiplier;

View File

@ -91,7 +91,10 @@ public class App extends ValueObject implements Comparable<App> {
// True if the current update for this app is to be ignored
public int ignoreThisUpdate;
// To be displayed at 48dp (x1.0)
public String iconUrl;
// To be displayed at 72dp (x1.5)
public String iconUrlLarge;
public String installedVersionName;
@ -196,6 +199,9 @@ public class App extends ValueObject implements Comparable<App> {
case AppProvider.DataColumns.ICON_URL:
iconUrl = cursor.getString(i);
break;
case AppProvider.DataColumns.ICON_URL_LARGE:
iconUrlLarge = cursor.getString(i);
break;
case AppProvider.DataColumns.InstalledApp.VERSION_CODE:
installedVersionCode = cursor.getInt(i);
break;
@ -355,6 +361,7 @@ public class App extends ValueObject implements Comparable<App> {
values.put(AppProvider.DataColumns.SUMMARY, summary);
values.put(AppProvider.DataColumns.ICON, icon);
values.put(AppProvider.DataColumns.ICON_URL, iconUrl);
values.put(AppProvider.DataColumns.ICON_URL_LARGE, iconUrlLarge);
values.put(AppProvider.DataColumns.DESCRIPTION, description);
values.put(AppProvider.DataColumns.LICENSE, license);
values.put(AppProvider.DataColumns.WEB_URL, webURL);

View File

@ -183,6 +183,7 @@ public class AppProvider extends FDroidProvider {
String IGNORE_ALLUPDATES = "ignoreAllUpdates";
String IGNORE_THISUPDATE = "ignoreThisUpdate";
String ICON_URL = "iconUrl";
String ICON_URL_LARGE = "iconUrlLarge";
interface SuggestedApk {
String VERSION = "suggestedApkVersion";
@ -199,9 +200,9 @@ public class AppProvider extends FDroidProvider {
BITCOIN_ADDR, LITECOIN_ADDR, DOGECOIN_ADDR, FLATTR_ID,
UPSTREAM_VERSION, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
CATEGORIES, ANTI_FEATURES, REQUIREMENTS, IGNORE_ALLUPDATES,
IGNORE_THISUPDATE, ICON_URL, SUGGESTED_VERSION_CODE,
SuggestedApk.VERSION, InstalledApp.VERSION_CODE,
InstalledApp.VERSION_NAME
IGNORE_THISUPDATE, ICON_URL, ICON_URL_LARGE,
SUGGESTED_VERSION_CODE, SuggestedApk.VERSION,
InstalledApp.VERSION_CODE, InstalledApp.VERSION_NAME
};
}
@ -789,7 +790,7 @@ public class AppProvider extends FDroidProvider {
updateCompatibleFlags();
updateSuggestedFromLatest();
updateSuggestedFromUpstream();
updateIconUrls(1.0);
updateIconUrls();
}
/**
@ -923,16 +924,19 @@ public class AppProvider extends FDroidProvider {
/**
* Updates URLs to icons
*
* @param dpiMultiplier Lets you grab icons for densities larger or smaller than that of your device by some fraction. Useful, for example, if you want to display a 48dp image at twice the size, 96dp, in which case you'd use a dpiMultiplier of 2.0 to get an image twice as big.
*/
public void updateIconUrls(final double dpiMultiplier) {
Log.d(TAG, "Updating icon paths for apps belonging to repos with version >= " + Repo.VERSION_DENSITY_SPECIFIC_ICONS);
final String iconsDir = Utils.getIconsDir(getContext(), dpiMultiplier);
Log.d(TAG, "Using icon dir '"+iconsDir+"'");
public void updateIconUrls() {
final String iconsDir = Utils.getIconsDir(getContext(), 1.0);
final String iconsDirLarge = Utils.getIconsDir(getContext(), 1.5);
String repoVersion = Integer.toString(Repo.VERSION_DENSITY_SPECIFIC_ICONS);
Log.d(TAG, "Updating icon paths for apps belonging to repos with version >= "
+ repoVersion);
Log.d(TAG, "Using icons dir '" + iconsDir + "'");
Log.d(TAG, "Using large icons dir '" + iconsDirLarge + "'");
String query = getIconUpdateQuery();
final String[] params = { repoVersion, iconsDir };
final String[] params = {
repoVersion, iconsDir, Utils.FALLBACK_ICONS_DIR,
repoVersion, iconsDirLarge, Utils.FALLBACK_ICONS_DIR };
write().execSQL(query, params);
}
@ -947,39 +951,51 @@ public class AppProvider extends FDroidProvider {
final String app = DBHelper.TABLE_APP;
final String repo = DBHelper.TABLE_REPO;
final String iconUrlQuery =
" SELECT " +
// Concatenate (using the "||" operator) the address, the
// icons directory (bound to the ? as the second parameter
// when executing the query) and the icon path.
" ( " +
repo + ".address " +
" || " +
// If the repo has the relevant version, then use a more
// intelligent icons dir, otherwise revert to the default
// one
" CASE WHEN " + repo + ".version >= ? THEN ? ELSE ? END " +
" || " +
app + ".icon " +
") " +
" FROM " +
apk +
" JOIN " + repo + " ON (" + repo + "._id = " + apk + ".repo) " +
" WHERE " +
app + ".id = " + apk + ".id AND " +
apk + ".vercode = ( " +
// We only want the latest apk here. Ideally, we should
// instead join onto apk.suggestedVercode, but as per
// https://gitlab.com/fdroid/fdroidclient/issues/1 there
// may be some situations where suggestedVercode isn't
// set.
// TODO: If we can guarantee that suggestedVercode is set,
// then join onto that instead. This will save from doing
// a futher sub query for each app.
" SELECT MAX(inner_apk.vercode) " +
" FROM fdroid_apk as inner_apk " +
" WHERE inner_apk.id = fdroid_apk.id ) " +
" AND fdroid_apk.repo = fdroid_repo._id ";
return
" UPDATE " + app + " SET iconUrl = ( " +
" SELECT " +
// Concatenate (using the "||" operator) the address, the icons directory (bound to the ? as the
// second parameter when executing the query) and the icon path.
" ( " +
repo + ".address " +
" || " +
// If the repo has the relevant version, then use a more intelligent icons dir,
// otherwise revert to '/icons/'
" CASE WHEN " + repo + ".version >= ? THEN ? ELSE '/icons/' END " +
" || " +
app + ".icon " +
") " +
" FROM " +
apk +
" JOIN " + repo + " ON (" + repo + "._id = " + apk + ".repo) " +
" WHERE " +
app + ".id = " + apk + ".id AND " +
apk + ".vercode = ( " +
// We only want the latest apk here. Ideally, we should instead join
// onto apk.suggestedVercode, but as per https://gitlab.com/fdroid/fdroidclient/issues/1
// there may be some situations where suggestedVercode isn't set.
// TODO: If we can guarantee that suggestedVercode is set, then join onto that instead.
// This will save from doing a futher sub query for each app.
" SELECT MAX(inner_apk.vercode) " +
" FROM fdroid_apk as inner_apk " +
" WHERE inner_apk.id = fdroid_apk.id ) " +
" AND fdroid_apk.repo = fdroid_repo._id " +
" UPDATE " + app + " SET " +
" iconUrl = ( " +
iconUrlQuery +
" ), " +
" iconUrlLarge = ( " +
iconUrlQuery +
" ) ";
}

View File

@ -89,6 +89,7 @@ public class DBHelper extends SQLiteOpenHelper {
+ "ignoreAllUpdates int not null,"
+ "ignoreThisUpdate int not null,"
+ "iconUrl text, "
+ "iconUrlLarge text, "
+ "primary key(id));";
public static final String TABLE_INSTALLED_APP = "fdroid_installedApp";
@ -100,7 +101,7 @@ public class DBHelper extends SQLiteOpenHelper {
+ InstalledAppProvider.DataColumns.APPLICATION_LABEL + " TEXT NOT NULL "
+ " );";
private static final int DB_VERSION = 48;
private static final int DB_VERSION = 49;
private final Context context;
@ -281,7 +282,8 @@ public class DBHelper extends SQLiteOpenHelper {
if (oldVersion < 43) createInstalledApp(db);
addAppLabelToInstalledCache(db, oldVersion);
addIsSwapToRepo(db, oldVersion);
addChangelogToRepo(db, oldVersion);
addChangelogToApp(db, oldVersion);
addIconUrlLargeToApp(db, oldVersion);
}
/**
@ -416,10 +418,17 @@ public class DBHelper extends SQLiteOpenHelper {
}
}
private void addChangelogToRepo(SQLiteDatabase db, int oldVersion) {
private void addChangelogToApp(SQLiteDatabase db, int oldVersion) {
if (oldVersion < 48 && !columnExists(db, TABLE_APP, "changelogURL")) {
Log.i(TAG, "Adding changelogURL column to " + TABLE_APP);
db.execSQL("Alter table " + TABLE_APP + " add column changelogURL text");
db.execSQL("alter table " + TABLE_APP + " add column changelogURL text");
}
}
private void addIconUrlLargeToApp(SQLiteDatabase db, int oldVersion) {
if (oldVersion < 49 && !columnExists(db, TABLE_APP, "iconUrlLarge")) {
Log.i(TAG, "Adding iconUrlLarge columns to " + TABLE_APP);
db.execSQL("alter table " + TABLE_APP + " add column iconUrlLarge text");
}
}