diff --git a/res/values/strings.xml b/res/values/strings.xml
index 872d12650..587bb6aa3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -117,6 +117,8 @@
Application compatibility
Incompatible apps
Show apps written for newer Android versions or different hardware
+ Root
+ Show apps that require root privileges
Ignore Touchscreen
Always include apps that require touchscreen
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index b40c96113..f755058ef 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -28,6 +28,9 @@
+
diff --git a/src/org/fdroid/fdroid/AppFilter.java b/src/org/fdroid/fdroid/AppFilter.java
new file mode 100644
index 000000000..6cd688d7e
--- /dev/null
+++ b/src/org/fdroid/fdroid/AppFilter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010-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
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.fdroid.fdroid;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+public class AppFilter {
+
+ boolean pref_rooted;
+
+ public AppFilter(Context ctx) {
+
+ // Read preferences and cache them so we can do quick lookups.
+ SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(ctx);
+ pref_rooted = prefs.getBoolean("rooted", true);
+ }
+
+ // Return true if the given app should be filtered out based on user
+ // preferences, and false otherwise.
+ public boolean filter(DB.App app) {
+ if (app.requirements == null) return false;
+ for (String r : app.requirements) {
+ if (r.equals("root") && !pref_rooted)
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/org/fdroid/fdroid/AppListManager.java b/src/org/fdroid/fdroid/AppListManager.java
index c2fb21203..258f419b3 100644
--- a/src/org/fdroid/fdroid/AppListManager.java
+++ b/src/org/fdroid/fdroid/AppListManager.java
@@ -197,9 +197,9 @@ public class AppListManager {
boolean isInCategory = isInCategory(app, currentCategory, recentDate);
// Add it to the list(s). Always to installed and updates, but
- // only to available if it's compatible (or incompatible with
- // showIncompatible at true)
- if (isInCategory && (showIncompatible || app.compatible)) {
+ // only to available if it's not filtered.
+ if (!app.filtered && isInCategory
+ && (showIncompatible || app.compatible)) {
availApps.add(app);
}
if (app.installedVersion != null) {
diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java
index 5482d6200..10c7ee81d 100644
--- a/src/org/fdroid/fdroid/DB.java
+++ b/src/org/fdroid/fdroid/DB.java
@@ -96,7 +96,7 @@ public class DB {
+ "curVersion text," + "curVercode integer,"
+ "antiFeatures string," + "donateURL string,"
+ "bitcoinAddr string," + "litecoinAddr string,"
- + "flattrID string,"
+ + "flattrID string," + "requirements string,"
+ "category string," + "added string,"
+ "lastUpdated string," + "compatible int not null,"
+ "ignoreAllUpdates int not null,"
@@ -119,6 +119,7 @@ public class DB {
detail_litecoinAddr = null;
detail_webURL = null;
antiFeatures = null;
+ requirements = null;
hasUpdates = false;
toUpdate = false;
updated = false;
@@ -129,6 +130,7 @@ public class DB {
compatible = false;
ignoreAllUpdates = false;
ignoreThisUpdate = 0;
+ filtered = false;
iconUrl = null;
}
@@ -191,6 +193,14 @@ public class DB {
// documentation) or null if there aren't any.
public CommaSeparatedList antiFeatures;
+ // List of special requirements (such as root privileges) or
+ // null if there aren't any.
+ public CommaSeparatedList requirements;
+
+ // Whether the app is filtered or not based on AntiFeatures and root
+ // permission (set in the Settings page)
+ public boolean filtered;
+
// True if there are new versions (apks) available, regardless of
// any filtering
public boolean hasUpdates;
@@ -430,7 +440,7 @@ public class DB {
public String lastetag; // last etag we updated from, null forces update
}
- private final int DBVersion = 28;
+ private final int DBVersion = 27;
private static void createAppApk(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_APP);
@@ -749,7 +759,7 @@ public class DB {
long startTime = System.currentTimeMillis();
try {
- String cols[] = new String[] { "antiFeatures",
+ String cols[] = new String[] { "antiFeatures", "requirements",
"id", "name", "summary", "icon", "license", "category",
"curVersion", "curVercode", "added", "lastUpdated",
"compatible", "ignoreAllUpdates", "ignoreThisUpdate" };
@@ -759,24 +769,25 @@ public class DB {
App app = new App();
app.antiFeatures = DB.CommaSeparatedList.make(c.getString(0));
- app.id = c.getString(1);
- app.name = c.getString(2);
- app.summary = c.getString(3);
- app.icon = c.getString(4);
- app.license = c.getString(5);
- app.category = c.getString(6);
- app.curVersion = c.getString(7);
- app.curVercode = c.getInt(8);
- String sAdded = c.getString(9);
+ app.requirements = DB.CommaSeparatedList.make(c.getString(1));
+ app.id = c.getString(2);
+ app.name = c.getString(3);
+ app.summary = c.getString(4);
+ app.icon = c.getString(5);
+ app.license = c.getString(6);
+ app.category = c.getString(7);
+ app.curVersion = c.getString(8);
+ app.curVercode = c.getInt(9);
+ String sAdded = c.getString(10);
app.added = (sAdded == null || sAdded.length() == 0) ? null
: mDateFormat.parse(sAdded);
- String sLastUpdated = c.getString(10);
+ String sLastUpdated = c.getString(11);
app.lastUpdated = (sLastUpdated == null || sLastUpdated
.length() == 0) ? null : mDateFormat
.parse(sLastUpdated);
- app.compatible = c.getInt(11) == 1;
- app.ignoreAllUpdates = c.getInt(12) == 1;
- app.ignoreThisUpdate = c.getInt(13);
+ app.compatible = c.getInt(12) == 1;
+ app.ignoreAllUpdates = c.getInt(13) == 1;
+ app.ignoreThisUpdate = c.getInt(14);
app.hasUpdates = false;
if (getinstalledinfo && systemApks.containsKey(app.id)) {
@@ -1134,6 +1145,7 @@ public class DB {
values.put("curVersion", upapp.curVersion);
values.put("curVercode", upapp.curVercode);
values.put("antiFeatures", CommaSeparatedList.str(upapp.antiFeatures));
+ values.put("requirements", CommaSeparatedList.str(upapp.requirements));
values.put("compatible", upapp.compatible ? 1 : 0);
// Values to keep if already present
diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java
index 2915a37aa..a0eeade1e 100644
--- a/src/org/fdroid/fdroid/FDroidApp.java
+++ b/src/org/fdroid/fdroid/FDroidApp.java
@@ -196,10 +196,14 @@ public class FDroidApp extends Application {
}
public void filterApps() {
+ AppFilter appFilter = new AppFilter(ctx);
for (DB.App app : apps) {
+ app.filtered = appFilter.filter(app);
+
app.toUpdate = (app.hasUpdates
&& !app.ignoreAllUpdates
&& app.curApk.vercode > app.ignoreThisUpdate
+ && !app.filtered
&& (showIncompatible || app.compatible));
}
}
diff --git a/src/org/fdroid/fdroid/RepoXMLHandler.java b/src/org/fdroid/fdroid/RepoXMLHandler.java
index d5419050e..f29c7d752 100644
--- a/src/org/fdroid/fdroid/RepoXMLHandler.java
+++ b/src/org/fdroid/fdroid/RepoXMLHandler.java
@@ -235,6 +235,8 @@ public class RepoXMLHandler extends DefaultHandler {
}
} else if (curel.equals("antifeatures")) {
curapp.antiFeatures = DB.CommaSeparatedList.make(str);
+ } else if (curel.equals("requirements")) {
+ curapp.requirements = DB.CommaSeparatedList.make(str);
}
}
}
diff --git a/src/org/fdroid/fdroid/views/AppListAdapter.java b/src/org/fdroid/fdroid/views/AppListAdapter.java
index f335ce15b..41044bd14 100644
--- a/src/org/fdroid/fdroid/views/AppListAdapter.java
+++ b/src/org/fdroid/fdroid/views/AppListAdapter.java
@@ -111,7 +111,7 @@ abstract public class AppListAdapter extends BaseAdapter {
// Disable it all if it isn't compatible...
View[] views = { convertView, status, summary, license, name };
for (View view : views) {
- view.setEnabled(app.compatible);
+ view.setEnabled(app.compatible && !app.filtered);
}
return convertView;