Added new table to store user preferences.
Haven't yet migrated data from the old location in the app table yet.
This commit is contained in:
parent
3c5f8756f4
commit
d47967e03d
@ -95,6 +95,11 @@
|
||||
android:name="org.fdroid.fdroid.data.InstalledAppProvider"
|
||||
android:exported="false"/>
|
||||
|
||||
<provider
|
||||
android:authorities="org.fdroid.fdroid.data.AppPrefsProvider"
|
||||
android:name="org.fdroid.fdroid.data.AppPrefsProvider"
|
||||
android:exported="false"/>
|
||||
|
||||
<provider
|
||||
android:name="org.fdroid.fdroid.installer.ApkFileProvider"
|
||||
android:authorities="org.fdroid.fdroid.installer.ApkFileProvider"
|
||||
|
24
app/src/main/java/org/fdroid/fdroid/data/AppPrefs.java
Normal file
24
app/src/main/java/org/fdroid/fdroid/data/AppPrefs.java
Normal file
@ -0,0 +1,24 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
public class AppPrefs extends ValueObject {
|
||||
|
||||
/**
|
||||
* True if all updates for this app are to be ignored
|
||||
*/
|
||||
public final boolean ignoreAllUpdates;
|
||||
|
||||
/**
|
||||
* True if the current update for this app is to be ignored
|
||||
*/
|
||||
public final int ignoreThisUpdate;
|
||||
|
||||
public AppPrefs(int ignoreThis, boolean ignoreAll) {
|
||||
ignoreThisUpdate = ignoreThis;
|
||||
ignoreAllUpdates = ignoreAll;
|
||||
}
|
||||
|
||||
public static AppPrefs createDefault() {
|
||||
return new AppPrefs(0, false);
|
||||
}
|
||||
|
||||
}
|
173
app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java
Normal file
173
app/src/main/java/org/fdroid/fdroid/data/AppPrefsProvider.java
Normal file
@ -0,0 +1,173 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.fdroid.fdroid.data.Schema.AppPrefsTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppPrefsTable.Cols;
|
||||
|
||||
public class AppPrefsProvider extends FDroidProvider {
|
||||
|
||||
private static final String TAG = "AppPrefsProvider";
|
||||
|
||||
public static final class Helper {
|
||||
private Helper() { }
|
||||
|
||||
public static void update(Context context, App app, AppPrefs prefs) {
|
||||
ContentValues values = new ContentValues(3);
|
||||
values.put(Cols.IGNORE_ALL_UPDATES, prefs.ignoreAllUpdates);
|
||||
values.put(Cols.IGNORE_THIS_UPDATE, prefs.ignoreThisUpdate);
|
||||
|
||||
if (getPrefsOrNull(context, app) == null) {
|
||||
values.put(Cols.APP_ID, app.getId());
|
||||
context.getContentResolver().insert(getContentUri(), values);
|
||||
} else {
|
||||
context.getContentResolver().update(getAppUri(app.getId()), values, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static AppPrefs getPrefsOrDefault(Context context, App app) {
|
||||
AppPrefs prefs = getPrefsOrNull(context, app);
|
||||
return prefs == null ? AppPrefs.createDefault() : prefs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AppPrefs getPrefsOrNull(Context context, App app) {
|
||||
Cursor cursor = context.getContentResolver().query(getAppUri(app.getId()), Cols.ALL, null, null, null);
|
||||
if (cursor == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (cursor.getCount() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
cursor.moveToFirst();
|
||||
return new AppPrefs(
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(Cols.IGNORE_THIS_UPDATE)),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(Cols.IGNORE_ALL_UPDATES)) > 0);
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Query extends QueryBuilder {
|
||||
|
||||
@Override
|
||||
protected String getRequiredTables() {
|
||||
return AppPrefsTable.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addField(String field) {
|
||||
appendField(field, getTableName());
|
||||
}
|
||||
}
|
||||
|
||||
private static final String PROVIDER_NAME = "AppPrefsProvider";
|
||||
|
||||
private static final UriMatcher MATCHER = new UriMatcher(-1);
|
||||
|
||||
private static final String PATH_APP_ID = "appId";
|
||||
|
||||
static {
|
||||
MATCHER.addURI(getAuthority(), PATH_APP_ID + "/#", CODE_SINGLE);
|
||||
}
|
||||
|
||||
private static Uri getContentUri() {
|
||||
return Uri.parse("content://" + getAuthority());
|
||||
}
|
||||
|
||||
public static Uri getAppUri(long appId) {
|
||||
return getContentUri().buildUpon().appendPath(PATH_APP_ID).appendPath(Long.toString(appId)).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTableName() {
|
||||
return AppPrefsTable.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProviderName() {
|
||||
return "AppPrefsProvider";
|
||||
}
|
||||
|
||||
public static String getAuthority() {
|
||||
return AUTHORITY + "." + PROVIDER_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UriMatcher getMatcher() {
|
||||
return MATCHER;
|
||||
}
|
||||
|
||||
protected QuerySelection querySingle(long appId) {
|
||||
final String selection = getTableName() + "." + Cols.APP_ID + " = ?";
|
||||
final String[] args = {Long.toString(appId)};
|
||||
return new QuerySelection(selection, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String customSelection, String[] selectionArgs, String sortOrder) {
|
||||
QuerySelection selection = new QuerySelection(customSelection, selectionArgs);
|
||||
|
||||
switch (MATCHER.match(uri)) {
|
||||
case CODE_SINGLE:
|
||||
selection = selection.add(querySingle(Long.parseLong(uri.getLastPathSegment())));
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.e(TAG, "Invalid URI for app content provider: " + uri);
|
||||
throw new UnsupportedOperationException("Invalid URI for app content provider: " + uri);
|
||||
}
|
||||
|
||||
Query query = new Query();
|
||||
query.addSelection(selection);
|
||||
query.addFields(projection);
|
||||
query.addOrderBy(sortOrder);
|
||||
|
||||
Cursor cursor = LoggingQuery.query(db(), query.toString(), query.getArgs());
|
||||
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String where, String[] whereArgs) {
|
||||
switch (MATCHER.match(uri)) {
|
||||
default:
|
||||
throw new UnsupportedOperationException("Delete not supported for " + uri + ".");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
db().insertOrThrow(getTableName(), null, values);
|
||||
if (!isApplyingBatch()) {
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
}
|
||||
return getAppUri(values.getAsLong(Cols.APP_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
|
||||
switch (MATCHER.match(uri)) {
|
||||
case CODE_SINGLE:
|
||||
QuerySelection query = new QuerySelection(where, whereArgs)
|
||||
.add(querySingle(Long.parseLong(uri.getLastPathSegment())));
|
||||
return db().update(getTableName(), values, query.getSelection(), query.getArgs());
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Update not supported for " + uri + ".");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import android.util.Log;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.Schema.ApkTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppPrefsTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppTable;
|
||||
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
|
||||
import org.fdroid.fdroid.data.Schema.RepoTable;
|
||||
@ -101,6 +102,13 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
+ AppTable.Cols.ICON_URL_LARGE + " text, "
|
||||
+ "primary key(" + AppTable.Cols.PACKAGE_NAME + "));";
|
||||
|
||||
private static final String CREATE_TABLE_APP_PREFS = "CREATE TABLE " + AppPrefsTable.NAME
|
||||
+ " ( "
|
||||
+ AppPrefsTable.Cols.APP_ID + " INT REFERENCES " + AppTable.NAME + "(" + AppTable.Cols.ROW_ID + ") ON DELETE CASCADE, "
|
||||
+ AppPrefsTable.Cols.IGNORE_THIS_UPDATE+ " INT BOOLEAN NOT NULL, "
|
||||
+ AppPrefsTable.Cols.IGNORE_ALL_UPDATES + " INT NOT NULL "
|
||||
+ " );";
|
||||
|
||||
private static final String CREATE_TABLE_INSTALLED_APP = "CREATE TABLE " + InstalledAppTable.NAME
|
||||
+ " ( "
|
||||
+ InstalledAppTable.Cols.PACKAGE_NAME + " TEXT NOT NULL PRIMARY KEY, "
|
||||
@ -219,6 +227,7 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
createAppApk(db);
|
||||
db.execSQL(CREATE_TABLE_INSTALLED_APP);
|
||||
db.execSQL(CREATE_TABLE_REPO);
|
||||
db.execSQL(CREATE_TABLE_APP_PREFS);
|
||||
|
||||
insertRepo(
|
||||
db,
|
||||
|
@ -9,6 +9,19 @@ import android.provider.BaseColumns;
|
||||
*/
|
||||
public interface Schema {
|
||||
|
||||
interface AppPrefsTable {
|
||||
|
||||
String NAME = "fdroid_appPrefs";
|
||||
|
||||
interface Cols extends BaseColumns {
|
||||
String APP_ID = "appId";
|
||||
String IGNORE_ALL_UPDATES = "ignoreAllUpdates";
|
||||
String IGNORE_THIS_UPDATE = "ignoreThisUpdate";
|
||||
|
||||
String[] ALL = {APP_ID, IGNORE_ALL_UPDATES, IGNORE_THIS_UPDATE,};
|
||||
}
|
||||
}
|
||||
|
||||
interface AppTable {
|
||||
|
||||
String NAME = "fdroid_app";
|
||||
|
@ -0,0 +1,56 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import org.fdroid.fdroid.Assert;
|
||||
import org.fdroid.fdroid.BuildConfig;
|
||||
import org.fdroid.fdroid.TestUtils;
|
||||
import org.fdroid.fdroid.data.Schema.AppPrefsTable.Cols;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
@Config(constants = BuildConfig.class, application = Application.class)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class AppPrefsProviderTest extends FDroidProviderTest {
|
||||
|
||||
private static final String[] PROJ = Cols.ALL;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
ShadowContentResolver.registerProvider(AppProvider.getAuthority(), new AppProvider());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newPreferences() {
|
||||
App withPrefs = Assert.insertApp(context, "com.example.withPrefs", "With Prefs");
|
||||
App withoutPrefs = Assert.insertApp(context, "com.example.withoutPrefs", "Without Prefs");
|
||||
|
||||
assertNull(AppPrefsProvider.Helper.getPrefsOrNull(context, withPrefs));
|
||||
assertNull(AppPrefsProvider.Helper.getPrefsOrNull(context, withoutPrefs));
|
||||
|
||||
AppPrefs defaultPrefs = AppPrefsProvider.Helper.getPrefsOrDefault(context, withPrefs);
|
||||
assertEquals(0, defaultPrefs.ignoreThisUpdate);
|
||||
assertFalse(defaultPrefs.ignoreAllUpdates);
|
||||
|
||||
AppPrefsProvider.Helper.update(context, withPrefs, new AppPrefs(12, false));
|
||||
AppPrefs newPrefs = AppPrefsProvider.Helper.getPrefsOrDefault(context, withPrefs);
|
||||
assertEquals(12, newPrefs.ignoreThisUpdate);
|
||||
assertFalse(newPrefs.ignoreAllUpdates);
|
||||
|
||||
AppPrefsProvider.Helper.update(context, withPrefs, new AppPrefs(14, true));
|
||||
AppPrefs evenNewerPrefs = AppPrefsProvider.Helper.getPrefsOrDefault(context, withPrefs);
|
||||
assertEquals(14, evenNewerPrefs.ignoreThisUpdate);
|
||||
assertTrue(evenNewerPrefs.ignoreAllUpdates);
|
||||
|
||||
assertNull(AppPrefsProvider.Helper.getPrefsOrNull(context, withoutPrefs));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user