Fix repo update notifications

* Get rid of getAppsBasic(boolean)
* Use FDroidApp to read apps from UpdateService
  - Don't read the SQL tables twice if updating manually
  - Use two app lists, not three
* Notify regardless of the previous updates count
This commit is contained in:
Daniel Martí 2013-09-28 19:34:48 +02:00
parent 60dcf7f12c
commit fa1b53a81c
2 changed files with 23 additions and 129 deletions

View File

@ -609,8 +609,7 @@ public class DB {
// Get the number of apps that have updates available. This can be a // Get the number of apps that have updates available. This can be a
// time consuming operation. // time consuming operation.
public int getNumUpdates() { public int getNumUpdates(List<DB.App> apps) {
List<App> apps = getAppsBasic(true);
int count = 0; int count = 0;
for (App app : apps) { for (App app : apps) {
if (!app.ignoreUpdates && app.hasUpdates) if (!app.ignoreUpdates && app.hasUpdates)
@ -924,100 +923,6 @@ public class DB {
return apps; return apps;
} }
private List<App> getAppsBasic(boolean getinstalledinfo) {
// If we're going to need it, get info in what's currently installed
Map<String, PackageInfo> systemApks = null;
if (getinstalledinfo) {
Log.d("FDroid", "Reading installed packages");
systemApks = new HashMap<String, PackageInfo>();
List<PackageInfo> installedPackages = mContext.getPackageManager()
.getInstalledPackages(0);
for (PackageInfo appInfo : installedPackages) {
systemApks.put(appInfo.packageName, appInfo);
}
}
Map<String, App> apps = new HashMap<String, App>();
Cursor c = null;
long startTime = System.currentTimeMillis();
try {
String cols[] = new String[] { "id", "curVercode" };
c = db.query(TABLE_APP, cols, null, null, null, null, null);
c.moveToFirst();
while (!c.isAfterLast()) {
App app = new App();
app.id = c.getString(0);
app.curVercode = c.getInt(1);
app.hasUpdates = false;
if (getinstalledinfo && systemApks.containsKey(app.id)) {
PackageInfo sysapk = systemApks.get(app.id);
app.installedVerCode = sysapk.versionCode;
} else {
app.installedVerCode = 0;
}
apps.put(app.id, app);
c.moveToNext();
}
c.close();
c = null;
Log.d("FDroid", "Read basic app data from database " + " (took "
+ (System.currentTimeMillis() - startTime) + " ms)");
cols = new String[] { "id", "vercode", "repo" };
c = db.query(TABLE_APK, cols, null, null, null, null,
"vercode desc");
c.moveToFirst();
while (!c.isAfterLast()) {
Apk apk = new Apk();
apk.id = c.getString(0);
apk.vercode = c.getInt(1);
apk.repo = c.getInt(2);
apps.get(apk.id).apks.add(apk);
c.moveToNext();
}
c.close();
} catch (Exception e) {
Log.e("FDroid", "Exception during database reading:\n"
+ Log.getStackTraceString(e));
} finally {
if (c != null) {
c.close();
}
Log.d("FDroid", "Read basic app and apk data from database " +
" (took " + (System.currentTimeMillis() - startTime) +
" ms)");
}
List<App> result = new ArrayList<App>(apps.values());
Collections.sort(result);
// Fill in the hasUpdates fields if we have the necessary information...
if (getinstalledinfo) {
// We'll say an application has updates if it's installed AND the
// version is older than the current one
for (App app : result) {
Apk curver = app.getCurrentVersion();
if (curver != null
&& app.installedVerCode > 0
&& app.installedVerCode < curver.vercode) {
app.hasUpdates = true;
app.updateVersion = curver.version;
}
}
}
return result;
}
public List<String> doSearch(String query) { public List<String> doSearch(String query) {
List<String> ids = new ArrayList<String>(); List<String> ids = new ArrayList<String>();
@ -1070,27 +975,18 @@ public class DB {
private List<App> updateApps = null; private List<App> updateApps = null;
// Called before a repo update starts. Returns the number of updates // Called before a repo update starts.
// available beforehand. public void beginUpdate(List<DB.App> apps) {
public int beginUpdate(List<DB.App> apps) {
// Get a list of all apps. All the apps and apks in this list will // Get a list of all apps. All the apps and apks in this list will
// have 'updated' set to false at this point, and we will only set // have 'updated' set to false at this point, and we will only set
// it to true when we see the app/apk in a repository. Thus, at the // it to true when we see the app/apk in a repository. Thus, at the
// end, any that are still false can be removed. // end, any that are still false can be removed.
updateApps = apps; updateApps = apps;
Log.d("FDroid", "AppUpdate: " + updateApps.size() Log.d("FDroid", "AppUpdate: " + updateApps.size() + " apps before starting.");
+ " apps before starting.");
// Wrap the whole update in a transaction. Make sure to call // Wrap the whole update in a transaction. Make sure to call
// either endUpdate or cancelUpdate to commit or discard it, // either endUpdate or cancelUpdate to commit or discard it,
// respectively. // respectively.
db.beginTransaction(); db.beginTransaction();
int count = 0;
for (App app : updateApps) {
if (!app.ignoreUpdates && app.hasUpdates)
count++;
}
return count;
} }
// Called when a repo update ends. Any applications that have not been // Called when a repo update ends. Any applications that have not been
@ -1408,7 +1304,7 @@ public class DB {
db.delete(TABLE_REPO, "address = ?", db.delete(TABLE_REPO, "address = ?",
new String[] { address }); new String[] { address });
} }
List<App> apps = getAppsBasic(true); List<App> apps = getApps(false);
for (App app : apps) { for (App app : apps) {
if (app.apks.isEmpty()) { if (app.apks.isEmpty()) {
db.delete(TABLE_APP, "id = ?", new String[] { app.id }); db.delete(TABLE_APP, "id = ?", new String[] { app.id });

View File

@ -134,8 +134,7 @@ public class UpdateService extends IntentService implements ProgressListener {
// Grab some preliminary information, then we can release the // Grab some preliminary information, then we can release the
// database while we do all the downloading, etc... // database while we do all the downloading, etc...
int prevUpdates = 0; int updates = 0;
int newUpdates = 0;
List<DB.Repo> repos; List<DB.Repo> repos;
try { try {
DB db = DB.getDB(); DB db = DB.getDB();
@ -145,7 +144,7 @@ public class UpdateService extends IntentService implements ProgressListener {
} }
// Process each repo... // Process each repo...
List<DB.App> apps = new ArrayList<DB.App>(); List<DB.App> updatingApps = new ArrayList<DB.App>();
List<Integer> keeprepos = new ArrayList<Integer>(); List<Integer> keeprepos = new ArrayList<Integer>();
boolean success = true; boolean success = true;
boolean changes = false; boolean changes = false;
@ -159,7 +158,7 @@ public class UpdateService extends IntentService implements ProgressListener {
StringBuilder newetag = new StringBuilder(); StringBuilder newetag = new StringBuilder();
String err = RepoXMLHandler.doUpdate(getBaseContext(), String err = RepoXMLHandler.doUpdate(getBaseContext(),
repo, apps, newetag, keeprepos, this); repo, updatingApps, newetag, keeprepos, this);
if (err == null) { if (err == null) {
String nt = newetag.toString(); String nt = newetag.toString();
if (!nt.equals(repo.lastetag)) { if (!nt.equals(repo.lastetag)) {
@ -178,7 +177,6 @@ public class UpdateService extends IntentService implements ProgressListener {
} }
} }
List<DB.App> acceptedapps = new ArrayList<DB.App>();
if (!changes && success) { if (!changes && success) {
Log.d("FDroid", Log.d("FDroid",
"Not checking app details or compatibility, because all repos were up to date."); "Not checking app details or compatibility, because all repos were up to date.");
@ -186,7 +184,7 @@ public class UpdateService extends IntentService implements ProgressListener {
sendStatus(STATUS_INFO, sendStatus(STATUS_INFO,
getString(R.string.status_checking_compatibility)); getString(R.string.status_checking_compatibility));
List<DB.App> prevapps = ((FDroidApp) getApplication()).getApps(); List<DB.App> apps = ((FDroidApp) getApplication()).getApps();
DB db = DB.getDB(); DB db = DB.getDB();
try { try {
@ -195,7 +193,7 @@ public class UpdateService extends IntentService implements ProgressListener {
// no data about during the update. (i.e. stuff from a repo // no data about during the update. (i.e. stuff from a repo
// that we know is unchanged due to the etag) // that we know is unchanged due to the etag)
for (int keep : keeprepos) { for (int keep : keeprepos) {
for (DB.App app : prevapps) { for (DB.App app : apps) {
boolean keepapp = false; boolean keepapp = false;
for (DB.Apk apk : app.apks) { for (DB.Apk apk : app.apks) {
if (apk.repo == keep) { if (apk.repo == keep) {
@ -205,14 +203,14 @@ public class UpdateService extends IntentService implements ProgressListener {
} }
if (keepapp) { if (keepapp) {
DB.App app_k = null; DB.App app_k = null;
for (DB.App app2 : apps) { for (DB.App app2 : updatingApps) {
if (app2.id.equals(app.id)) { if (app2.id.equals(app.id)) {
app_k = app2; app_k = app2;
break; break;
} }
} }
if (app_k == null) { if (app_k == null) {
apps.add(app); updatingApps.add(app);
app_k = app; app_k = app;
} }
app_k.updated = true; app_k.updated = true;
@ -224,14 +222,15 @@ public class UpdateService extends IntentService implements ProgressListener {
} }
} }
prevUpdates = db.beginUpdate(prevapps); db.beginUpdate(apps);
for (DB.App app : apps) { for (DB.App app : updatingApps) {
if (db.updateApplication(app)) db.updateApplication(app);
acceptedapps.add(app);
} }
db.endUpdate(); db.endUpdate();
if (notify) if (notify) {
newUpdates = db.getNumUpdates(); apps = ((FDroidApp) getApplication()).getApps();
updates = db.getNumUpdates(apps);
}
for (DB.Repo repo : repos) for (DB.Repo repo : repos)
db.writeLastEtag(repo); db.writeLastEtag(repo);
} catch (Exception ex) { } catch (Exception ex) {
@ -249,9 +248,8 @@ public class UpdateService extends IntentService implements ProgressListener {
if (success && changes) if (success && changes)
((FDroidApp) getApplication()).invalidateAllApps(); ((FDroidApp) getApplication()).invalidateAllApps();
if (success && changes && notify && (newUpdates > prevUpdates)) { if (success && changes && notify && updates > 0) {
Log.d("FDroid", "Notifying updates. Apps before:" + prevUpdates Log.d("FDroid", "Notifying "+updates+" updates.");
+ ", apps after: " + newUpdates);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this) this)
.setSmallIcon(R.drawable.icon) .setSmallIcon(R.drawable.icon)
@ -263,9 +261,9 @@ public class UpdateService extends IntentService implements ProgressListener {
getString(R.string.fdroid_updates_available)); getString(R.string.fdroid_updates_available));
Intent notifyIntent = new Intent(this, FDroid.class) Intent notifyIntent = new Intent(this, FDroid.class)
.putExtra(FDroid.EXTRA_TAB_UPDATE, true); .putExtra(FDroid.EXTRA_TAB_UPDATE, true);
if (newUpdates > 1) { if (updates > 1) {
mBuilder.setContentText(getString( mBuilder.setContentText(getString(
R.string.many_updates_available, newUpdates)); R.string.many_updates_available, updates));
} else { } else {
mBuilder.setContentText(getString(R.string.one_update_available)); mBuilder.setContentText(getString(R.string.one_update_available));