From 1d3befcbd2472d59f36629b8529c0ee522c86987 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Thu, 4 Jan 2018 21:45:44 -0600 Subject: [PATCH 1/5] Injected the CategoryDao where needed. --- .../category/CategorizationFragment.java | 9 ++----- .../fr/free/nrw/commons/data/CategoryDao.java | 26 ++++++++++++++----- .../commons/di/CommonsApplicationModule.java | 9 +++++++ .../nrw/commons/data/CategoryDaoTest.java | 10 +++---- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java index 335f7364c..fe70d126d 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java @@ -1,6 +1,5 @@ package fr.free.nrw.commons.category; -import android.content.ContentProviderClient; import android.content.SharedPreferences; import android.os.Bundle; import android.support.v7.app.AlertDialog; @@ -48,7 +47,6 @@ import timber.log.Timber; import static android.view.KeyEvent.ACTION_UP; import static android.view.KeyEvent.KEYCODE_BACK; -import static fr.free.nrw.commons.category.CategoryContentProvider.AUTHORITY; /** * Displays the category suggestion and selection screen. Category search is initiated here. @@ -70,12 +68,12 @@ public class CategorizationFragment extends DaggerFragment { @Inject MediaWikiApi mwApi; @Inject @Named("default_preferences") SharedPreferences prefs; + @Inject CategoryDao categoryDao; private RVRendererAdapter categoriesAdapter; private OnCategoriesSaveHandler onCategoriesSaveHandler; private HashMap> categoriesCache; private List selectedCategories = new ArrayList<>(); - private ContentProviderClient databaseClient; private final CategoriesAdapterFactory adapterFactory = new CategoriesAdapterFactory(item -> { if (item.isSelected()) { @@ -141,7 +139,6 @@ public class CategorizationFragment extends DaggerFragment { @Override public void onDestroy() { super.onDestroy(); - databaseClient.release(); } @Override @@ -179,7 +176,6 @@ public class CategorizationFragment extends DaggerFragment { setHasOptionsMenu(true); onCategoriesSaveHandler = (OnCategoriesSaveHandler) getActivity(); getActivity().setTitle(R.string.categories_activity_title); - databaseClient = getActivity().getContentResolver().acquireContentProviderClient(AUTHORITY); } private void updateCategoryList(String filter) { @@ -262,7 +258,7 @@ public class CategorizationFragment extends DaggerFragment { } private Observable recentCategories() { - return Observable.fromIterable(new CategoryDao(databaseClient).recentCategories(SEARCH_CATS_LIMIT)) + return Observable.fromIterable(categoryDao.recentCategories(SEARCH_CATS_LIMIT)) .map(s -> new CategoryItem(s, false)); } @@ -313,7 +309,6 @@ public class CategorizationFragment extends DaggerFragment { } private void updateCategoryCount(CategoryItem item) { - CategoryDao categoryDao = new CategoryDao(databaseClient); Category category = categoryDao.find(item.getName()); // Newly used category... diff --git a/app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java b/app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java index 8bae4a522..0660fcaf1 100644 --- a/app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java +++ b/app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java @@ -12,25 +12,33 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + import fr.free.nrw.commons.category.CategoryContentProvider; public class CategoryDao { - private final ContentProviderClient client; + private final Provider clientProvider; - public CategoryDao(ContentProviderClient client) { - this.client = client; + @Inject + public CategoryDao(@Named("category") Provider clientProvider) { + this.clientProvider = clientProvider; } public void save(Category category) { + ContentProviderClient db = clientProvider.get(); try { if (category.getContentUri() == null) { - category.setContentUri(client.insert(CategoryContentProvider.BASE_URI, toContentValues(category))); + category.setContentUri(db.insert(CategoryContentProvider.BASE_URI, toContentValues(category))); } else { - client.update(category.getContentUri(), toContentValues(category), null, null); + db.update(category.getContentUri(), toContentValues(category), null, null); } } catch (RemoteException e) { throw new RuntimeException(e); + } finally { + db.release(); } } @@ -43,8 +51,9 @@ public class CategoryDao { public @Nullable Category find(String name) { Cursor cursor = null; + ContentProviderClient db = clientProvider.get(); try { - cursor = client.query( + cursor = db.query( CategoryContentProvider.BASE_URI, Table.ALL_FIELDS, Table.COLUMN_NAME + "=?", @@ -60,6 +69,7 @@ public class CategoryDao { if (cursor != null) { cursor.close(); } + db.release(); } return null; } @@ -73,8 +83,9 @@ public class CategoryDao { List recentCategories(int limit) { List items = new ArrayList<>(); Cursor cursor = null; + ContentProviderClient db = clientProvider.get(); try { - cursor = client.query( + cursor = db.query( CategoryContentProvider.BASE_URI, Table.ALL_FIELDS, null, @@ -91,6 +102,7 @@ public class CategoryDao { if (cursor != null) { cursor.close(); } + db.release(); } return items; } diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java index 99d3235e7..67f1f8edd 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java @@ -1,5 +1,6 @@ package fr.free.nrw.commons.di; +import android.content.ContentProviderClient; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v4.util.LruCache; @@ -26,6 +27,8 @@ import static android.content.Context.MODE_PRIVATE; @Module @SuppressWarnings({"WeakerAccess", "unused"}) public class CommonsApplicationModule { + public static final String CATEGORY_AUTHORITY = "fr.free.nrw.commons.categories.contentprovider"; + private CommonsApplication application; public CommonsApplicationModule(CommonsApplication application) { @@ -37,6 +40,12 @@ public class CommonsApplicationModule { return new AccountUtil(application); } + @Provides + @Named("category") + public ContentProviderClient provideContentProviderClient() { + return application.getContentResolver().acquireContentProviderClient(CATEGORY_AUTHORITY); + } + @Provides @Named("application_preferences") public SharedPreferences providesApplicationSharedPreferences() { diff --git a/app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java b/app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java index 62d4f4d2c..b5bb53c0b 100644 --- a/app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java +++ b/app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java @@ -50,20 +50,20 @@ import static org.mockito.Mockito.when; public class CategoryDaoTest { @Mock - ContentProviderClient client; + private ContentProviderClient client; @Mock - SQLiteDatabase database; + private SQLiteDatabase database; @Captor - ArgumentCaptor captor; + private ArgumentCaptor captor; @Captor - ArgumentCaptor queryCaptor; + private ArgumentCaptor queryCaptor; private CategoryDao testObject; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - testObject = new CategoryDao(client); + testObject = new CategoryDao(() -> client); } @Test From f2ed57a127f0c3ffc801e42d2df13fdee7728a9a Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Thu, 4 Jan 2018 21:52:12 -0600 Subject: [PATCH 2/5] Moved Category and CategoryDao to the 'category' package --- .../main/java/fr/free/nrw/commons/CommonsApplication.java | 2 +- .../free/nrw/commons/category/CategorizationFragment.java | 2 -- .../fr/free/nrw/commons/{data => category}/Category.java | 2 +- .../free/nrw/commons/category/CategoryContentProvider.java | 6 +++--- .../fr/free/nrw/commons/{data => category}/CategoryDao.java | 6 ++---- .../main/java/fr/free/nrw/commons/data/DBOpenHelper.java | 1 + .../nrw/commons/{data => category}/CategoryDaoTest.java | 5 ++--- 7 files changed, 10 insertions(+), 14 deletions(-) rename app/src/main/java/fr/free/nrw/commons/{data => category}/Category.java (97%) rename app/src/main/java/fr/free/nrw/commons/{data => category}/CategoryDao.java (97%) rename app/src/test/java/fr/free/nrw/commons/{data => category}/CategoryDaoTest.java (98%) diff --git a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java index b7e1a6039..5faf0c1d0 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -21,8 +21,8 @@ import javax.inject.Named; import dagger.android.AndroidInjector; import dagger.android.DaggerApplication; import fr.free.nrw.commons.auth.SessionManager; +import fr.free.nrw.commons.category.CategoryDao; import fr.free.nrw.commons.contributions.ContributionDao; -import fr.free.nrw.commons.data.CategoryDao; import fr.free.nrw.commons.data.DBOpenHelper; import fr.free.nrw.commons.di.CommonsApplicationComponent; import fr.free.nrw.commons.di.CommonsApplicationModule; diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java index fe70d126d..4787d0e4f 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java @@ -35,8 +35,6 @@ import butterknife.BindView; import butterknife.ButterKnife; import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.data.Category; -import fr.free.nrw.commons.data.CategoryDao; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.upload.MwVolleyApi; import fr.free.nrw.commons.utils.StringSortingUtils; diff --git a/app/src/main/java/fr/free/nrw/commons/data/Category.java b/app/src/main/java/fr/free/nrw/commons/category/Category.java similarity index 97% rename from app/src/main/java/fr/free/nrw/commons/data/Category.java rename to app/src/main/java/fr/free/nrw/commons/category/Category.java index 9a32f3a7a..f2d83d2e5 100644 --- a/app/src/main/java/fr/free/nrw/commons/data/Category.java +++ b/app/src/main/java/fr/free/nrw/commons/category/Category.java @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.data; +package fr.free.nrw.commons.category; import android.net.Uri; diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java index 3384a984b..dcc1bc6f2 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java @@ -17,9 +17,9 @@ import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; import static android.content.UriMatcher.NO_MATCH; -import static fr.free.nrw.commons.data.CategoryDao.Table.ALL_FIELDS; -import static fr.free.nrw.commons.data.CategoryDao.Table.COLUMN_ID; -import static fr.free.nrw.commons.data.CategoryDao.Table.TABLE_NAME; +import static fr.free.nrw.commons.category.CategoryDao.Table.ALL_FIELDS; +import static fr.free.nrw.commons.category.CategoryDao.Table.COLUMN_ID; +import static fr.free.nrw.commons.category.CategoryDao.Table.TABLE_NAME; public class CategoryContentProvider extends ContentProvider { diff --git a/app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java similarity index 97% rename from app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java rename to app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java index 0660fcaf1..2460c3409 100644 --- a/app/src/main/java/fr/free/nrw/commons/data/CategoryDao.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.data; +package fr.free.nrw.commons.category; import android.content.ContentProviderClient; import android.content.ContentValues; @@ -16,8 +16,6 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; -import fr.free.nrw.commons.category.CategoryContentProvider; - public class CategoryDao { private final Provider clientProvider; @@ -159,7 +157,7 @@ public class CategoryDao { onCreate(db); } - static void onUpdate(SQLiteDatabase db, int from, int to) { + public static void onUpdate(SQLiteDatabase db, int from, int to) { if (from == to) { return; } diff --git a/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java b/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java index c8d33e3da..35305c5ba 100644 --- a/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java +++ b/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java @@ -4,6 +4,7 @@ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import fr.free.nrw.commons.category.CategoryDao; import fr.free.nrw.commons.contributions.ContributionDao; import fr.free.nrw.commons.modifications.ModifierSequenceDao; diff --git a/app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java b/app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java similarity index 98% rename from app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java rename to app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java index b5bb53c0b..1cf0c338b 100644 --- a/app/src/test/java/fr/free/nrw/commons/data/CategoryDaoTest.java +++ b/app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.data; +package fr.free.nrw.commons.category; import android.content.ContentProviderClient; import android.content.ContentValues; @@ -27,8 +27,7 @@ import java.util.List; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.TestCommonsApplication; -import fr.free.nrw.commons.category.CategoryContentProvider; -import fr.free.nrw.commons.data.CategoryDao.Table; +import fr.free.nrw.commons.category.CategoryDao.Table; import static fr.free.nrw.commons.category.CategoryContentProvider.BASE_URI; import static fr.free.nrw.commons.category.CategoryContentProvider.uriForId; From 99278796804817b77d386a60445651532d0717e7 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Thu, 4 Jan 2018 22:11:36 -0600 Subject: [PATCH 3/5] Injected the ContributionDao where needed. --- .../fr/free/nrw/commons/auth/AccountUtil.java | 8 +++--- .../contributions/ContributionDao.java | 25 ++++++++++++----- .../contributions/ContributionsActivity.java | 14 +++++----- .../ContributionsContentProvider.java | 8 +++--- .../ContributionsListAdapter.java | 7 +++-- .../commons/di/CommonsApplicationModule.java | 9 ++++++- .../ModificationsSyncAdapter.java | 5 ++-- .../nrw/commons/upload/UploadService.java | 13 +++++---- .../contributions/ContributionDaoTest.java | 27 ++++++++++--------- 9 files changed, 70 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java b/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java index 4114b19a9..fa132130c 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java @@ -8,13 +8,13 @@ import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; -import fr.free.nrw.commons.contributions.ContributionsContentProvider; -import fr.free.nrw.commons.modifications.ModificationsContentProvider; import timber.log.Timber; import static android.accounts.AccountManager.ERROR_CODE_REMOTE_EXCEPTION; import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; +import static fr.free.nrw.commons.contributions.ContributionsContentProvider.CONTRIBUTION_AUTHORITY; +import static fr.free.nrw.commons.modifications.ModificationsContentProvider.AUTHORITY; public class AccountUtil { @@ -51,8 +51,8 @@ public class AccountUtil { } // FIXME: If the user turns it off, it shouldn't be auto turned back on - ContentResolver.setSyncAutomatically(account, ContributionsContentProvider.AUTHORITY, true); // Enable sync by default! - ContentResolver.setSyncAutomatically(account, ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(account, CONTRIBUTION_AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(account, AUTHORITY, true); // Enable sync by default! } private AccountManager accountManager() { diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java index ffaf3fc8d..e6f8dc789 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java @@ -11,40 +11,51 @@ import android.text.TextUtils; import java.util.Date; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + import fr.free.nrw.commons.settings.Prefs; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId; public class ContributionDao { - private final ContentProviderClient client; + private final Provider clientProvider; - public ContributionDao(ContentProviderClient client) { - this.client = client; + @Inject + public ContributionDao(@Named("contribution") Provider clientProvider) { + this.clientProvider = clientProvider; } public void save(Contribution contribution) { + ContentProviderClient db = clientProvider.get(); try { if (contribution.getContentUri() == null) { - contribution.setContentUri(client.insert(BASE_URI, toContentValues(contribution))); + contribution.setContentUri(db.insert(BASE_URI, toContentValues(contribution))); } else { - client.update(contribution.getContentUri(), toContentValues(contribution), null, null); + db.update(contribution.getContentUri(), toContentValues(contribution), null, null); } } catch (RemoteException e) { throw new RuntimeException(e); + } finally { + db.release(); } } public void delete(Contribution contribution) { + ContentProviderClient db = clientProvider.get(); try { if (contribution.getContentUri() == null) { // noooo throw new RuntimeException("tried to delete item with no content URI"); } else { - client.delete(contribution.getContentUri(), null, null); + db.delete(contribution.getContentUri(), null, null); } } catch (RemoteException e) { throw new RuntimeException(e); + } finally { + db.release(); } } @@ -74,7 +85,7 @@ public class ContributionDao { return cv; } - public static Contribution fromCursor(Cursor cursor) { + public Contribution fromCursor(Cursor cursor) { // Hardcoding column positions! //Check that cursor has a value to avoid CursorIndexOutOfBoundsException if (cursor.getCount() > 0) { diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java index 91e2ced35..c0fda159d 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java @@ -43,7 +43,6 @@ import timber.log.Timber; import static android.content.ContentResolver.requestSync; import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED; import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS; -import static fr.free.nrw.commons.contributions.ContributionsContentProvider.AUTHORITY; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING; @@ -58,6 +57,7 @@ public class ContributionsActivity @Inject MediaWikiApi mediaWikiApi; @Inject SessionManager sessionManager; @Inject @Named("default_preferences") SharedPreferences prefs; + @Inject ContributionDao contributionDao; private Cursor allContributions; private ContributionsListFragment contributionsList; @@ -121,7 +121,7 @@ public class ContributionsActivity @Override protected void onAuthCookieAcquired(String authCookie) { // Do a sync everytime we get here! - requestSync(sessionManager.getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle()); + requestSync(sessionManager.getCurrentAccount(), ContributionsContentProvider.CONTRIBUTION_AUTHORITY, new Bundle()); Intent uploadServiceIntent = new Intent(this, UploadService.class); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); startService(uploadServiceIntent); @@ -186,7 +186,7 @@ public class ContributionsActivity public void retryUpload(int i) { allContributions.moveToPosition(i); - Contribution c = ContributionDao.fromCursor(allContributions); + Contribution c = contributionDao.fromCursor(allContributions); if (c.getState() == STATE_FAILED) { uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c); Timber.d("Restarting for %s", c.toString()); @@ -197,10 +197,10 @@ public class ContributionsActivity public void deleteUpload(int i) { allContributions.moveToPosition(i); - Contribution c = ContributionDao.fromCursor(allContributions); + Contribution c = contributionDao.fromCursor(allContributions); if (c.getState() == STATE_FAILED) { Timber.d("Deleting failed contrib %s", c.toString()); - new ContributionDao(getContentResolver().acquireContentProviderClient(AUTHORITY)).delete(c); + contributionDao.delete(c); } else { Timber.d("Skipping deletion for non-failed contrib %s", c.toString()); } @@ -248,7 +248,7 @@ public class ContributionsActivity if (contributionsList.getAdapter() == null) { contributionsList.setAdapter(new ContributionsListAdapter(getApplicationContext(), - cursor, 0)); + cursor, 0, contributionDao)); } else { ((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor); } @@ -269,7 +269,7 @@ public class ContributionsActivity // not yet ready to return data return null; } else { - return ContributionDao.fromCursor((Cursor) contributionsList.getAdapter().getItem(i)); + return contributionDao.fromCursor((Cursor) contributionsList.getAdapter().getItem(i)); } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java index 402f91aaa..4d82bdfb1 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java @@ -26,13 +26,13 @@ public class ContributionsContentProvider extends ContentProvider { private static final int CONTRIBUTIONS_ID = 2; private static final String BASE_PATH = "contributions"; private static final UriMatcher uriMatcher = new UriMatcher(NO_MATCH); - public static final String AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider"; + public static final String CONTRIBUTION_AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider"; - public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); + public static final Uri BASE_URI = Uri.parse("content://" + CONTRIBUTION_AUTHORITY + "/" + BASE_PATH); static { - uriMatcher.addURI(AUTHORITY, BASE_PATH, CONTRIBUTIONS); - uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID); + uriMatcher.addURI(CONTRIBUTION_AUTHORITY, BASE_PATH, CONTRIBUTIONS); + uriMatcher.addURI(CONTRIBUTION_AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID); } public static Uri uriForId(int id) { diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java index 781b3c4c4..a31caf54f 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java @@ -11,8 +11,11 @@ import fr.free.nrw.commons.R; class ContributionsListAdapter extends CursorAdapter { - public ContributionsListAdapter(Context context, Cursor c, int flags) { + private final ContributionDao contributionDao; + + public ContributionsListAdapter(Context context, Cursor c, int flags, ContributionDao contributionDao) { super(context, c, flags); + this.contributionDao = contributionDao; } @Override @@ -26,7 +29,7 @@ class ContributionsListAdapter extends CursorAdapter { @Override public void bindView(View view, Context context, Cursor cursor) { final ContributionViewHolder views = (ContributionViewHolder)view.getTag(); - final Contribution contribution = ContributionDao.fromCursor(cursor); + final Contribution contribution = contributionDao.fromCursor(cursor); views.imageView.setMedia(contribution); views.titleView.setText(contribution.getDisplayTitle()); diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java index 67f1f8edd..7231bf28f 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java @@ -23,6 +23,7 @@ import fr.free.nrw.commons.nearby.NearbyPlaces; import fr.free.nrw.commons.upload.UploadController; import static android.content.Context.MODE_PRIVATE; +import static fr.free.nrw.commons.contributions.ContributionsContentProvider.CONTRIBUTION_AUTHORITY; @Module @SuppressWarnings({"WeakerAccess", "unused"}) @@ -42,10 +43,16 @@ public class CommonsApplicationModule { @Provides @Named("category") - public ContentProviderClient provideContentProviderClient() { + public ContentProviderClient provideCategoryContentProviderClient() { return application.getContentResolver().acquireContentProviderClient(CATEGORY_AUTHORITY); } + @Provides + @Named("contribution") + public ContentProviderClient provideContributionContentProviderClient() { + return application.getContentResolver().acquireContentProviderClient(CONTRIBUTION_AUTHORITY); + } + @Provides @Named("application_preferences") public SharedPreferences providesApplicationSharedPreferences() { diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java b/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java index d000a2ed5..7f6438d82 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java @@ -26,6 +26,7 @@ import timber.log.Timber; public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { @Inject MediaWikiApi mwApi; + @Inject ContributionDao contributionDao; public ModificationsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); @@ -80,7 +81,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { ContentProviderClient contributionsClient = null; try { - contributionsClient = getContext().getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY); + contributionsClient = getContext().getContentResolver().acquireContentProviderClient(ContributionsContentProvider.CONTRIBUTION_AUTHORITY); while (!allModifications.isAfterLast()) { ModifierSequence sequence = ModifierSequenceDao.fromCursor(allModifications); @@ -94,7 +95,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { throw new RuntimeException(e); } contributionCursor.moveToFirst(); - contrib = ContributionDao.fromCursor(contributionCursor); + contrib = contributionDao.fromCursor(contributionCursor); if (contrib.getState() == Contribution.STATE_COMPLETED) { String pageContent; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java index 023252b84..1e49680e2 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java @@ -52,6 +52,7 @@ public class UploadService extends HandlerService { @Inject MediaWikiApi mwApi; @Inject SessionManager sessionManager; @Inject @Named("default_preferences") SharedPreferences prefs; + @Inject ContributionDao contributionDao; private NotificationManager notificationManager; private ContentProviderClient contributionsProviderClient; @@ -67,7 +68,6 @@ public class UploadService extends HandlerService { public static final int NOTIFICATION_UPLOAD_IN_PROGRESS = 1; public static final int NOTIFICATION_UPLOAD_COMPLETE = 2; public static final int NOTIFICATION_UPLOAD_FAILED = 3; - private ContributionDao dao; public UploadService() { super("UploadService"); @@ -107,7 +107,7 @@ public class UploadService extends HandlerService { startForeground(NOTIFICATION_UPLOAD_IN_PROGRESS, curProgressNotification.build()); contribution.setTransferred(transferred); - dao.save(contribution); + contributionDao.save(contribution); } } @@ -124,8 +124,7 @@ public class UploadService extends HandlerService { super.onCreate(); notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - contributionsProviderClient = this.getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY); - dao = new ContributionDao(contributionsProviderClient); + contributionsProviderClient = this.getContentResolver().acquireContentProviderClient(ContributionsContentProvider.CONTRIBUTION_AUTHORITY); } @Override @@ -147,7 +146,7 @@ public class UploadService extends HandlerService { contribution.setState(Contribution.STATE_QUEUED); contribution.setTransferred(0); - dao.save(contribution); + contributionDao.save(contribution); toUpload++; if (curProgressNotification != null && toUpload != 1) { curProgressNotification.setContentText(getResources().getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload, toUpload)); @@ -262,7 +261,7 @@ public class UploadService extends HandlerService { contribution.setImageUrl(uploadResult.getImageUrl()); contribution.setState(Contribution.STATE_COMPLETED); contribution.setDateUploaded(uploadResult.getDateUploaded()); - dao.save(contribution); + contributionDao.save(contribution); } } catch (IOException e) { Timber.d("I have a network fuckup"); @@ -293,7 +292,7 @@ public class UploadService extends HandlerService { notificationManager.notify(NOTIFICATION_UPLOAD_FAILED, failureNotification); contribution.setState(Contribution.STATE_FAILED); - dao.save(contribution); + contributionDao.save(contribution); } private String findUniqueFilename(String fileName) throws IOException { diff --git a/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java b/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java index c7394003a..15e37e640 100644 --- a/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java +++ b/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java @@ -31,10 +31,13 @@ import static fr.free.nrw.commons.contributions.Contribution.SOURCE_CAMERA; import static fr.free.nrw.commons.contributions.Contribution.SOURCE_GALLERY; import static fr.free.nrw.commons.contributions.Contribution.STATE_COMPLETED; import static fr.free.nrw.commons.contributions.Contribution.STATE_QUEUED; -import static fr.free.nrw.commons.contributions.ContributionDao.*; +import static fr.free.nrw.commons.contributions.ContributionDao.Table; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; @@ -49,22 +52,22 @@ public class ContributionDaoTest { private static final String LOCAL_URI = "http://example.com/"; @Mock - ContentProviderClient client; + private ContentProviderClient client; @Mock - SQLiteDatabase database; + private SQLiteDatabase database; @Captor - ArgumentCaptor captor; + private ArgumentCaptor captor; private Uri contentUri; private ContributionDao testObject; @Before - public void setUp() throws Exception { + public void setUp() { MockitoAnnotations.initMocks(this); contentUri = uriForId(111); - testObject = new ContributionDao(client); + testObject = new ContributionDao(() -> client); } @Test @@ -288,7 +291,7 @@ public class ContributionDaoTest { long uploaded = 456L; MatrixCursor mc = createCursor(created, uploaded, false, LOCAL_URI); - Contribution c = ContributionDao.fromCursor(mc); + Contribution c = testObject.fromCursor(mc); assertEquals(uriForId(111), c.getContentUri()); assertEquals("file", c.getFilename()); @@ -312,7 +315,7 @@ public class ContributionDaoTest { public void createFromCursor_nullableTimestamps() { MatrixCursor mc = createCursor(0L, 0L, false, LOCAL_URI); - Contribution c = ContributionDao.fromCursor(mc); + Contribution c = testObject.fromCursor(mc); assertNull(c.getTimestamp()); assertNull(c.getDateCreated()); @@ -323,7 +326,7 @@ public class ContributionDaoTest { public void createFromCursor_nullableLocalUri() { MatrixCursor mc = createCursor(0L, 0L, false, ""); - Contribution c = ContributionDao.fromCursor(mc); + Contribution c = testObject.fromCursor(mc); assertNull(c.getLocalUri()); assertNull(c.getDateCreated()); @@ -333,10 +336,10 @@ public class ContributionDaoTest { @Test public void createFromCursor_booleanEncoding() { MatrixCursor mcFalse = createCursor(0L, 0L, false, LOCAL_URI); - assertFalse(ContributionDao.fromCursor(mcFalse).getMultiple()); + assertFalse(testObject.fromCursor(mcFalse).getMultiple()); MatrixCursor mcHammer = createCursor(0L, 0L, true, LOCAL_URI); - assertTrue(ContributionDao.fromCursor(mcHammer).getMultiple()); + assertTrue(testObject.fromCursor(mcHammer).getMultiple()); } @NonNull From 874627e3f5944e857992f7436856b474a7e927ec Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 5 Jan 2018 13:01:20 -0600 Subject: [PATCH 4/5] Injected the ModifierSequenceDao where needed. --- .../fr/free/nrw/commons/auth/AccountUtil.java | 4 +-- .../commons/di/CommonsApplicationModule.java | 7 ++++++ .../ModificationsContentProvider.java | 8 +++--- .../ModificationsSyncAdapter.java | 6 ++--- .../modifications/ModifierSequenceDao.java | 25 +++++++++++++------ .../commons/upload/MultipleShareActivity.java | 7 +++--- .../nrw/commons/upload/ShareActivity.java | 6 ++--- .../nrw/commons/upload/UploadService.java | 2 +- .../ModifierSequenceDaoTest.java | 16 ++++++------ 9 files changed, 49 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java b/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java index fa132130c..a020c1fb7 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AccountUtil.java @@ -14,7 +14,7 @@ import static android.accounts.AccountManager.ERROR_CODE_REMOTE_EXCEPTION; import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.CONTRIBUTION_AUTHORITY; -import static fr.free.nrw.commons.modifications.ModificationsContentProvider.AUTHORITY; +import static fr.free.nrw.commons.modifications.ModificationsContentProvider.MODIFICATIONS_AUTHORITY; public class AccountUtil { @@ -52,7 +52,7 @@ public class AccountUtil { // FIXME: If the user turns it off, it shouldn't be auto turned back on ContentResolver.setSyncAutomatically(account, CONTRIBUTION_AUTHORITY, true); // Enable sync by default! - ContentResolver.setSyncAutomatically(account, AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(account, MODIFICATIONS_AUTHORITY, true); // Enable sync by default! } private AccountManager accountManager() { diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java index 7231bf28f..913eef57e 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java @@ -24,6 +24,7 @@ import fr.free.nrw.commons.upload.UploadController; import static android.content.Context.MODE_PRIVATE; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.CONTRIBUTION_AUTHORITY; +import static fr.free.nrw.commons.modifications.ModificationsContentProvider.MODIFICATIONS_AUTHORITY; @Module @SuppressWarnings({"WeakerAccess", "unused"}) @@ -53,6 +54,12 @@ public class CommonsApplicationModule { return application.getContentResolver().acquireContentProviderClient(CONTRIBUTION_AUTHORITY); } + @Provides + @Named("modification") + public ContentProviderClient provideModificationContentProviderClient() { + return application.getContentResolver().acquireContentProviderClient(MODIFICATIONS_AUTHORITY); + } + @Provides @Named("application_preferences") public SharedPreferences providesApplicationSharedPreferences() { diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsContentProvider.java b/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsContentProvider.java index e1877e79c..3f2c01930 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsContentProvider.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsContentProvider.java @@ -23,15 +23,15 @@ public class ModificationsContentProvider extends ContentProvider { private static final int MODIFICATIONS = 1; private static final int MODIFICATIONS_ID = 2; - public static final String AUTHORITY = "fr.free.nrw.commons.modifications.contentprovider"; + public static final String MODIFICATIONS_AUTHORITY = "fr.free.nrw.commons.modifications.contentprovider"; public static final String BASE_PATH = "modifications"; - public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); + public static final Uri BASE_URI = Uri.parse("content://" + MODIFICATIONS_AUTHORITY + "/" + BASE_PATH); private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { - uriMatcher.addURI(AUTHORITY, BASE_PATH, MODIFICATIONS); - uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", MODIFICATIONS_ID); + uriMatcher.addURI(MODIFICATIONS_AUTHORITY, BASE_PATH, MODIFICATIONS); + uriMatcher.addURI(MODIFICATIONS_AUTHORITY, BASE_PATH + "/#", MODIFICATIONS_ID); } public static Uri uriForId(int id) { diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java b/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java index 7f6438d82..f81c273d2 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/ModificationsSyncAdapter.java @@ -27,6 +27,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { @Inject MediaWikiApi mwApi; @Inject ContributionDao contributionDao; + @Inject ModifierSequenceDao modifierSequenceDao; public ModificationsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); @@ -84,8 +85,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { contributionsClient = getContext().getContentResolver().acquireContentProviderClient(ContributionsContentProvider.CONTRIBUTION_AUTHORITY); while (!allModifications.isAfterLast()) { - ModifierSequence sequence = ModifierSequenceDao.fromCursor(allModifications); - ModifierSequenceDao dao = new ModifierSequenceDao(contributionsClient); + ModifierSequence sequence = modifierSequenceDao.fromCursor(allModifications); Contribution contrib; Cursor contributionCursor; @@ -123,7 +123,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { // FIXME: Log this somewhere else Timber.d("Non success result! %s", editResult); } else { - dao.delete(sequence); + modifierSequenceDao.delete(sequence); } } allModifications.moveToNext(); diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java b/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java index c98081c72..d6abbe276 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java @@ -11,15 +11,20 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + public class ModifierSequenceDao { - private final ContentProviderClient client; + private final Provider clientProvider; - public ModifierSequenceDao(ContentProviderClient client) { - this.client = client; + @Inject + public ModifierSequenceDao(@Named("modification") Provider clientProvider) { + this.clientProvider = clientProvider; } - public static ModifierSequence fromCursor(Cursor cursor) { + public ModifierSequence fromCursor(Cursor cursor) { // Hardcoding column positions! ModifierSequence ms = null; try { @@ -34,22 +39,28 @@ public class ModifierSequenceDao { } public void save(ModifierSequence sequence) { + ContentProviderClient db = clientProvider.get(); try { if (sequence.getContentUri() == null) { - sequence.setContentUri(client.insert(ModificationsContentProvider.BASE_URI, toContentValues(sequence))); + sequence.setContentUri(db.insert(ModificationsContentProvider.BASE_URI, toContentValues(sequence))); } else { - client.update(sequence.getContentUri(), toContentValues(sequence), null, null); + db.update(sequence.getContentUri(), toContentValues(sequence), null, null); } } catch (RemoteException e) { throw new RuntimeException(e); + } finally { + db.release(); } } public void delete(ModifierSequence sequence) { + ContentProviderClient db = clientProvider.get(); try { - client.delete(sequence.getContentUri(), null, null); + db.delete(sequence.getContentUri(), null, null); } catch (RemoteException e) { throw new RuntimeException(e); + } finally { + db.release(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java b/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java index 15acdcd4a..a41938cf7 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java @@ -2,7 +2,6 @@ package fr.free.nrw.commons.upload; import android.Manifest; import android.app.ProgressDialog; -import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -55,6 +54,7 @@ public class MultipleShareActivity extends AuthenticatedActivity @Inject MediaWikiApi mwApi; @Inject SessionManager sessionManager; @Inject UploadController uploadController; + @Inject ModifierSequenceDao modifierSequenceDao; @Inject @Named("default_preferences") SharedPreferences prefs; private ArrayList photosList = null; @@ -166,19 +166,18 @@ public class MultipleShareActivity extends AuthenticatedActivity @Override public void onCategoriesSave(List categories) { if (categories.size() > 0) { - ModifierSequenceDao dao = new ModifierSequenceDao(getContentResolver().acquireContentProviderClient(ModificationsContentProvider.AUTHORITY)); for (Contribution contribution : photosList) { ModifierSequence categoriesSequence = new ModifierSequence(contribution.getContentUri()); categoriesSequence.queueModifier(new CategoryModifier(categories.toArray(new String[]{}))); categoriesSequence.queueModifier(new TemplateRemoveModifier("Uncategorized")); - dao.save(categoriesSequence); + modifierSequenceDao.save(categoriesSequence); } } // FIXME: Make sure that the content provider is up // This is the wrong place for it, but bleh - better than not having it turned on by default for people who don't go throughl ogin - ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.MODIFICATIONS_AUTHORITY, true); // Enable sync by default! finish(); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java b/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java index 0992cbb31..2f0a4977e 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java @@ -76,6 +76,7 @@ public class ShareActivity @Inject CacheController cacheController; @Inject SessionManager sessionManager; @Inject UploadController uploadController; + @Inject ModifierSequenceDao modifierSequenceDao; @Inject @Named("default_preferences") SharedPreferences prefs; private String source; @@ -166,13 +167,12 @@ public class ShareActivity categoriesSequence.queueModifier(new CategoryModifier(categories.toArray(new String[]{}))); categoriesSequence.queueModifier(new TemplateRemoveModifier("Uncategorized")); - ModifierSequenceDao dao = new ModifierSequenceDao(getContentResolver().acquireContentProviderClient(ModificationsContentProvider.AUTHORITY)); - dao.save(categoriesSequence); + modifierSequenceDao.save(categoriesSequence); } // FIXME: Make sure that the content provider is up // This is the wrong place for it, but bleh - better than not having it turned on by default for people who don't go throughl ogin - ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.MODIFICATIONS_AUTHORITY, true); // Enable sync by default! finish(); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java index 1e49680e2..98f6d4889 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java @@ -273,7 +273,7 @@ public class UploadService extends HandlerService { toUpload--; if (toUpload == 0) { // Sync modifications right after all uplaods are processed - ContentResolver.requestSync(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle()); + ContentResolver.requestSync(sessionManager.getCurrentAccount(), ModificationsContentProvider.MODIFICATIONS_AUTHORITY, new Bundle()); stopForeground(true); } } diff --git a/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java b/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java index 888c758ff..ef290500d 100644 --- a/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java +++ b/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java @@ -52,14 +52,14 @@ public class ModifierSequenceDaoTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - testObject = new ModifierSequenceDao(client); + testObject = new ModifierSequenceDao(() -> client); } @Test public void createFromCursorWithEmptyModifiers() { MatrixCursor cursor = createCursor(""); - ModifierSequence seq = ModifierSequenceDao.fromCursor(cursor); + ModifierSequence seq = testObject.fromCursor(cursor); assertEquals(EXPECTED_MEDIA_URI, seq.getMediaUri().toString()); assertEquals(BASE_URI.buildUpon().appendPath("1").toString(), seq.getContentUri().toString()); @@ -70,7 +70,7 @@ public class ModifierSequenceDaoTest { public void createFromCursorWtihCategoryModifier() { MatrixCursor cursor = createCursor("{\"name\": \"CategoriesModifier\", \"data\": {}}"); - ModifierSequence seq = ModifierSequenceDao.fromCursor(cursor); + ModifierSequence seq = testObject.fromCursor(cursor); assertEquals(1, seq.getModifiers().size()); assertTrue(seq.getModifiers().get(0) instanceof CategoryModifier); @@ -80,7 +80,7 @@ public class ModifierSequenceDaoTest { public void createFromCursorWithRemoveModifier() { MatrixCursor cursor = createCursor("{\"name\": \"TemplateRemoverModifier\", \"data\": {}}"); - ModifierSequence seq = ModifierSequenceDao.fromCursor(cursor); + ModifierSequence seq = testObject.fromCursor(cursor); assertEquals(1, seq.getModifiers().size()); assertTrue(seq.getModifiers().get(0) instanceof TemplateRemoveModifier); @@ -89,7 +89,7 @@ public class ModifierSequenceDaoTest { @Test public void deleteSequence() throws Exception { when(client.delete(isA(Uri.class), isNull(String.class), isNull(String[].class))).thenReturn(1); - ModifierSequence seq = ModifierSequenceDao.fromCursor(createCursor("")); + ModifierSequence seq = testObject.fromCursor(createCursor("")); testObject.delete(seq); @@ -99,7 +99,7 @@ public class ModifierSequenceDaoTest { @Test(expected = RuntimeException.class) public void deleteTranslatesRemoteExceptions() throws Exception { when(client.delete(isA(Uri.class), isNull(String.class), isNull(String[].class))).thenThrow(new RemoteException("")); - ModifierSequence seq = ModifierSequenceDao.fromCursor(createCursor("")); + ModifierSequence seq = testObject.fromCursor(createCursor("")); testObject.delete(seq); } @@ -110,9 +110,9 @@ public class ModifierSequenceDaoTest { String expectedData = "{\"modifiers\":[" + modifierJson + "]}"; MatrixCursor cursor = createCursor(modifierJson); - testObject.save(ModifierSequenceDao.fromCursor(cursor)); + testObject.save(testObject.fromCursor(cursor)); - verify(client).update(eq(ModifierSequenceDao.fromCursor(cursor).getContentUri()), contentValuesCaptor.capture(), isNull(String.class), isNull(String[].class)); + verify(client).update(eq(testObject.fromCursor(cursor).getContentUri()), contentValuesCaptor.capture(), isNull(String.class), isNull(String[].class)); ContentValues cv = contentValuesCaptor.getValue(); assertEquals(2, cv.size()); assertEquals(EXPECTED_MEDIA_URI, cv.get(ModifierSequenceDao.Table.COLUMN_MEDIA_URI)); From 4bd72462e5c86674cf984025a475aeffa5b300d5 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 5 Jan 2018 19:53:51 -0600 Subject: [PATCH 5/5] More cleanup now that clean Dao classes are available from Dagger. --- .../nrw/commons/category/CategoryDao.java | 4 +-- .../contributions/ContributionDao.java | 28 ++++++++++++++++++- .../contributions/ContributionsActivity.java | 22 ++------------- .../ContributionsSyncAdapter.java | 3 +- .../modifications/ModifierSequenceDao.java | 28 +++++++++---------- .../nrw/commons/upload/UploadService.java | 4 --- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java index 2460c3409..e63b04c26 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java @@ -46,7 +46,7 @@ public class CategoryDao { * @param name Category's name * @return category from database, or null if not found */ - public @Nullable + @Nullable Category find(String name) { Cursor cursor = null; ContentProviderClient db = clientProvider.get(); @@ -77,7 +77,7 @@ public class CategoryDao { * * @return a list containing recent categories */ - public @NonNull + @NonNull List recentCategories(int limit) { List items = new ArrayList<>(); Cursor cursor = null; diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java index e6f8dc789..9d3038e03 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java @@ -17,10 +17,25 @@ import javax.inject.Provider; import fr.free.nrw.commons.settings.Prefs; +import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId; public class ContributionDao { + /* + This sorts in the following order: + Currently Uploading + Failed (Sorted in ascending order of time added - FIFO) + Queued to Upload (Sorted in ascending order of time added - FIFO) + Completed (Sorted in descending order of time added) + + This is why Contribution.STATE_COMPLETED is -1. + */ + static final String CONTRIBUTION_SORT = Table.COLUMN_STATE + " DESC, " + + Table.COLUMN_UPLOADED + " DESC , (" + + Table.COLUMN_TIMESTAMP + " * " + + Table.COLUMN_STATE + ")"; + private final Provider clientProvider; @Inject @@ -28,6 +43,17 @@ public class ContributionDao { this.clientProvider = clientProvider; } + Cursor loadAllContributions() { + ContentProviderClient db = clientProvider.get(); + try { + return db.query(BASE_URI, ALL_FIELDS, "", null, CONTRIBUTION_SORT); + } catch (RemoteException e) { + return null; + } finally { + db.release(); + } + } + public void save(Contribution contribution) { ContentProviderClient db = clientProvider.get(); try { @@ -59,7 +85,7 @@ public class ContributionDao { } } - public static ContentValues toContentValues(Contribution contribution) { + ContentValues toContentValues(Contribution contribution) { ContentValues cv = new ContentValues(); cv.put(Table.COLUMN_FILENAME, contribution.getFilename()); if (contribution.getLocalUri() != null) { diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java index c0fda159d..947a7b7a9 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java @@ -65,21 +65,6 @@ public class ContributionsActivity private UploadService uploadService; private boolean isUploadServiceConnected; private ArrayList observersWaitingForLoad = new ArrayList<>(); - private String CONTRIBUTION_SELECTION = ""; - - /* - This sorts in the following order: - Currently Uploading - Failed (Sorted in ascending order of time added - FIFO) - Queued to Upload (Sorted in ascending order of time added - FIFO) - Completed (Sorted in descending order of time added) - - This is why Contribution.STATE_COMPLETED is -1. - */ - private String CONTRIBUTION_SORT = ContributionDao.Table.COLUMN_STATE + " DESC, " - + ContributionDao.Table.COLUMN_UPLOADED + " DESC , (" - + ContributionDao.Table.COLUMN_TIMESTAMP + " * " - + ContributionDao.Table.COLUMN_STATE + ")"; private CompositeDisposable compositeDisposable = new CompositeDisposable(); @@ -127,8 +112,7 @@ public class ContributionsActivity startService(uploadServiceIntent); bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); - allContributions = getContentResolver().query(BASE_URI, ALL_FIELDS, - CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT); + allContributions = contributionDao.loadAllContributions(); getSupportLoaderManager().initLoader(0, null, this); } @@ -238,8 +222,8 @@ public class ContributionsActivity public Loader onCreateLoader(int i, Bundle bundle) { int uploads = prefs.getInt(UPLOADS_SHOWING, 100); return new CursorLoader(this, BASE_URI, - ALL_FIELDS, CONTRIBUTION_SELECTION, null, - CONTRIBUTION_SORT + "LIMIT " + uploads); + ALL_FIELDS, "", null, + ContributionDao.CONTRIBUTION_SORT + "LIMIT " + uploads); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java index 4be42b1e0..f8245032b 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java @@ -89,6 +89,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { LogEventResult result; Boolean done = false; String queryContinue = null; + ContributionDao contributionDao = new ContributionDao(() -> contentProviderClient); while (!done) { try { @@ -121,7 +122,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { "", -1, dateUpdated, dateUpdated, user, "", ""); contrib.setState(STATE_COMPLETED); - imageValues.add(ContributionDao.toContentValues(contrib)); + imageValues.add(contributionDao.toContentValues(contrib)); if (imageValues.size() % COMMIT_THRESHOLD == 0) { try { diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java b/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java index d6abbe276..e6b741d7a 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequenceDao.java @@ -24,20 +24,6 @@ public class ModifierSequenceDao { this.clientProvider = clientProvider; } - public ModifierSequence fromCursor(Cursor cursor) { - // Hardcoding column positions! - ModifierSequence ms = null; - try { - ms = new ModifierSequence(Uri.parse(cursor.getString(1)), - new JSONObject(cursor.getString(2))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - ms.setContentUri( ModificationsContentProvider.uriForId(cursor.getInt(0))); - - return ms; - } - public void save(ModifierSequence sequence) { ContentProviderClient db = clientProvider.get(); try { @@ -64,6 +50,20 @@ public class ModifierSequenceDao { } } + ModifierSequence fromCursor(Cursor cursor) { + // Hardcoding column positions! + ModifierSequence ms = null; + try { + ms = new ModifierSequence(Uri.parse(cursor.getString(1)), + new JSONObject(cursor.getString(2))); + } catch (JSONException e) { + throw new RuntimeException(e); + } + ms.setContentUri( ModificationsContentProvider.uriForId(cursor.getInt(0))); + + return ms; + } + private JSONObject toJSON(ModifierSequence sequence) { JSONObject data = new JSONObject(); try { diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java index 98f6d4889..1c8f9ac58 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; -import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; @@ -55,7 +54,6 @@ public class UploadService extends HandlerService { @Inject ContributionDao contributionDao; private NotificationManager notificationManager; - private ContentProviderClient contributionsProviderClient; private NotificationCompat.Builder curProgressNotification; private int toUpload; @@ -115,7 +113,6 @@ public class UploadService extends HandlerService { @Override public void onDestroy() { super.onDestroy(); - contributionsProviderClient.release(); Timber.d("UploadService.onDestroy; %s are yet to be uploaded", unfinishedUploads); } @@ -124,7 +121,6 @@ public class UploadService extends HandlerService { super.onCreate(); notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - contributionsProviderClient = this.getContentResolver().acquireContentProviderClient(ContributionsContentProvider.CONTRIBUTION_AUTHORITY); } @Override