diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java index 8d99d1c29..aecde9477 100644 --- a/src/org/fdroid/fdroid/AppDetails.java +++ b/src/org/fdroid/fdroid/AppDetails.java @@ -23,6 +23,8 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; +import org.fdroid.fdroid.DB.Apk.CompatibilityChecker; + import android.app.AlertDialog; import android.app.ListActivity; import android.app.ProgressDialog; @@ -157,13 +159,12 @@ public class AppDetails extends ListActivity { private static final int MARKET = Menu.FIRST + 5; private static final int DONATE = Menu.FIRST + 6; - private DB db; private DB.App app; private int app_currentvercode; private DB.Apk curapk; private String appid; + private CompatibilityChecker compatChecker; private PackageManager mPm; - private DB.Apk.CompatibilityChecker compatChecker; private DownloadHandler downloadHandler; private boolean stateRetained; @@ -197,8 +198,6 @@ public class AppDetails extends ListActivity { @Override protected void onStart() { super.onStart(); - db = new DB(this); - compatChecker = db.getCompatibilityChecker(); mPm = getPackageManager(); // Get the preferences we're going to use in this Activity... SharedPreferences prefs = PreferenceManager @@ -235,8 +234,6 @@ public class AppDetails extends ListActivity { @Override protected void onStop() { - db.close(); - db = null; super.onStop(); } @@ -275,8 +272,15 @@ public class AppDetails extends ListActivity { // also when something has been installed/uninstalled. private void reset() { Log.d("FDroid", "Getting application details for " + appid); - app = db.getApps(appid, null, true, false).get(0); - DB.Apk curver = app.getCurrentVersion(compatChecker); + DB.Apk curver; + try { + DB db = DB.getDB(); + compatChecker = db.getCompatibilityChecker(); + app = db.getApps(appid, null, true, false).get(0); + curver = app.getCurrentVersion(compatChecker); + } finally { + DB.releaseDB(); + } app_currentvercode = curver == null ? 0 : curver.vercode; // Get the signature of the installed package... diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java index 3a49e0a55..5d11483f0 100644 --- a/src/org/fdroid/fdroid/DB.java +++ b/src/org/fdroid/fdroid/DB.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; +import java.util.concurrent.Semaphore; import android.content.ContentValues; import android.content.Context; @@ -44,6 +45,31 @@ import android.util.Log; public class DB { + private static Semaphore dbSync = new Semaphore(1, true); + static DB dbInstance = null; + + // Initialise the database. Called once when the application starts up. + static void initDB(Context ctx) { + dbInstance = new DB(ctx); + } + + // Get access to the database. Must be called before any database activity, + // and releaseDB must be called subsequently. Returns null in the event of + // failure. + static DB getDB() { + try { + dbSync.acquire(); + return dbInstance; + } catch (InterruptedException e) { + return null; + } + } + + // Release database access lock acquired via getDB(). + static void releaseDB() { + dbSync.release(); + } + private static final String DATABASE_NAME = "fdroid"; // Possible values of the SQLite flag "synchronous" @@ -131,7 +157,7 @@ public class DB { // To skip compatibility checks, pass null as the checker. public Apk getCurrentVersion(DB.Apk.CompatibilityChecker checker) { - // Try and return the version that's in Google's market first... + // Try and return the real current version first... if (marketVersion != null && marketVercode > 0) { for (Apk apk : apks) { if (apk.vercode == marketVercode @@ -140,7 +166,7 @@ public class DB { } } - // If we don't know the market version, or we don't have it, we + // If we don't know the current version, or we don't have it, we // return the most recent compatible version we have... int latestcode = -1; Apk latestapk = null; @@ -396,7 +422,7 @@ public class DB { // database. private SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd"); - public DB(Context ctx) { + private DB(Context ctx) { mContext = ctx; DBHelper h = new DBHelper(ctx); @@ -568,12 +594,13 @@ public class DB { app.marketVercode = c.getInt(c .getColumnIndex("marketVercode")); String sAdded = c.getString(c.getColumnIndex("added")); - app.added = (sAdded == null || sAdded.length() == 0) ? null : mDateFormat - .parse(sAdded); + app.added = (sAdded == null || sAdded.length() == 0) ? null + : mDateFormat.parse(sAdded); String sLastUpdated = c.getString(c .getColumnIndex("lastUpdated")); - app.lastUpdated = (sLastUpdated == null || sLastUpdated.length() == 0) ? null - : mDateFormat.parse(sLastUpdated); + app.lastUpdated = (sLastUpdated == null || sLastUpdated + .length() == 0) ? null : mDateFormat + .parse(sLastUpdated); app.hasUpdates = false; c2 = db.rawQuery("select * from " + TABLE_APK @@ -873,8 +900,12 @@ public class DB { values.put("trackerURL", upapp.trackerURL); values.put("sourceURL", upapp.sourceURL); values.put("donateURL", upapp.donateURL); - values.put("added", upapp.added == null ? "" : mDateFormat.format(upapp.added)); - values.put("lastUpdated", upapp.added == null ? "" : mDateFormat.format(upapp.lastUpdated)); + values.put("added", + upapp.added == null ? "" : mDateFormat.format(upapp.added)); + values.put( + "lastUpdated", + upapp.added == null ? "" : mDateFormat + .format(upapp.lastUpdated)); values.put("marketVersion", upapp.marketVersion); values.put("marketVercode", upapp.marketVercode); values.put("antiFeatures", CommaSeparatedList.str(upapp.antiFeatures)); @@ -907,7 +938,8 @@ public class DB { values.put("apkName", upapk.apkName); values.put("apkSource", upapk.apkSource); values.put("minSdkVersion", upapk.minSdkVersion); - values.put("added", upapk.added == null ? "" : mDateFormat.format(upapk.added)); + values.put("added", + upapk.added == null ? "" : mDateFormat.format(upapk.added)); values.put("permissions", CommaSeparatedList.str(upapk.permissions)); values.put("features", CommaSeparatedList.str(upapk.features)); if (oldapk != null) { diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java index fba2a8976..104a459e2 100644 --- a/src/org/fdroid/fdroid/FDroid.java +++ b/src/org/fdroid/fdroid/FDroid.java @@ -70,8 +70,6 @@ public class FDroid extends TabActivity implements OnItemClickListener, private static final int ABOUT = Menu.FIRST + 3; private static final int SEARCH = Menu.FIRST + 4; - private DB db = null; - // Apps that are available to be installed private AppListAdapter apps_av = new AppListAdapter(this); @@ -135,14 +133,12 @@ public class FDroid extends TabActivity implements OnItemClickListener, @Override protected void onStart() { super.onStart(); - db = new DB(this); triedEmptyUpdate = false; populateLists(true); } @Override protected void onStop() { - db.close(); super.onStop(); } @@ -328,23 +324,34 @@ public class FDroid extends TabActivity implements OnItemClickListener, long startTime = System.currentTimeMillis(); - // Populate the category list with the real categories, and the locally - // generated meta-categories for "All", "What's New" and "Recently - // Updated"... - String cat_all = getString(R.string.category_all); - String cat_whatsnew = getString(R.string.category_whatsnew); - String cat_recentlyupdated = getString(R.string.category_recentlyupdated); - categories.add(cat_all); - for (String s : db.getCategories()) { - Log.d("FDroid", "s: " + s); - categories.add(s); - } - categories.add(cat_whatsnew); - categories.add(cat_recentlyupdated); - if (currentCategory == null) - currentCategory = cat_all; + DB db; + Vector apps; + String cat_all, cat_whatsnew, cat_recentlyupdated; + try { + db = DB.getDB(); + + // Populate the category list with the real categories, and the + // locally + // generated meta-categories for "All", "What's New" and "Recently + // Updated"... + cat_all = getString(R.string.category_all); + cat_whatsnew = getString(R.string.category_whatsnew); + cat_recentlyupdated = getString(R.string.category_recentlyupdated); + categories.add(cat_all); + for (String s : db.getCategories()) { + Log.d("FDroid", "s: " + s); + categories.add(s); + } + categories.add(cat_whatsnew); + categories.add(cat_recentlyupdated); + if (currentCategory == null) + currentCategory = cat_all; + + apps = db.getApps(null, null, update, true); + } finally { + DB.releaseDB(); + } - Vector apps = db.getApps(null, null, update, true); if (apps.isEmpty()) { // Don't attempt this more than once - we may have invalid // repositories. @@ -419,8 +426,9 @@ public class FDroid extends TabActivity implements OnItemClickListener, public UpdateReceiver(Handler handler) { super(handler); } + @Override - protected void onReceiveResult (int resultCode, Bundle resultData) { + protected void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode == 1) { Toast.makeText(FDroid.this, getString(R.string.connection_error_msg), @@ -432,6 +440,7 @@ public class FDroid extends TabActivity implements OnItemClickListener, pd.dismiss(); } } + private UpdateReceiver mUpdateReceiver; // Force a repo update now. A progress dialog is shown and the UpdateService diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java index aab5031c2..05d0d375a 100644 --- a/src/org/fdroid/fdroid/FDroidApp.java +++ b/src/org/fdroid/fdroid/FDroidApp.java @@ -22,5 +22,13 @@ import android.app.Application; public class FDroidApp extends Application { + @Override + public void onCreate() { + super.onCreate(); + + DB.initDB(getApplicationContext()); + } + } + diff --git a/src/org/fdroid/fdroid/ManageRepo.java b/src/org/fdroid/fdroid/ManageRepo.java index d9917bc1e..f241a3526 100644 --- a/src/org/fdroid/fdroid/ManageRepo.java +++ b/src/org/fdroid/fdroid/ManageRepo.java @@ -1,6 +1,6 @@ /* + * Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com * Copyright (C) 2009 Roberto Jacinto, roberto.jacinto@caixamagica.pt - * Copyright (C) 2010 Ciaran Gultnieks, ciaran@ciarang.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -44,8 +44,6 @@ import android.widget.SimpleAdapter; public class ManageRepo extends ListActivity { - private DB db = null; - private final int ADD_REPO = 1; private final int REM_REPO = 2; @@ -59,8 +57,6 @@ public class ManageRepo extends ListActivity { super.onCreate(savedInstanceState); setContentView(R.layout.repolist); - db = new DB(this); - } @Override @@ -71,7 +67,12 @@ public class ManageRepo extends ListActivity { } private void redraw() { - repos = db.getRepos(); + try { + DB db = DB.getDB(); + repos = db.getRepos(); + } finally { + DB.releaseDB(); + } List> result = new ArrayList>(); Map server_line; @@ -91,22 +92,22 @@ public class ManageRepo extends ListActivity { byte[] fingerprint = digest.digest(); Formatter formatter = new Formatter(new StringBuilder()); formatter.format("%02X", fingerprint[0]); - for (int i=1; i < fingerprint.length; i++) { + for (int i = 1; i < fingerprint.length; i++) { formatter.format(i % 5 == 0 ? " %02X" : ":%02X", - fingerprint[i]); + fingerprint[i]); } server_line.put("fingerprint", formatter.toString()); } catch (Exception e) { Log.w("FDroid", "Unable to get certificate fingerprint.\n" - + Log.getStackTraceString(e)); + + Log.getStackTraceString(e)); } } result.add(server_line); } SimpleAdapter show_out = new SimpleAdapter(this, result, - R.layout.repolisticons, - new String[] { "address", "inuse", "fingerprint" }, - new int[] { R.id.uri, R.id.img, R.id.fingerprint }); + R.layout.repolisticons, new String[] { "address", "inuse", + "fingerprint" }, new int[] { R.id.uri, R.id.img, + R.id.fingerprint }); setListAdapter(show_out); } @@ -115,7 +116,12 @@ public class ManageRepo extends ListActivity { protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); - db.changeServerStatus(repos.get(position).address); + try { + DB db = DB.getDB(); + db.changeServerStatus(repos.get(position).address); + } finally { + DB.releaseDB(); + } changed = true; redraw(); } @@ -150,7 +156,12 @@ public class ManageRepo extends ListActivity { EditText uri = (EditText) alrt .findViewById(R.id.edit_uri); String uri_str = uri.getText().toString(); - db.addServer(uri_str, 10, null); + try { + DB db = DB.getDB(); + db.addServer(uri_str, 10, null); + } finally { + DB.releaseDB(); + } changed = true; redraw(); } @@ -180,11 +191,9 @@ public class ManageRepo extends ListActivity { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { if (isChecked) { - rem_lst - .addElement(repos.get(whichButton).address); + rem_lst.addElement(repos.get(whichButton).address); } else { - rem_lst - .removeElement(repos.get(whichButton).address); + rem_lst.removeElement(repos.get(whichButton).address); } } }); @@ -192,7 +201,12 @@ public class ManageRepo extends ListActivity { new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { - db.removeServers(rem_lst); + try { + DB db = DB.getDB(); + db.removeServers(rem_lst); + } finally { + DB.releaseDB(); + } changed = true; redraw(); } @@ -217,7 +231,6 @@ public class ManageRepo extends ListActivity { if (changed) ret.putExtra("update", true); this.setResult(RESULT_OK, ret); - db.close(); super.finish(); } diff --git a/src/org/fdroid/fdroid/SearchResults.java b/src/org/fdroid/fdroid/SearchResults.java index 7d6d280ad..18707401a 100644 --- a/src/org/fdroid/fdroid/SearchResults.java +++ b/src/org/fdroid/fdroid/SearchResults.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Ciaran Gultnieks, ciaran@ciarang.com + * Copyright (C) 2011-12 Ciaran Gultnieks, ciaran@ciarang.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -67,8 +67,13 @@ public class SearchResults extends ListActivity { } private void updateView() { - DB db = new DB(this); - Vector apps = db.getApps(null, mQuery, false, true); + Vector apps; + try { + DB db = DB.getDB(); + apps = db.getApps(null, mQuery, false, true); + } finally { + DB.releaseDB(); + } TextView tv = (TextView) findViewById(R.id.description); String headertext; if(apps.size()==0) @@ -86,7 +91,6 @@ public class SearchResults extends ListActivity { } applist.notifyDataSetChanged(); setListAdapter(applist); - db.close(); } diff --git a/src/org/fdroid/fdroid/UpdateService.java b/src/org/fdroid/fdroid/UpdateService.java index 84efae659..a6e618d01 100644 --- a/src/org/fdroid/fdroid/UpdateService.java +++ b/src/org/fdroid/fdroid/UpdateService.java @@ -89,7 +89,7 @@ public class UpdateService extends IntentService { // Do the update... DB db = null; try { - db = new DB(getBaseContext()); + db = DB.getDB(); boolean notify = prefs.getBoolean("updateNotify", false); // Get the number of updates available before we @@ -141,7 +141,7 @@ public class UpdateService extends IntentService { } } finally { if (db != null) - db.close(); + DB.releaseDB(); } }