From 04f676c3205454c69fd8c96c938eaa428923d451 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Thu, 24 Aug 2017 22:58:28 -0500 Subject: [PATCH 01/17] Added dagger2 to the build --- app/build.gradle | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 51d6f56b0..52d11cc5a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,11 +44,17 @@ dependencies { testCompile 'com.squareup.okhttp3:mockwebserver:3.8.1' androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.8.1' androidTestCompile "com.android.support:support-annotations:${project.supportLibVersion}" - androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' + androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.2'){ + exclude group: 'com.google.code.findbugs' + } debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1' + + compile 'com.google.dagger:dagger:2.11' + compile 'com.google.dagger:dagger-android-support:2.11' + annotationProcessor 'com.google.dagger:dagger-compiler:2.11' } android { From 8fe2816ca95273174a9691861118c8c9ae705ca2 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 00:57:17 -0500 Subject: [PATCH 02/17] First baby steps into the world of dependency injection using Dagger. --- app/build.gradle | 1 + .../free/nrw/commons/CommonsApplication.java | 47 +++++++++++++++---- .../free/nrw/commons/MediaDataExtractor.java | 15 +++--- .../nrw/commons/MediaThumbnailFetchTask.java | 7 +-- .../free/nrw/commons/MediaWikiImageView.java | 8 ++-- .../fr/free/nrw/commons/auth/AccountUtil.java | 24 ++++++---- .../commons/auth/AuthenticatedActivity.java | 19 ++++---- .../free/nrw/commons/auth/LoginActivity.java | 18 +++---- .../fr/free/nrw/commons/auth/LoginTask.java | 12 +++-- .../free/nrw/commons/auth/SignupActivity.java | 6 ++- .../auth/WikiAccountAuthenticator.java | 18 +++---- .../auth/WikiAccountAuthenticatorService.java | 13 +++-- .../category/CategoryContentProvider.java | 9 +++- .../contributions/ContributionsActivity.java | 13 +++-- .../ContributionsContentProvider.java | 18 ++++--- .../ContributionsSyncAdapter.java | 11 ++++- .../nrw/commons/di/ActivityBuilderModule.java | 45 ++++++++++++++++++ .../di/CommonsApplicationComponent.java | 35 ++++++++++++++ .../commons/di/CommonsApplicationModule.java | 29 ++++++++++++ .../di/ContentProviderBuilderModule.java | 24 ++++++++++ .../commons/media/MediaDetailFragment.java | 3 +- .../media/MediaDetailPagerFragment.java | 2 +- .../ModificationsContentProvider.java | 17 ++++--- .../ModificationsSyncAdapter.java | 7 ++- .../fr/free/nrw/commons/mwapi/EventLog.java | 9 ++-- .../fr/free/nrw/commons/mwapi/LogBuilder.java | 8 ++-- .../fr/free/nrw/commons/mwapi/LogTask.java | 11 +++-- .../nrw/commons/nearby/NearbyActivity.java | 17 ++++--- .../free/nrw/commons/theme/BaseActivity.java | 3 +- .../commons/upload/MultipleShareActivity.java | 6 +-- .../nrw/commons/upload/ShareActivity.java | 7 ++- .../nrw/commons/upload/UploadService.java | 4 +- 32 files changed, 351 insertions(+), 115 deletions(-) create mode 100644 app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java create mode 100644 app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java create mode 100644 app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java create mode 100644 app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java diff --git a/app/build.gradle b/app/build.gradle index 52d11cc5a..fe14d8c8a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,7 @@ dependencies { compile 'com.google.dagger:dagger:2.11' compile 'com.google.dagger:dagger-android-support:2.11' annotationProcessor 'com.google.dagger:dagger-compiler:2.11' + annotationProcessor 'com.google.dagger:dagger-android-processor:2.11' } android { 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 b7b75fae5..6b5f07caa 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -4,7 +4,9 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; +import android.app.Activity; import android.app.Application; +import android.content.ContentProvider; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -23,11 +25,21 @@ import org.acra.annotation.ReportsCrashes; import java.io.File; import java.io.IOException; +import javax.inject.Inject; + +import dagger.android.AndroidInjector; +import dagger.android.DaggerApplication; +import dagger.android.DispatchingAndroidInjector; +import dagger.android.HasActivityInjector; +import dagger.android.HasContentProviderInjector; import fr.free.nrw.commons.auth.AccountUtil; import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.data.DBOpenHelper; +import fr.free.nrw.commons.di.CommonsApplicationComponent; +import fr.free.nrw.commons.di.CommonsApplicationModule; +import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent; import fr.free.nrw.commons.modifications.ModifierSequence; import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi; @@ -44,7 +56,10 @@ import timber.log.Timber; resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, resDialogOkToast = R.string.crash_dialog_ok_toast ) -public class CommonsApplication extends Application { +public class CommonsApplication extends DaggerApplication { + + @Inject MediaWikiApi mediaWikiApi; + @Inject AccountUtil accountUtil; private Account currentAccount = null; // Unlike a savings account... public static final String API_URL = "https://commons.wikimedia.org/w/api.php"; @@ -70,6 +85,7 @@ public class CommonsApplication extends Application { private CacheController cacheData = null; private DBOpenHelper dbOpenHelper = null; private NearbyPlaces nearbyPlaces = null; + private CommonsApplicationComponent component; /** * This should not be called by ANY application code (other than the magic Android glue) @@ -121,6 +137,7 @@ public class CommonsApplication extends Application { @Override public void onCreate() { super.onCreate(); + if (LeakCanary.isInAnalyzerProcess(this)) { // This process is dedicated to LeakCanary for heap analysis. // You should not init your app in this process. @@ -130,8 +147,6 @@ public class CommonsApplication extends Application { Timber.plant(new Timber.DebugTree()); - - if (!BuildConfig.DEBUG) { ACRA.init(this); } else { @@ -147,13 +162,27 @@ public class CommonsApplication extends Application { cacheData = new CacheController(); } + @Override + protected AndroidInjector applicationInjector() { + return injector(); + } + + public CommonsApplicationComponent injector() { + if (component == null) { + component = DaggerCommonsApplicationComponent.builder() + .appModule(new CommonsApplicationModule(this)) + .build(); + } + return component; + } + /** * @return Account|null */ public Account getCurrentAccount() { if(currentAccount == null) { AccountManager accountManager = AccountManager.get(this); - Account[] allAccounts = accountManager.getAccountsByType(AccountUtil.accountType()); + Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); if(allAccounts.length != 0) { currentAccount = allAccounts[0]; } @@ -169,10 +198,10 @@ public class CommonsApplication extends Application { return false; // This should never happen } - accountManager.invalidateAuthToken(AccountUtil.accountType(), getMWApi().getAuthCookie()); + accountManager.invalidateAuthToken(accountUtil.accountType(), mediaWikiApi.getAuthCookie()); try { String authCookie = accountManager.blockingGetAuthToken(curAccount, "", false); - getMWApi().setAuthCookie(authCookie); + mediaWikiApi.setAuthCookie(authCookie); return true; } catch (OperationCanceledException | NullPointerException | IOException | AuthenticatorException e) { e.printStackTrace(); @@ -199,13 +228,13 @@ public class CommonsApplication extends Application { } AccountManager accountManager = AccountManager.get(this); - Account[] allAccounts = accountManager.getAccountsByType(AccountUtil.accountType()); + Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); for (Account allAccount : allAccounts) { accountManager.removeAccount(allAccount, null, null); } //TODO: fix preference manager - PreferenceManager.getDefaultSharedPreferences(getInstance()).edit().clear().commit(); + PreferenceManager.getDefaultSharedPreferences(this).edit().clear().commit(); SharedPreferences preferences = context .getSharedPreferences("fr.free.nrw.commons", MODE_PRIVATE); preferences.edit().clear().commit(); @@ -219,7 +248,7 @@ public class CommonsApplication extends Application { * Deletes all tables and re-creates them. */ public void updateAllDatabases() { - DBOpenHelper dbOpenHelper = CommonsApplication.getInstance().getDBOpenHelper(); + DBOpenHelper dbOpenHelper = getDBOpenHelper(); dbOpenHelper.getReadableDatabase().close(); SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); diff --git a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java index 5ec80f0d3..68ba02297 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java @@ -2,7 +2,6 @@ package fr.free.nrw.commons; import android.support.annotation.Nullable; -import org.mediawiki.api.ApiResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -34,6 +33,7 @@ import timber.log.Timber; * which are not intrinsic to the media and may change due to editing. */ public class MediaDataExtractor { + private final MediaWikiApi mediaWikiApi; private boolean fetched; private String filename; @@ -45,14 +45,16 @@ public class MediaDataExtractor { private LicenseList licenseList; /** + * @param mwApi instance of MediaWikiApi * @param filename of the target media object, should include 'File:' prefix */ - public MediaDataExtractor(String filename, LicenseList licenseList) { + public MediaDataExtractor(String filename, LicenseList licenseList, MediaWikiApi mwApi) { this.filename = filename; - categories = new ArrayList<>(); - descriptions = new HashMap<>(); - fetched = false; + this.categories = new ArrayList<>(); + this.descriptions = new HashMap<>(); + this.fetched = false; this.licenseList = licenseList; + this.mediaWikiApi = mwApi; } /** @@ -66,8 +68,7 @@ public class MediaDataExtractor { throw new IllegalStateException("Tried to call MediaDataExtractor.fetch() again."); } - MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); - MediaResult result = api.fetchMediaByFilename(filename); + MediaResult result = mediaWikiApi.fetchMediaByFilename(filename); // In-page category links are extracted from source, as XML doesn't cover [[links]] extractCategories(result.getWikiSource()); diff --git a/app/src/main/java/fr/free/nrw/commons/MediaThumbnailFetchTask.java b/app/src/main/java/fr/free/nrw/commons/MediaThumbnailFetchTask.java index 5ccc80c06..a542cb363 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaThumbnailFetchTask.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaThumbnailFetchTask.java @@ -7,16 +7,17 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi; class MediaThumbnailFetchTask extends AsyncTask { protected final Media media; + private MediaWikiApi mediaWikiApi; - public MediaThumbnailFetchTask(@NonNull Media media) { + public MediaThumbnailFetchTask(@NonNull Media media, MediaWikiApi mwApi) { this.media = media; + this.mediaWikiApi = mwApi; } @Override protected String doInBackground(String... params) { try { - MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); - return api.findThumbnailByFilename(params[0]); + return mediaWikiApi.findThumbnailByFilename(params[0]); } catch (Exception e) { // Do something better! } diff --git a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java index 3e147f4a8..fbf475a57 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java @@ -11,6 +11,7 @@ import android.widget.Toast; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.view.SimpleDraweeView; +import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; public class MediaWikiImageView extends SimpleDraweeView { @@ -43,7 +44,8 @@ public class MediaWikiImageView extends SimpleDraweeView { setImageUrl(CommonsApplication.getInstance().getThumbnailUrlCache().get(media.getFilename())); } else { setImageUrl(null); - currentThumbnailTask = new ThumbnailFetchTask(media); + MediaWikiApi mediaWikiApi = CommonsApplication.getInstance().getMWApi(); + currentThumbnailTask = new ThumbnailFetchTask(media, mediaWikiApi); currentThumbnailTask.execute(media.getFilename()); } } @@ -71,8 +73,8 @@ public class MediaWikiImageView extends SimpleDraweeView { } private class ThumbnailFetchTask extends MediaThumbnailFetchTask { - ThumbnailFetchTask(@NonNull Media media) { - super(media); + ThumbnailFetchTask(@NonNull Media media, @NonNull MediaWikiApi mwApi) { + super(media, mwApi); } @Override 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 479b47444..557746f9b 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,6 +8,8 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import javax.inject.Inject; + import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.contributions.ContributionsContentProvider; import fr.free.nrw.commons.modifications.ModificationsContentProvider; @@ -15,8 +17,15 @@ import timber.log.Timber; public class AccountUtil { - public static void createAccount(@Nullable AccountAuthenticatorResponse response, - String username, String password) { + private final CommonsApplication application; + + @Inject + public AccountUtil(CommonsApplication application) { + this.application = application; + } + + public void createAccount(@Nullable AccountAuthenticatorResponse response, + String username, String password) { Account account = new Account(username, accountType()); boolean created = accountManager().addAccountExplicitly(account, password, null); @@ -46,17 +55,12 @@ public class AccountUtil { } @NonNull - public static String accountType() { + public String accountType() { return "fr.free.nrw.commons"; } - private static AccountManager accountManager() { - return AccountManager.get(app()); - } - - @NonNull - private static CommonsApplication app() { - return CommonsApplication.getInstance(); + private AccountManager accountManager() { + return AccountManager.get(application); } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index 0db56e66b..e17380578 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -5,6 +5,9 @@ import android.accounts.AccountManager; import android.accounts.AccountManagerFuture; import android.os.Bundle; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.theme.NavigationBaseActivity; import io.reactivex.Single; @@ -14,27 +17,23 @@ import timber.log.Timber; public abstract class AuthenticatedActivity extends NavigationBaseActivity { - String accountType; - CommonsApplication app; + @Inject CommonsApplication app; + @Inject AccountUtil accountUtil; private String authCookie; - public AuthenticatedActivity() { - this.accountType = AccountUtil.accountType(); - } - private void getAuthCookie(Account account, AccountManager accountManager) { Single.fromCallable(() -> accountManager.blockingGetAuthToken(account, "", false)) .subscribeOn(Schedulers.io()) .doOnError(Timber::e) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - cookie -> onAuthCookieAcquired(cookie), + this::onAuthCookieAcquired, throwable -> onAuthFailure()); } private void addAccount(AccountManager accountManager) { - Single.just(accountManager.addAccount(accountType, null, null, null, AuthenticatedActivity.this, null, null)) + Single.just(accountManager.addAccount(accountUtil.accountType(), null, null, null, AuthenticatedActivity.this, null, null)) .subscribeOn(Schedulers.io()) .map(AccountManagerFuture::getResult) .doOnEvent((bundle, throwable) -> { @@ -47,7 +46,7 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { .doOnError(Timber::e) .observeOn(AndroidSchedulers.mainThread()) .subscribe(s -> { - Account[] allAccounts = accountManager.getAccountsByType(accountType); + Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); Account curAccount = allAccounts[0]; getAuthCookie(curAccount, accountManager); }, @@ -71,7 +70,7 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - app = CommonsApplication.getInstance(); + if(savedInstanceState != null) { authCookie = savedInstanceState.getString("authCookie"); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index aca419b9c..cd83ca8f7 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -8,15 +8,16 @@ import android.os.Bundle; import android.support.v4.app.NavUtils; import android.text.Editable; import android.text.TextWatcher; -import android.view.KeyEvent; import android.view.MenuItem; import android.view.View; -import android.view.inputmethod.EditorInfo; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; @@ -34,6 +35,9 @@ public class LoginActivity extends AccountAuthenticatorActivity { public static final String PARAM_USERNAME = "fr.free.nrw.commons.login.username"; + @Inject CommonsApplication application; + @Inject AccountUtil accountUtil; + private SharedPreferences prefs = null; private Button loginButton; @@ -43,14 +47,11 @@ public class LoginActivity extends AccountAuthenticatorActivity { ProgressDialog progressDialog; private LoginTextWatcher textWatcher = new LoginTextWatcher(); - private CommonsApplication app; - @Override public void onCreate(Bundle savedInstanceState) { + AndroidInjection.inject(this); super.onCreate(savedInstanceState); - app = CommonsApplication.getInstance(); - setContentView(R.layout.activity_login); loginButton = (Button) findViewById(R.id.loginButton); @@ -111,7 +112,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { WelcomeActivity.startYourself(this); prefs.edit().putBoolean("firstrun", false).apply(); } - if (app.getCurrentAccount() != null) { + if (application.getCurrentAccount() != null) { startMainActivity(); } } @@ -143,7 +144,8 @@ public class LoginActivity extends AccountAuthenticatorActivity { this, canonicializeUsername(usernameEdit.getText().toString()), passwordEdit.getText().toString(), - twoFactorEdit.getText().toString() + twoFactorEdit.getText().toString(), + accountUtil, application ); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java index dd4f1c4e7..49e2f93b8 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java @@ -19,14 +19,16 @@ class LoginTask extends AsyncTask { private String username; private String password; private String twoFactorCode = ""; + private AccountUtil accountUtil; private CommonsApplication app; - public LoginTask(LoginActivity loginActivity, String username, String password, String twoFactorCode) { + public LoginTask(LoginActivity loginActivity, String username, String password, String twoFactorCode, AccountUtil accountUtil, CommonsApplication application) { this.loginActivity = loginActivity; this.username = username; this.password = password; this.twoFactorCode = twoFactorCode; - app = CommonsApplication.getInstance(); + this.accountUtil = accountUtil; + this.app = application; } @Override @@ -59,7 +61,7 @@ class LoginTask extends AsyncTask { super.onPostExecute(result); Timber.d("Login done!"); - EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, app) .param("username", username) .param("result", result) .log(); @@ -83,12 +85,12 @@ class LoginTask extends AsyncTask { if (response != null) { Bundle authResult = new Bundle(); authResult.putString(AccountManager.KEY_ACCOUNT_NAME, username); - authResult.putString(AccountManager.KEY_ACCOUNT_TYPE, AccountUtil.accountType()); + authResult.putString(AccountManager.KEY_ACCOUNT_TYPE, accountUtil.accountType()); response.onResult(authResult); } } - AccountUtil.createAccount(response, username, password); + accountUtil.createAccount(response, username, password); loginActivity.startMainActivity(); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java index db810fa84..9a27a116c 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java @@ -6,12 +6,16 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.theme.BaseActivity; import timber.log.Timber; public class SignupActivity extends BaseActivity { + @Inject CommonsApplication application; private WebView webView; @Override @@ -38,7 +42,7 @@ public class SignupActivity extends BaseActivity { Timber.d("Overriding URL %s", url); Toast toast = Toast.makeText( - CommonsApplication.getInstance(), + application, "Account created!", Toast.LENGTH_LONG ); diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java index 8ecfc67cb..79f48d375 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java @@ -13,16 +13,19 @@ import android.support.annotation.Nullable; import java.io.IOException; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.mwapi.MediaWikiApi; public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { - private Context context; + private final Context context; + private final AccountUtil accountUtil; + private MediaWikiApi mediaWikiApi; - public WikiAccountAuthenticator(Context context) { + public WikiAccountAuthenticator(Context context, AccountUtil accountUtil, MediaWikiApi mwApi) { super(context); this.context = context; + this.accountUtil = accountUtil; + this.mediaWikiApi = mwApi; } private Bundle unsupportedOperation() { @@ -36,7 +39,7 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { } private boolean supportedAccountType(@Nullable String type) { - return AccountUtil.accountType().equals(type); + return accountUtil.accountType().equals(type); } @Override @@ -75,11 +78,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { } private String getAuthCookie(String username, String password) throws IOException { - MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); //TODO add 2fa support here - String result = api.login(username, password); + String result = mediaWikiApi.login(username, password); if(result.equals("PASS")) { - return api.getAuthCookie(); + return mediaWikiApi.getAuthCookie(); } else { return null; } @@ -102,7 +104,7 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { if (authCookie != null) { final Bundle result = new Bundle(); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); - result.putString(AccountManager.KEY_ACCOUNT_TYPE, AccountUtil.accountType()); + result.putString(AccountManager.KEY_ACCOUNT_TYPE, accountUtil.accountType()); result.putString(AccountManager.KEY_AUTHTOKEN, authCookie); return result; } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java index 0a996b7d4..2d1dc20fc 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java @@ -5,18 +5,25 @@ import android.app.Service; import android.content.Intent; import android.os.IBinder; +import javax.inject.Inject; + +import fr.free.nrw.commons.CommonsApplication; + public class WikiAccountAuthenticatorService extends Service { - private static WikiAccountAuthenticator wikiAccountAuthenticator = null; - + @Inject CommonsApplication application; + @Inject AccountUtil accountUtil; + private WikiAccountAuthenticator wikiAccountAuthenticator = null; + @Override public IBinder onBind(Intent intent) { if (!intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) { return null; } + ((CommonsApplication)getApplication()).injector().inject(this); if (wikiAccountAuthenticator == null) { - wikiAccountAuthenticator = new WikiAccountAuthenticator(this); + wikiAccountAuthenticator = new WikiAccountAuthenticator(this, accountUtil, application.getMWApi()); } return wikiAccountAuthenticator.getIBinder(); } 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 e75f1adcf..9d493b30c 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 @@ -10,6 +10,9 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.text.TextUtils; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.data.DBOpenHelper; @@ -36,10 +39,14 @@ public class CategoryContentProvider extends ContentProvider { return Uri.parse(BASE_URI.toString() + "/" + id); } + @Inject CommonsApplication application; + private DBOpenHelper dbOpenHelper; + @Override public boolean onCreate() { - dbOpenHelper = CommonsApplication.getInstance().getDBOpenHelper(); + AndroidInjection.inject(this); + dbOpenHelper = application.getDBOpenHelper(); return false; } 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 fa1d2d96f..f4a70410a 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 @@ -24,13 +24,17 @@ import android.widget.AdapterView; import java.util.ArrayList; +import javax.inject.Inject; + import butterknife.ButterKnife; +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.auth.AuthenticatedActivity; import fr.free.nrw.commons.media.MediaDetailPagerFragment; +import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.settings.Prefs; import fr.free.nrw.commons.upload.UploadService; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -46,6 +50,9 @@ public class ContributionsActivity FragmentManager.OnBackStackChangedListener, ContributionsListFragment.SourceRefresher { + @Inject CommonsApplication application; + @Inject MediaWikiApi mediaWikiApi; + private Cursor allContributions; private ContributionsListFragment contributionsList; private MediaDetailPagerFragment mediaDetails; @@ -108,7 +115,7 @@ public class ContributionsActivity @Override protected void onAuthCookieAcquired(String authCookie) { // Do a sync everytime we get here! - ContentResolver.requestSync(CommonsApplication.getInstance().getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle()); + ContentResolver.requestSync(application.getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle()); Intent uploadServiceIntent = new Intent(this, UploadService.class); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); startService(uploadServiceIntent); @@ -263,10 +270,8 @@ public class ContributionsActivity } private void setUploadCount() { - CommonsApplication application = CommonsApplication.getInstance(); - compositeDisposable.add( - CommonsApplication.getInstance().getMWApi() + mediaWikiApi .getUploadCount(application.getCurrentAccount().name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) 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 6e84065f2..59603f898 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 @@ -10,6 +10,9 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.text.TextUtils; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import timber.log.Timber; @@ -33,9 +36,12 @@ public class ContributionsContentProvider extends ContentProvider{ return Uri.parse(BASE_URI.toString() + "/" + id); } + @Inject CommonsApplication application; + @Override public boolean onCreate() { - return false; + AndroidInjection.inject(this); + return true; } @Override @@ -45,7 +51,7 @@ public class ContributionsContentProvider extends ContentProvider{ int uriType = uriMatcher.match(uri); - SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase(); + SQLiteDatabase db = application.getDBOpenHelper().getReadableDatabase(); Cursor cursor; switch(uriType) { @@ -79,7 +85,7 @@ public class ContributionsContentProvider extends ContentProvider{ @Override public Uri insert(@NonNull Uri uri, ContentValues contentValues) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); long id = 0; switch (uriType) { case CONTRIBUTIONS: @@ -97,7 +103,7 @@ public class ContributionsContentProvider extends ContentProvider{ int rows = 0; int uriType = uriMatcher.match(uri); - SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase(); + SQLiteDatabase db = application.getDBOpenHelper().getReadableDatabase(); switch(uriType) { case CONTRIBUTIONS_ID: @@ -118,7 +124,7 @@ public class ContributionsContentProvider extends ContentProvider{ public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { Timber.d("Hello, bulk insert! (ContributionsContentProvider)"); int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); sqlDB.beginTransaction(); switch (uriType) { case CONTRIBUTIONS: @@ -146,7 +152,7 @@ public class ContributionsContentProvider extends ContentProvider{ In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. */ int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); int rowsUpdated = 0; switch (uriType) { case CONTRIBUTIONS: 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 6d769e94c..e9e20c9f2 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 @@ -17,6 +17,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import javax.inject.Inject; + import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.mwapi.LogEventResult; @@ -25,6 +27,9 @@ import timber.log.Timber; public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { private static int COMMIT_THRESHOLD = 10; + + @Inject CommonsApplication application; + public ContributionsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); } @@ -59,10 +64,12 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { @Override public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) { + ((CommonsApplication)getContext().getApplicationContext()).injector().inject(this); + // This code is fraught with possibilities of race conditions, but lalalalala I can't hear you! String user = account.name; - MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); - SharedPreferences prefs = this.getContext().getSharedPreferences("prefs", Context.MODE_PRIVATE); + MediaWikiApi api = application.getMWApi(); + SharedPreferences prefs = getContext().getSharedPreferences("prefs", Context.MODE_PRIVATE); String lastModified = prefs.getString("lastSyncTimestamp", ""); Date curTime = new Date(); LogEventResult result; diff --git a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java new file mode 100644 index 000000000..28acf341b --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java @@ -0,0 +1,45 @@ +package fr.free.nrw.commons.di; + +import dagger.Module; +import dagger.android.ContributesAndroidInjector; +import fr.free.nrw.commons.AboutActivity; +import fr.free.nrw.commons.WelcomeActivity; +import fr.free.nrw.commons.auth.LoginActivity; +import fr.free.nrw.commons.auth.SignupActivity; +import fr.free.nrw.commons.contributions.ContributionsActivity; +import fr.free.nrw.commons.nearby.NearbyActivity; +import fr.free.nrw.commons.settings.SettingsActivity; +import fr.free.nrw.commons.upload.MultipleShareActivity; +import fr.free.nrw.commons.upload.ShareActivity; + +@Module +public abstract class ActivityBuilderModule { + + @ContributesAndroidInjector + abstract ContributionsActivity bindContributionsActivity(); + + @ContributesAndroidInjector + abstract MultipleShareActivity bindMultipleShareActivity(); + + @ContributesAndroidInjector + abstract ShareActivity bindShareActivity(); + + @ContributesAndroidInjector + abstract LoginActivity bindLoginActivity(); + + @ContributesAndroidInjector + abstract SignupActivity bindSignupActivity(); + + @ContributesAndroidInjector + abstract NearbyActivity bindNearbyActivity(); + + @ContributesAndroidInjector + abstract AboutActivity bindAboutActivity(); + + @ContributesAndroidInjector + abstract SettingsActivity bindSettingsActivity(); + + @ContributesAndroidInjector + abstract WelcomeActivity bindWelcomeActivity(); + +} diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java new file mode 100644 index 000000000..84d510faa --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -0,0 +1,35 @@ +package fr.free.nrw.commons.di; + +import javax.inject.Singleton; + +import dagger.Component; +import dagger.android.AndroidInjectionModule; +import dagger.android.AndroidInjector; +import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; +import fr.free.nrw.commons.contributions.ContributionsSyncAdapter; +import fr.free.nrw.commons.modifications.ModificationsSyncAdapter; + +@Singleton +@Component(modules = { + CommonsApplicationModule.class, + AndroidInjectionModule.class, + ActivityBuilderModule.class, + ContentProviderBuilderModule.class +}) +public interface CommonsApplicationComponent extends AndroidInjector { + void inject(CommonsApplication application); + + void inject(WikiAccountAuthenticatorService service); + + void inject(ContributionsSyncAdapter syncAdapter); + + void inject(ModificationsSyncAdapter syncAdapter); + + @Component.Builder + interface Builder { + Builder appModule(CommonsApplicationModule applicationModule); + + CommonsApplicationComponent build(); + } +} 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 new file mode 100644 index 000000000..9af4e3853 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java @@ -0,0 +1,29 @@ +package fr.free.nrw.commons.di; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; +import fr.free.nrw.commons.mwapi.MediaWikiApi; + +@Module +public class CommonsApplicationModule { + private CommonsApplication application; + + public CommonsApplicationModule(CommonsApplication application) { + this.application = application; + } + + @Provides + public CommonsApplication providesCommonsApplication() { + return application; + } + + @Provides + @Singleton + public MediaWikiApi provideMediaWikiApi() { + return new ApacheHttpClientMediaWikiApi(CommonsApplication.API_URL); + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java new file mode 100644 index 000000000..9d5e91f65 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java @@ -0,0 +1,24 @@ +package fr.free.nrw.commons.di; + +import dagger.Module; +import dagger.android.ContributesAndroidInjector; +import fr.free.nrw.commons.auth.LoginActivity; +import fr.free.nrw.commons.auth.SignupActivity; +import fr.free.nrw.commons.category.CategoryContentProvider; +import fr.free.nrw.commons.contributions.ContributionsActivity; +import fr.free.nrw.commons.contributions.ContributionsContentProvider; +import fr.free.nrw.commons.modifications.ModificationsContentProvider; + +@Module +public abstract class ContentProviderBuilderModule { + + @ContributesAndroidInjector + abstract CategoryContentProvider bindCategoryContentProvider(); + + @ContributesAndroidInjector + abstract ContributionsContentProvider bindContributionsContentProvider(); + + @ContributesAndroidInjector + abstract ModificationsContentProvider bindModificationsContentProvider(); + +} diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index f2461fcf0..d062bd5da 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.Locale; +import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.License; import fr.free.nrw.commons.LicenseList; import fr.free.nrw.commons.Media; @@ -188,7 +189,7 @@ public class MediaDetailFragment extends Fragment { @Override protected void onPreExecute() { - extractor = new MediaDataExtractor(media.getFilename(), licenseList); + extractor = new MediaDataExtractor(media.getFilename(), licenseList, CommonsApplication.getInstance().getMWApi()); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index 271ac5c92..3e63b2006 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -131,7 +131,7 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa switch(item.getItemId()) { case R.id.menu_share_current_image: // Share - this is just logs it, intent set in onCreateOptionsMenu, around line 252 - EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("filename", m.getFilename()) .log(); 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 11caa94fa..8b8d965e3 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 @@ -10,6 +10,9 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.text.TextUtils; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import timber.log.Timber; @@ -33,10 +36,12 @@ public class ModificationsContentProvider extends ContentProvider{ return Uri.parse(BASE_URI.toString() + "/" + id); } + @Inject CommonsApplication application; @Override public boolean onCreate() { - return false; + AndroidInjection.inject(this); + return true; } @Override @@ -53,7 +58,7 @@ public class ModificationsContentProvider extends ContentProvider{ throw new IllegalArgumentException("Unknown URI" + uri); } - SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase(); + SQLiteDatabase db = application.getDBOpenHelper().getReadableDatabase(); Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); @@ -69,7 +74,7 @@ public class ModificationsContentProvider extends ContentProvider{ @Override public Uri insert(@NonNull Uri uri, ContentValues contentValues) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); long id = 0; switch (uriType) { case MODIFICATIONS: @@ -85,7 +90,7 @@ public class ModificationsContentProvider extends ContentProvider{ @Override public int delete(@NonNull Uri uri, String s, String[] strings) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); switch (uriType) { case MODIFICATIONS_ID: String id = uri.getLastPathSegment(); @@ -103,7 +108,7 @@ public class ModificationsContentProvider extends ContentProvider{ public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { Timber.d("Hello, bulk insert! (ModificationsContentProvider)"); int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); sqlDB.beginTransaction(); switch (uriType) { case MODIFICATIONS: @@ -131,7 +136,7 @@ public class ModificationsContentProvider extends ContentProvider{ In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. */ int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); int rowsUpdated = 0; switch (uriType) { case MODIFICATIONS: 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 f2940ec74..d6ba9bbf7 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 @@ -14,6 +14,8 @@ import android.os.RemoteException; import java.io.IOException; +import javax.inject.Inject; + import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.contributions.Contribution; @@ -23,6 +25,8 @@ import timber.log.Timber; public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { + @Inject CommonsApplication application; + public ModificationsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); } @@ -30,6 +34,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { @Override public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) { // This code is fraught with possibilities of race conditions, but lalalalala I can't hear you! + ((CommonsApplication)getContext().getApplicationContext()).injector().inject(this); Cursor allModifications; try { @@ -59,7 +64,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { return; } - MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); + MediaWikiApi api = application.getMWApi(); api.setAuthCookie(authCookie); String editToken; diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java b/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java index d3ba7c0d5..415d947c6 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java @@ -2,6 +2,7 @@ package fr.free.nrw.commons.mwapi; import android.os.Build; +import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Utils; public class EventLog { @@ -15,14 +16,14 @@ public class EventLog { } } - private static LogBuilder schema(String schema, long revision) { - return new LogBuilder(schema, revision); + private static LogBuilder schema(String schema, long revision, CommonsApplication application) { + return new LogBuilder(schema, revision, application); } - public static LogBuilder schema(Object[] scid) { + public static LogBuilder schema(Object[] scid, CommonsApplication application) { if (scid.length != 2) { throw new IllegalArgumentException("Needs an object array with schema as first param and revision as second"); } - return schema((String) scid[0], (Long) scid[1]); + return schema((String) scid[0], (Long) scid[1], application); } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java b/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java index b512f9647..d391e12db 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java @@ -17,14 +17,16 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.settings.Prefs; public class LogBuilder { + private final CommonsApplication application; private JSONObject data; private long rev; private String schema; - LogBuilder(String schema, long revision) { + LogBuilder(String schema, long revision, CommonsApplication application) { data = new JSONObject(); this.schema = schema; this.rev = revision; + this.application = application; } public LogBuilder param(String key, Object value) { @@ -56,11 +58,11 @@ public class LogBuilder { // Use *only* for tracking the user preference change for EventLogging // Attempting to use anywhere else will cause kitten explosions public void log(boolean force) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(CommonsApplication.getInstance()); + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(application); if (!settings.getBoolean(Prefs.TRACKING_ENABLED, true) && !force) { return; // User has disabled tracking } - LogTask logTask = new LogTask(); + LogTask logTask = new LogTask(application.getMWApi()); logTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, this); } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/LogTask.java b/app/src/main/java/fr/free/nrw/commons/mwapi/LogTask.java index ee947afbc..3fce8aaf1 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/LogTask.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/LogTask.java @@ -2,11 +2,16 @@ package fr.free.nrw.commons.mwapi; import android.os.AsyncTask; -import fr.free.nrw.commons.CommonsApplication; - class LogTask extends AsyncTask { + + private final MediaWikiApi mwApi; + + public LogTask(MediaWikiApi mwApi) { + this.mwApi = mwApi; + } + @Override protected Boolean doInBackground(LogBuilder... logBuilders) { - return CommonsApplication.getInstance().getMWApi().logEvents(logBuilders); + return mwApi.logEvents(logBuilders); } } diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java index d58eb3566..fd0a26959 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java @@ -27,8 +27,11 @@ import com.google.gson.GsonBuilder; import java.util.List; +import javax.inject.Inject; + import butterknife.BindView; import butterknife.ButterKnife; +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.location.LatLng; @@ -37,11 +40,12 @@ import fr.free.nrw.commons.theme.NavigationBaseActivity; import fr.free.nrw.commons.utils.UriSerializer; import timber.log.Timber; - public class NearbyActivity extends NavigationBaseActivity { @BindView(R.id.progressBar) ProgressBar progressBar; + @Inject CommonsApplication application; + private boolean isMapViewActive = false; private static final int LOCATION_REQUEST = 1; @@ -91,7 +95,7 @@ public class NearbyActivity extends NavigationBaseActivity { locationManager = new LocationServiceManager(this); locationManager.registerLocationManager(); curLatLang = locationManager.getLatestLocation(); - nearbyAsyncTask = new NearbyAsyncTask(this); + nearbyAsyncTask = new NearbyAsyncTask(this, application); nearbyAsyncTask.execute(); } @@ -230,7 +234,7 @@ public class NearbyActivity extends NavigationBaseActivity { } private void refreshView() { - nearbyAsyncTask = new NearbyAsyncTask(this); + nearbyAsyncTask = new NearbyAsyncTask(this, application); nearbyAsyncTask.execute(); } @@ -245,9 +249,11 @@ public class NearbyActivity extends NavigationBaseActivity { private class NearbyAsyncTask extends AsyncTask> { private final Context mContext; + private final CommonsApplication application; - private NearbyAsyncTask(Context context) { + private NearbyAsyncTask(Context context, CommonsApplication application) { mContext = context; + this.application = application; } @Override @@ -258,8 +264,7 @@ public class NearbyActivity extends NavigationBaseActivity { @Override protected List doInBackground(Void... params) { return NearbyController - .loadAttractionsFromLocation(curLatLang, CommonsApplication.getInstance() - ); + .loadAttractionsFromLocation(curLatLang, application); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java index af4f0eff4..8bef4f6ae 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java @@ -5,15 +5,16 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; +import dagger.android.AndroidInjection; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; public class BaseActivity extends AppCompatActivity { boolean currentTheme; - @Override protected void onCreate(Bundle savedInstanceState) { + AndroidInjection.inject(this); if(Utils.isDarkTheme(this)){ currentTheme = true; setTheme(R.style.DarkAppTheme); 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 680264ab3..8cfa40f66 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 @@ -177,7 +177,7 @@ public class MultipleShareActivity // 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(app.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", photosList.size()) @@ -288,7 +288,7 @@ public class MultipleShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", photosList.size()) @@ -296,7 +296,7 @@ public class MultipleShareActivity .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) 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 42ec3cfe6..4bc38c523 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 @@ -27,7 +27,6 @@ import com.facebook.drawee.view.SimpleDraweeView; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -168,7 +167,7 @@ public class ShareActivity // 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(app.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", 1) @@ -190,7 +189,7 @@ public class ShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", 1) @@ -198,7 +197,7 @@ public class ShareActivity .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) 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 f6e4ee6a2..c064b55b4 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 @@ -247,7 +247,7 @@ public class UploadService extends HandlerService { String resultStatus = uploadResult.getResultStatus(); if (!resultStatus.equals("Success")) { showFailedNotification(contribution); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("source", contribution.getSource()) .param("multiple", contribution.getMultiple()) @@ -261,7 +261,7 @@ public class UploadService extends HandlerService { contribution.setDateUploaded(uploadResult.getDateUploaded()); contribution.save(); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) .param("username", app.getCurrentAccount().name) .param("source", contribution.getSource()) //FIXME .param("filename", contribution.getFilename()) From 7880a08c30a125ba259fd4b2d5e8ee656b0e8759 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 09:55:25 -0500 Subject: [PATCH 03/17] Ensure that activities and content providers are integrated into DI. --- app/src/main/AndroidManifest.xml | 143 +++++++++--------- .../main/java/fr/free/nrw/commons/Utils.java | 3 - .../nrw/commons/di/ActivityBuilderModule.java | 24 +-- .../di/ContentProviderBuilderModule.java | 6 +- .../free/nrw/commons/theme/BaseActivity.java | 14 +- 5 files changed, 90 insertions(+), 100 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 882e1fb13..ab69029bd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,48 +2,46 @@ package="fr.free.nrw.commons"> - - - - - + + + + + - - - - - - + + + + + + - + android:supportsRtl="true" + android:theme="@style/Theme.AppCompat"> + android:name="org.acra.CrashReportDialog" + android:excludeFromRecents="true" + android:finishOnTaskLaunch="true" + android:launchMode="singleInstance" + android:theme="@android:style/Theme.Dialog" /> + + - - + + - - + + + + android:label="@string/app_name"> @@ -51,11 +49,11 @@ + + android:name=".upload.MultipleShareActivity" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name"> @@ -65,33 +63,34 @@ - + android:name=".contributions.ContributionsActivity" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" /> + + android:label="@string/title_activity_settings" /> + + + android:label="@string/title_activity_signup" /> + - - + + + android:process=":auth"> @@ -102,27 +101,25 @@ + android:name=".contributions.ContributionsSyncService" + android:exported="true"> - + + android:name="android.content.SyncAdapter" + android:resource="@xml/contributions_sync_adapter" /> + android:name=".modifications.ModificationsSyncService" + android:exported="true"> - + + android:name="android.content.SyncAdapter" + android:resource="@xml/modifications_sync_adapter" /> + android:resource="@xml/provider_paths" /> - + android:name=".contributions.ContributionsContentProvider" + android:authorities="fr.free.nrw.commons.contributions.contentprovider" + android:exported="false" + android:label="@string/provider_contributions" + android:syncable="true" /> - + android:name=".modifications.ModificationsContentProvider" + android:authorities="fr.free.nrw.commons.modifications.contentprovider" + android:exported="false" + android:label="@string/provider_modifications" + android:syncable="true" /> + - + android:name=".category.CategoryContentProvider" + android:authorities="fr.free.nrw.commons.categories.contentprovider" + android:exported="false" + android:label="@string/provider_categories" + android:syncable="false" /> diff --git a/app/src/main/java/fr/free/nrw/commons/Utils.java b/app/src/main/java/fr/free/nrw/commons/Utils.java index 7e75f8718..a3fcb746c 100644 --- a/app/src/main/java/fr/free/nrw/commons/Utils.java +++ b/app/src/main/java/fr/free/nrw/commons/Utils.java @@ -276,7 +276,4 @@ public class Utils { return value == null || value.trim().isEmpty(); } - public static boolean isDarkTheme(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("theme",false); - } } diff --git a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java index 28acf341b..d89c3ac84 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java @@ -16,16 +16,25 @@ import fr.free.nrw.commons.upload.ShareActivity; public abstract class ActivityBuilderModule { @ContributesAndroidInjector - abstract ContributionsActivity bindContributionsActivity(); + abstract LoginActivity bindLoginActivity(); @ContributesAndroidInjector - abstract MultipleShareActivity bindMultipleShareActivity(); + abstract WelcomeActivity bindWelcomeActivity(); @ContributesAndroidInjector abstract ShareActivity bindShareActivity(); @ContributesAndroidInjector - abstract LoginActivity bindLoginActivity(); + abstract MultipleShareActivity bindMultipleShareActivity(); + + @ContributesAndroidInjector + abstract ContributionsActivity bindContributionsActivity(); + + @ContributesAndroidInjector + abstract SettingsActivity bindSettingsActivity(); + + @ContributesAndroidInjector + abstract AboutActivity bindAboutActivity(); @ContributesAndroidInjector abstract SignupActivity bindSignupActivity(); @@ -33,13 +42,4 @@ public abstract class ActivityBuilderModule { @ContributesAndroidInjector abstract NearbyActivity bindNearbyActivity(); - @ContributesAndroidInjector - abstract AboutActivity bindAboutActivity(); - - @ContributesAndroidInjector - abstract SettingsActivity bindSettingsActivity(); - - @ContributesAndroidInjector - abstract WelcomeActivity bindWelcomeActivity(); - } diff --git a/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java index 9d5e91f65..ac9af26a8 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java @@ -12,13 +12,13 @@ import fr.free.nrw.commons.modifications.ModificationsContentProvider; @Module public abstract class ContentProviderBuilderModule { - @ContributesAndroidInjector - abstract CategoryContentProvider bindCategoryContentProvider(); - @ContributesAndroidInjector abstract ContributionsContentProvider bindContributionsContentProvider(); @ContributesAndroidInjector abstract ModificationsContentProvider bindModificationsContentProvider(); + @ContributesAndroidInjector + abstract CategoryContentProvider bindCategoryContentProvider(); + } diff --git a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java index 8bef4f6ae..c9c4f5cdd 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java @@ -3,19 +3,17 @@ package fr.free.nrw.commons.theme; import android.content.Intent; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.v7.app.AppCompatActivity; -import dagger.android.AndroidInjection; +import dagger.android.DaggerActivity; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.Utils; -public class BaseActivity extends AppCompatActivity { +public class BaseActivity extends DaggerActivity { boolean currentTheme; @Override protected void onCreate(Bundle savedInstanceState) { - AndroidInjection.inject(this); - if(Utils.isDarkTheme(this)){ + boolean currentThemeIsDark = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("theme", false); + if (currentThemeIsDark) { currentTheme = true; setTheme(R.style.DarkAppTheme); } else { @@ -28,8 +26,8 @@ public class BaseActivity extends AppCompatActivity { @Override protected void onResume() { // Restart activity if theme is changed - boolean newTheme = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("theme",false); - if(currentTheme!=newTheme){ //is activity theme changed + boolean newTheme = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("theme", false); + if (currentTheme != newTheme) { //is activity theme changed Intent intent = getIntent(); finish(); startActivity(intent); From dbcbeed822721ceac4089f7b7377739b863f8c95 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 10:35:34 -0500 Subject: [PATCH 04/17] Android injection for support classes. --- .../fr/free/nrw/commons/di/CommonsApplicationComponent.java | 2 ++ app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index 84d510faa..04f4e52b8 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -5,6 +5,7 @@ import javax.inject.Singleton; import dagger.Component; import dagger.android.AndroidInjectionModule; import dagger.android.AndroidInjector; +import dagger.android.support.AndroidSupportInjectionModule; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; import fr.free.nrw.commons.contributions.ContributionsSyncAdapter; @@ -14,6 +15,7 @@ import fr.free.nrw.commons.modifications.ModificationsSyncAdapter; @Component(modules = { CommonsApplicationModule.class, AndroidInjectionModule.class, + AndroidSupportInjectionModule.class, ActivityBuilderModule.class, ContentProviderBuilderModule.class }) diff --git a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java index c9c4f5cdd..fb90557ab 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.java @@ -4,10 +4,10 @@ import android.content.Intent; import android.os.Bundle; import android.preference.PreferenceManager; -import dagger.android.DaggerActivity; +import dagger.android.support.DaggerAppCompatActivity; import fr.free.nrw.commons.R; -public class BaseActivity extends DaggerActivity { +public class BaseActivity extends DaggerAppCompatActivity { boolean currentTheme; @Override From ed1ae98d8eec7566489b66d5ae7a606c9c92e384 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 21:40:50 -0500 Subject: [PATCH 05/17] Finished removing coupling between classes around the getInstance() method. --- .../free/nrw/commons/CommonsApplication.java | 16 -------- .../free/nrw/commons/MediaWikiImageView.java | 10 +++-- .../category/CategorizationFragment.java | 15 ++++--- .../ContributionsListFragment.java | 11 +++-- .../di/CommonsApplicationComponent.java | 3 ++ .../commons/media/MediaDetailFragment.java | 11 +++-- .../media/MediaDetailPagerFragment.java | 13 +++--- .../nrw/commons/nearby/NearbyActivity.java | 16 ++++---- .../nrw/commons/nearby/NearbyController.java | 11 +++-- .../commons/settings/SettingsFragment.java | 14 ++++++- .../nrw/commons/upload/ExistingFileAsync.java | 8 ++-- .../fr/free/nrw/commons/upload/FileUtils.java | 2 +- .../free/nrw/commons/upload/GPSExtractor.java | 13 ++++-- .../commons/upload/MultipleShareActivity.java | 33 ++++++++------- .../free/nrw/commons/upload/MwVolleyApi.java | 8 ++-- .../nrw/commons/upload/ShareActivity.java | 41 ++++++++++--------- .../nrw/commons/upload/UploadController.java | 28 ++++++------- .../nrw/commons/upload/UploadService.java | 26 ++++++------ 18 files changed, 154 insertions(+), 125 deletions(-) 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 6b5f07caa..a251c27ec 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -79,7 +79,6 @@ public class CommonsApplication extends DaggerApplication { public static final String FEEDBACK_EMAIL = "commons-app-android@googlegroups.com"; public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App (%s) Feedback"; - private static CommonsApplication instance = null; private MediaWikiApi api = null; private LruCache thumbnailUrlCache = new LruCache<>(1024); private CacheController cacheData = null; @@ -87,21 +86,6 @@ public class CommonsApplication extends DaggerApplication { private NearbyPlaces nearbyPlaces = null; private CommonsApplicationComponent component; - /** - * This should not be called by ANY application code (other than the magic Android glue) - * Use CommonsApplication.getInstance() instead to get the singleton. - */ - public CommonsApplication() { - CommonsApplication.instance = this; - } - - public static CommonsApplication getInstance() { - if (instance == null) { - instance = new CommonsApplication(); - } - return instance; - } - public MediaWikiApi getMWApi() { if (api == null) { api = new ApacheHttpClientMediaWikiApi(API_URL); diff --git a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java index fbf475a57..46ca80b46 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java @@ -40,11 +40,12 @@ public class MediaWikiImageView extends SimpleDraweeView { return; } - if (CommonsApplication.getInstance().getThumbnailUrlCache().get(media.getFilename()) != null) { - setImageUrl(CommonsApplication.getInstance().getThumbnailUrlCache().get(media.getFilename())); + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + if (app.getThumbnailUrlCache().get(media.getFilename()) != null) { + setImageUrl(app.getThumbnailUrlCache().get(media.getFilename())); } else { setImageUrl(null); - MediaWikiApi mediaWikiApi = CommonsApplication.getInstance().getMWApi(); + MediaWikiApi mediaWikiApi = app.getMWApi(); currentThumbnailTask = new ThumbnailFetchTask(media, mediaWikiApi); currentThumbnailTask.execute(media.getFilename()); } @@ -87,7 +88,8 @@ public class MediaWikiImageView extends SimpleDraweeView { } else { // only cache meaningful thumbnails received from network. try { - CommonsApplication.getInstance().getThumbnailUrlCache().put(media.getFilename(), result); + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + app.getThumbnailUrlCache().put(media.getFilename(), result); } catch (NullPointerException npe) { Timber.e("error when adding pic to cache " + npe); 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 b281a6c1b..e87195f22 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 @@ -30,8 +30,11 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; + import butterknife.BindView; import butterknife.ButterKnife; +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.data.Category; @@ -48,7 +51,7 @@ import static fr.free.nrw.commons.category.CategoryContentProvider.AUTHORITY; /** * Displays the category suggestion and selection screen. Category search is initiated here. */ -public class CategorizationFragment extends Fragment { +public class CategorizationFragment extends DaggerFragment { public static final int SEARCH_CATS_LIMIT = 25; @@ -63,6 +66,8 @@ public class CategorizationFragment extends Fragment { @BindView(R.id.categoriesExplanation) TextView categoriesSkip; + @Inject CommonsApplication application; + private RVRendererAdapter categoriesAdapter; private OnCategoriesSaveHandler onCategoriesSaveHandler; private HashMap> categoriesCache; @@ -202,7 +207,7 @@ public class CategorizationFragment extends Fragment { .observeOn(AndroidSchedulers.mainThread()) .subscribe( s -> categoriesAdapter.add(s), - throwable -> Timber.e(throwable), + Timber::e, () -> { categoriesAdapter.notifyDataSetChanged(); categoriesSearchInProgress.setVisibility(View.GONE); @@ -248,7 +253,7 @@ public class CategorizationFragment extends Fragment { SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity()); String title = titleDesc.getString("Title", ""); - return CommonsApplication.getInstance().getMWApi() + return application.getMWApi() .searchTitles(title, SEARCH_CATS_LIMIT) .map(name -> new CategoryItem(name, false)); } @@ -271,7 +276,7 @@ public class CategorizationFragment extends Fragment { } //otherwise, search API for matching categories - return CommonsApplication.getInstance().getMWApi() + return application.getMWApi() .allCategories(term, SEARCH_CATS_LIMIT) .map(name -> new CategoryItem(name, false)); } @@ -282,7 +287,7 @@ public class CategorizationFragment extends Fragment { return Observable.empty(); } - return CommonsApplication.getInstance().getMWApi() + return application.getMWApi() .searchCategories(term, SEARCH_CATS_LIMIT) .map(s -> new CategoryItem(s, false)); } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index bcbb5a739..364448723 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -1,8 +1,6 @@ package fr.free.nrw.commons.contributions; -import android.Manifest; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -23,8 +21,11 @@ import android.widget.GridView; import android.widget.ListAdapter; import android.widget.TextView; +import javax.inject.Inject; + import butterknife.BindView; import butterknife.ButterKnife; +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.nearby.NearbyActivity; @@ -33,7 +34,7 @@ import timber.log.Timber; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.app.Activity.RESULT_OK; -public class ContributionsListFragment extends Fragment { +public class ContributionsListFragment extends DaggerFragment { public interface SourceRefresher { void refreshSource(); @@ -43,6 +44,8 @@ public class ContributionsListFragment extends Fragment { @BindView(R.id.waitingMessage) TextView waitingMessage; @BindView(R.id.emptyMessage) TextView emptyMessage; + @Inject CommonsApplication application; + private ContributionController controller; @Override @@ -193,7 +196,7 @@ public class ContributionsListFragment extends Fragment { menu.clear(); // See http://stackoverflow.com/a/8495697/17865 inflater.inflate(R.menu.fragment_contributions_list, menu); - if (!CommonsApplication.getInstance().deviceHasCamera()) { + if (!application.deviceHasCamera()) { menu.findItem(R.id.menu_from_camera).setEnabled(false); } } diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index 04f4e52b8..8ea0a86d0 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -10,6 +10,7 @@ import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; import fr.free.nrw.commons.contributions.ContributionsSyncAdapter; import fr.free.nrw.commons.modifications.ModificationsSyncAdapter; +import fr.free.nrw.commons.upload.UploadService; @Singleton @Component(modules = { @@ -24,6 +25,8 @@ public interface CommonsApplicationComponent extends AndroidInjector detailFetchTask; private LicenseList licenseList; @@ -189,7 +194,7 @@ public class MediaDetailFragment extends Fragment { @Override protected void onPreExecute() { - extractor = new MediaDataExtractor(media.getFilename(), licenseList, CommonsApplication.getInstance().getMWApi()); + extractor = new MediaDataExtractor(media.getFilename(), licenseList, application.getMWApi()); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index 3e63b2006..2f3fd86cf 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -27,6 +27,9 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import javax.inject.Inject; + +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; @@ -34,7 +37,7 @@ import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.mwapi.EventLog; -public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPageChangeListener { +public class MediaDetailPagerFragment extends DaggerFragment implements ViewPager.OnPageChangeListener { public interface MediaDetailProvider { Media getMediaAtPosition(int i); @@ -48,9 +51,10 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa void unregisterDataSetObserver(DataSetObserver observer); } + @Inject CommonsApplication application; + private ViewPager pager; private Boolean editable; - private CommonsApplication app; public MediaDetailPagerFragment() { this(false); @@ -120,7 +124,6 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa if (savedInstanceState != null) { editable = savedInstanceState.getBoolean("editable"); } - app = CommonsApplication.getInstance(); setHasOptionsMenu(true); } @@ -131,8 +134,8 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa switch(item.getItemId()) { case R.id.menu_share_current_image: // Share - this is just logs it, intent set in onCreateOptionsMenu, around line 252 - EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("filename", m.getFilename()) .log(); return true; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java index fd0a26959..7e7d4f719 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java @@ -31,7 +31,6 @@ import javax.inject.Inject; import butterknife.BindView; import butterknife.ButterKnife; -import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.location.LatLng; @@ -95,7 +94,7 @@ public class NearbyActivity extends NavigationBaseActivity { locationManager = new LocationServiceManager(this); locationManager.registerLocationManager(); curLatLang = locationManager.getLatestLocation(); - nearbyAsyncTask = new NearbyAsyncTask(this, application); + nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(application)); nearbyAsyncTask.execute(); } @@ -234,7 +233,7 @@ public class NearbyActivity extends NavigationBaseActivity { } private void refreshView() { - nearbyAsyncTask = new NearbyAsyncTask(this, application); + nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(application)); nearbyAsyncTask.execute(); } @@ -249,11 +248,11 @@ public class NearbyActivity extends NavigationBaseActivity { private class NearbyAsyncTask extends AsyncTask> { private final Context mContext; - private final CommonsApplication application; + private final NearbyController nearbyController; - private NearbyAsyncTask(Context context, CommonsApplication application) { - mContext = context; - this.application = application; + private NearbyAsyncTask(Context context, NearbyController nearbyController) { + this.mContext = context; + this.nearbyController = nearbyController; } @Override @@ -263,8 +262,7 @@ public class NearbyActivity extends NavigationBaseActivity { @Override protected List doInBackground(Void... params) { - return NearbyController - .loadAttractionsFromLocation(curLatLang, application); + return nearbyController.loadAttractionsFromLocation(curLatLang, application); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index b08b99d72..46ad80dad 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -10,7 +10,6 @@ import com.mapbox.mapboxsdk.annotations.IconFactory; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -29,18 +28,24 @@ import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween; public class NearbyController { private static final int MAX_RESULTS = 1000; + private final CommonsApplication application; + + public NearbyController(CommonsApplication application) { + this.application = application; + } + /** * Prepares Place list to make their distance information update later. * @param curLatLng current location for user * @param context context * @return Place list without distance information */ - public static List loadAttractionsFromLocation(LatLng curLatLng, Context context) { + public List loadAttractionsFromLocation(LatLng curLatLng, Context context) { Timber.d("Loading attractions near %s", curLatLng); if (curLatLng == null) { return Collections.emptyList(); } - NearbyPlaces nearbyPlaces = CommonsApplication.getInstance().getNearbyPlaces(); + NearbyPlaces nearbyPlaces = application.getNearbyPlaces(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); List places = prefs.getBoolean("useWikidata", true) ? nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage()) diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index cfeda91d1..730ff2fed 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -1,6 +1,7 @@ package fr.free.nrw.commons.settings; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; @@ -11,11 +12,22 @@ import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; public class SettingsFragment extends PreferenceFragment { + @Inject CommonsApplication application; + + @Override + public void onAttach(Context context) { + AndroidInjection.inject(this); + super.onAttach(context); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -41,7 +53,7 @@ public class SettingsFragment extends PreferenceFragment { final EditTextPreference uploadLimit = (EditTextPreference) findPreference("uploads"); final SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(CommonsApplication.getInstance()); + .getDefaultSharedPreferences(application); int uploads = sharedPref.getInt(Prefs.UPLOADS_SHOWING, 100); uploadLimit.setText(uploads + ""); uploadLimit.setSummary(uploads + ""); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java b/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java index 09fed56ea..fee0765a4 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java @@ -1,14 +1,12 @@ package fr.free.nrw.commons.upload; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.support.v7.app.AlertDialog; import java.io.IOException; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.mwapi.MediaWikiApi; @@ -19,6 +17,7 @@ import timber.log.Timber; * Displays a warning to the user if the file already exists on Commons */ public class ExistingFileAsync extends AsyncTask { + interface Callback { void onResult(Result result); } @@ -29,14 +28,16 @@ public class ExistingFileAsync extends AsyncTask { DUPLICATE_CANCELLED } + private final MediaWikiApi api; private final String fileSha1; private final Context context; private final Callback callback; - public ExistingFileAsync(String fileSha1, Context context, Callback callback) { + public ExistingFileAsync(String fileSha1, Context context, Callback callback, MediaWikiApi mwApi) { this.fileSha1 = fileSha1; this.context = context; this.callback = callback; + this.api = mwApi; } @Override @@ -46,7 +47,6 @@ public class ExistingFileAsync extends AsyncTask { @Override protected Boolean doInBackground(Void... voids) { - MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); // https://commons.wikimedia.org/w/api.php?action=query&list=allimages&format=xml&aisha1=801957214aba50cb63bb6eb1b0effa50188900ba boolean fileExists; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java index a211a38bf..a20aa6186 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java @@ -154,7 +154,7 @@ public class FileUtils { } /** - * Check if the URI is owned by the current app. + * Check if the URI is owned by the current application. */ public static boolean isSelfOwned(Context context, Uri uri) { return uri.getAuthority().equals(context.getPackageName() + ".provider"); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java index e7326246c..39e8d4c48 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java @@ -26,6 +26,7 @@ import timber.log.Timber; */ public class GPSExtractor { + private final CommonsApplication application; private ExifInterface exif; private double decLatitude; private double decLongitude; @@ -38,26 +39,30 @@ public class GPSExtractor { /** * Construct from the file descriptor of the image (only for API 24 or newer). * @param fileDescriptor the file descriptor of the image + * @param application the application */ @RequiresApi(24) - public GPSExtractor(@NonNull FileDescriptor fileDescriptor) { + public GPSExtractor(@NonNull FileDescriptor fileDescriptor, CommonsApplication application) { try { exif = new ExifInterface(fileDescriptor); } catch (IOException | IllegalArgumentException e) { Timber.w(e); } + this.application = application; } /** * Construct from the file path of the image. * @param path file path of the image + * @param application the application */ - public GPSExtractor(@NonNull String path) { + public GPSExtractor(@NonNull String path, CommonsApplication application) { try { exif = new ExifInterface(path); } catch (IOException | IllegalArgumentException e) { Timber.w(e); } + this.application = application; } /** @@ -66,7 +71,7 @@ public class GPSExtractor { */ private boolean gpsPreferenceEnabled() { SharedPreferences sharedPref - = PreferenceManager.getDefaultSharedPreferences(CommonsApplication.getInstance()); + = PreferenceManager.getDefaultSharedPreferences(application); boolean gpsPref = sharedPref.getBoolean("allowGps", false); Timber.d("Gps pref set to: %b", gpsPref); return gpsPref; @@ -76,7 +81,7 @@ public class GPSExtractor { * Registers a LocationManager to listen for current location */ protected void registerLocationManager() { - locationManager = (LocationManager) CommonsApplication.getInstance() + locationManager = (LocationManager) application .getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); String provider = locationManager.getBestProvider(criteria, true); 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 8cfa40f66..f247b5604 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 @@ -24,6 +24,8 @@ import android.widget.Toast; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + import butterknife.ButterKnife; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Media; @@ -47,7 +49,9 @@ public class MultipleShareActivity FragmentManager.OnBackStackChangedListener, MultipleUploadListFragment.OnMultipleUploadInitiatedHandler, OnCategoriesSaveHandler { - private CommonsApplication app; + @Inject + CommonsApplication application; + private ArrayList photosList = null; private MultipleUploadListFragment uploadsList; @@ -133,7 +137,7 @@ public class MultipleShareActivity if (uploadCount == photosList.size()) { dialog.dismiss(); Toast startingToast = Toast.makeText( - CommonsApplication.getInstance(), + application, R.string.uploading_started, Toast.LENGTH_LONG ); @@ -176,9 +180,9 @@ public class MultipleShareActivity } // 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(app.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + ContentResolver.setSyncAutomatically(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", photosList.size()) .param("source", Contribution.SOURCE_EXTERNAL) @@ -202,10 +206,9 @@ public class MultipleShareActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - uploadController = new UploadController(); + uploadController = new UploadController(application); setContentView(R.layout.activity_multiple_uploads); - app = CommonsApplication.getInstance(); ButterKnife.bind(this); initDrawer(); @@ -245,7 +248,7 @@ public class MultipleShareActivity @Override protected void onAuthCookieAcquired(String authCookie) { - app.getMWApi().setAuthCookie(authCookie); + application.getMWApi().setAuthCookie(authCookie); Intent intent = getIntent(); if(intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { @@ -288,16 +291,16 @@ public class MultipleShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", photosList.size()) .param("source", Contribution.SOURCE_EXTERNAL) .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) .param("result", "cancelled") @@ -307,11 +310,7 @@ public class MultipleShareActivity @Override public void onBackStackChanged() { - if(mediaDetails != null && mediaDetails.isVisible()) { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } else { - getSupportActionBar().setDisplayHomeAsUpEnabled(false); - } + getSupportActionBar().setDisplayHomeAsUpEnabled(mediaDetails != null && mediaDetails.isVisible()); } } \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java b/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java index f515f2d0c..4b774ba68 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java @@ -33,13 +33,15 @@ public class MwVolleyApi { private static RequestQueue REQUEST_QUEUE; private static final Gson GSON = new GsonBuilder().create(); - protected static Set categorySet; + private static Set categorySet; private static List categoryList; private static final String MWURL = "https://commons.wikimedia.org/"; + private final CommonsApplication application; - public MwVolleyApi() { + public MwVolleyApi(CommonsApplication application) { categorySet = new HashSet<>(); + this.application = application; } public static List getGpsCat() { @@ -93,7 +95,7 @@ public class MwVolleyApi { private synchronized RequestQueue getQueue() { if (REQUEST_QUEUE == null) { - REQUEST_QUEUE = Volley.newRequestQueue(CommonsApplication.getInstance()); + REQUEST_QUEUE = Volley.newRequestQueue(application); } return REQUEST_QUEUE; } 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 4bc38c523..3043e506d 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 @@ -30,6 +30,8 @@ import java.io.InputStream; import java.util.Date; import java.util.List; +import javax.inject.Inject; + import butterknife.ButterKnife; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; @@ -63,7 +65,7 @@ public class ShareActivity private static final int REQUEST_PERM_ON_SUBMIT_STORAGE = 4; private CategorizationFragment categorizationFragment; - private CommonsApplication app; + @Inject CommonsApplication application; private String source; private String mimeType; @@ -114,7 +116,7 @@ public class ShareActivity @RequiresApi(16) private boolean needsToRequestStoragePermission() { // We need to ask storage permission when - // the file is not owned by this app, (e.g. shared from the Gallery) + // the file is not owned by this application, (e.g. shared from the Gallery) // and permission is not obtained. return !FileUtils.isSelfOwned(getApplicationContext(), mediaUri) && (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) @@ -125,7 +127,7 @@ public class ShareActivity getFileMetadata(locationPermitted); Toast startingToast = Toast.makeText( - CommonsApplication.getInstance(), + application, R.string.uploading_started, Toast.LENGTH_LONG ); @@ -133,7 +135,7 @@ public class ShareActivity if (!cacheFound) { //Has to be called after apiCall.request() - app.getCacheData().cacheCategory(); + application.getCacheData().cacheCategory(); Timber.d("Cache the categories found"); } @@ -165,10 +167,10 @@ public class ShareActivity // 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(app.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", 1) .param("source", contribution.getSource()) @@ -189,16 +191,16 @@ public class ShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", 1) .param("source", contribution.getSource()) .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) .param("result", "cancelled") @@ -208,7 +210,7 @@ public class ShareActivity @Override protected void onAuthCookieAcquired(String authCookie) { - app.getMWApi().setAuthCookie(authCookie); + application.getMWApi().setAuthCookie(authCookie); } @@ -222,11 +224,10 @@ public class ShareActivity @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - uploadController = new UploadController(); + uploadController = new UploadController(application); setContentView(R.layout.activity_share); ButterKnife.bind(this); initBack(); - app = CommonsApplication.getInstance(); backgroundImageView = (SimpleDraweeView)findViewById(R.id.backgroundImage); backgroundImageView.setHierarchy(GenericDraweeHierarchyBuilder .newInstance(getResources()) @@ -384,7 +385,7 @@ public class ShareActivity Timber.d("%s duplicate check: %s", mediaUri.toString(), result); duplicateCheckPassed = (result == DUPLICATE_PROCEED || result == NO_DUPLICATE); - }); + }, application.getMWApi()); fileAsyncTask.execute(); } catch (IOException e) { Timber.d(e, "IO Exception: "); @@ -448,12 +449,12 @@ public class ShareActivity = getContentResolver().openFileDescriptor(mediaUri, "r"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (descriptor != null) { - imageObj = new GPSExtractor(descriptor.getFileDescriptor()); + imageObj = new GPSExtractor(descriptor.getFileDescriptor(), application); } } else { String filePath = getPathOfMediaOrCopy(); if (filePath != null) { - imageObj = new GPSExtractor(filePath); + imageObj = new GPSExtractor(filePath, application); } } } @@ -480,12 +481,12 @@ public class ShareActivity if (imageObj.imageCoordsExists) { double decLongitude = imageObj.getDecLongitude(); double decLatitude = imageObj.getDecLatitude(); - app.getCacheData().setQtPoint(decLongitude, decLatitude); + application.getCacheData().setQtPoint(decLongitude, decLatitude); } - MwVolleyApi apiCall = new MwVolleyApi(); + MwVolleyApi apiCall = new MwVolleyApi(application); - List displayCatList = app.getCacheData().findCategory(); + List displayCatList = application.getCacheData().findCategory(); boolean catListEmpty = displayCatList.isEmpty(); // If no categories found in cache, call MediaWiki API to match image coords with nearby Commons categories diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java index 4a41fc4d1..e3cdd56dc 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java @@ -26,14 +26,14 @@ import timber.log.Timber; public class UploadController { private UploadService uploadService; - private final CommonsApplication app; + private final CommonsApplication application; public interface ContributionUploadProgress { void onUploadStarted(Contribution contribution); } - public UploadController() { - app = CommonsApplication.getInstance(); + public UploadController(CommonsApplication application) { + this.application = application; } private boolean isUploadServiceConnected; @@ -52,15 +52,15 @@ public class UploadController { }; public void prepareService() { - Intent uploadServiceIntent = new Intent(app, UploadService.class); + Intent uploadServiceIntent = new Intent(application, UploadService.class); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); - app.startService(uploadServiceIntent); - app.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); + application.startService(uploadServiceIntent); + application.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); } public void cleanup() { if(isUploadServiceConnected) { - app.unbindService(uploadServiceConnection); + application.unbindService(uploadServiceConnection); } } @@ -68,7 +68,7 @@ public class UploadController { Contribution contribution; //TODO: Modify this to include coords - contribution = new Contribution(mediaUri, null, title, description, -1, null, null, app.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY, decimalCoords); + contribution = new Contribution(mediaUri, null, title, description, -1, null, null, application.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY, decimalCoords); contribution.setTag("mimeType", mimeType); contribution.setSource(source); @@ -79,11 +79,11 @@ public class UploadController { public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(application); //Set creator, desc, and license if(TextUtils.isEmpty(contribution.getCreator())) { - contribution.setCreator(app.getCurrentAccount().name); + contribution.setCreator(application.getCurrentAccount().name); } if(contribution.getDescription() == null) { @@ -104,12 +104,12 @@ public class UploadController { long length; try { if(contribution.getDataLength() <= 0) { - length = app.getContentResolver() + length = application.getContentResolver() .openAssetFileDescriptor(contribution.getLocalUri(), "r") .getLength(); if(length == -1) { // Let us find out the long way! - length = Utils.countBytes(app.getContentResolver() + length = Utils.countBytes(application.getContentResolver() .openInputStream(contribution.getLocalUri())); } contribution.setDataLength(length); @@ -126,7 +126,7 @@ public class UploadController { Boolean imagePrefix = false; if (mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) { - mimeType = app.getContentResolver().getType(contribution.getLocalUri()); + mimeType = application.getContentResolver().getType(contribution.getLocalUri()); } if (mimeType != null) { @@ -137,7 +137,7 @@ public class UploadController { if (imagePrefix && contribution.getDateCreated() == null) { Timber.d("local uri " + contribution.getLocalUri()); - Cursor cursor = app.getContentResolver().query(contribution.getLocalUri(), + Cursor cursor = application.getContentResolver().query(contribution.getLocalUri(), new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null); if (cursor != null && cursor.getCount() != 0 && cursor.getColumnCount() != 0) { cursor.moveToFirst(); 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 c064b55b4..fb1535dce 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 @@ -22,6 +22,8 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.inject.Inject; + import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; import fr.free.nrw.commons.R; @@ -45,12 +47,11 @@ public class UploadService extends HandlerService { public static final String EXTRA_SOURCE = EXTRA_PREFIX + ".source"; public static final String EXTRA_CAMPAIGN = EXTRA_PREFIX + ".campaign"; + @Inject CommonsApplication application; + private NotificationManager notificationManager; private ContentProviderClient contributionsProviderClient; - private CommonsApplication app; - private NotificationCompat.Builder curProgressNotification; - private int toUpload; // The file names of unfinished uploads, used to prevent overwriting @@ -115,10 +116,11 @@ public class UploadService extends HandlerService { @Override public void onCreate() { + ((CommonsApplication)getApplicationContext()).injector().inject(this); + super.onCreate(); notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - app = CommonsApplication.getInstance(); contributionsProviderClient = this.getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY); } @@ -180,7 +182,7 @@ public class UploadService extends HandlerService { @SuppressLint("StringFormatInvalid") private void uploadContribution(Contribution contribution) { - MediaWikiApi api = app.getMWApi(); + MediaWikiApi api = application.getMWApi(); InputStream file = null; @@ -222,7 +224,7 @@ public class UploadService extends HandlerService { } if (!api.validateLogin()) { // Need to revalidate! - if (app.revalidateAuthToken()) { + if (application.revalidateAuthToken()) { Timber.d("Successfully revalidated token!"); } else { Timber.d("Unable to revalidate :("); @@ -247,8 +249,8 @@ public class UploadService extends HandlerService { String resultStatus = uploadResult.getResultStatus(); if (!resultStatus.equals("Success")) { showFailedNotification(contribution); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("source", contribution.getSource()) .param("multiple", contribution.getMultiple()) .param("result", uploadResult.getErrorCode()) @@ -261,8 +263,8 @@ public class UploadService extends HandlerService { contribution.setDateUploaded(uploadResult.getDateUploaded()); contribution.save(); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, CommonsApplication.getInstance()) - .param("username", app.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + .param("username", application.getCurrentAccount().name) .param("source", contribution.getSource()) //FIXME .param("filename", contribution.getFilename()) .param("multiple", contribution.getMultiple()) @@ -279,7 +281,7 @@ public class UploadService extends HandlerService { toUpload--; if (toUpload == 0) { // Sync modifications right after all uplaods are processed - ContentResolver.requestSync((CommonsApplication.getInstance()).getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle()); + ContentResolver.requestSync(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle()); stopForeground(true); } } @@ -302,7 +304,7 @@ public class UploadService extends HandlerService { } private String findUniqueFilename(String fileName) throws IOException { - MediaWikiApi api = app.getMWApi(); + MediaWikiApi api = application.getMWApi(); String sequenceFileName; for (int sequenceNumber = 1; true; sequenceNumber++) { if (sequenceNumber == 1) { From 647cc166ef243eabccd3d8065301dbbb96444b38 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 22:05:09 -0500 Subject: [PATCH 06/17] @Inject the MediaWikiApi where needed to reduce coupling between classes. --- .../free/nrw/commons/CommonsApplication.java | 14 ----------- .../free/nrw/commons/MediaWikiImageView.java | 13 ++++++---- .../free/nrw/commons/auth/LoginActivity.java | 4 +++- .../fr/free/nrw/commons/auth/LoginTask.java | 11 +++++---- .../auth/WikiAccountAuthenticatorService.java | 5 ++-- .../category/CategorizationFragment.java | 9 +++---- .../ContributionsSyncAdapter.java | 24 +++++++++---------- .../di/CommonsApplicationComponent.java | 3 +++ .../commons/media/MediaDetailFragment.java | 6 ++--- .../media/MediaDetailPagerFragment.java | 4 +++- .../ModificationsSyncAdapter.java | 11 ++++----- .../fr/free/nrw/commons/mwapi/EventLog.java | 8 +++---- .../fr/free/nrw/commons/mwapi/LogBuilder.java | 15 +++++++----- .../commons/upload/MultipleShareActivity.java | 13 +++++----- .../nrw/commons/upload/ShareActivity.java | 13 +++++----- .../nrw/commons/upload/UploadService.java | 14 +++++------ 16 files changed, 85 insertions(+), 82 deletions(-) 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 a251c27ec..0fd838cb6 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -4,9 +4,6 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; -import android.app.Activity; -import android.app.Application; -import android.content.ContentProvider; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -29,9 +26,6 @@ import javax.inject.Inject; import dagger.android.AndroidInjector; import dagger.android.DaggerApplication; -import dagger.android.DispatchingAndroidInjector; -import dagger.android.HasActivityInjector; -import dagger.android.HasContentProviderInjector; import fr.free.nrw.commons.auth.AccountUtil; import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.contributions.Contribution; @@ -79,20 +73,12 @@ public class CommonsApplication extends DaggerApplication { public static final String FEEDBACK_EMAIL = "commons-app-android@googlegroups.com"; public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App (%s) Feedback"; - private MediaWikiApi api = null; private LruCache thumbnailUrlCache = new LruCache<>(1024); private CacheController cacheData = null; private DBOpenHelper dbOpenHelper = null; private NearbyPlaces nearbyPlaces = null; private CommonsApplicationComponent component; - public MediaWikiApi getMWApi() { - if (api == null) { - api = new ApacheHttpClientMediaWikiApi(API_URL); - } - return api; - } - public CacheController getCacheData() { if (cacheData == null) { cacheData = new CacheController(); diff --git a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java index 46ca80b46..5d7a4cc48 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java @@ -11,10 +11,14 @@ import android.widget.Toast; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.view.SimpleDraweeView; +import javax.inject.Inject; + import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; public class MediaWikiImageView extends SimpleDraweeView { + @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; private ThumbnailFetchTask currentThumbnailTask; public MediaWikiImageView(Context context) { @@ -40,13 +44,11 @@ public class MediaWikiImageView extends SimpleDraweeView { return; } - CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); - if (app.getThumbnailUrlCache().get(media.getFilename()) != null) { - setImageUrl(app.getThumbnailUrlCache().get(media.getFilename())); + if (application.getThumbnailUrlCache().get(media.getFilename()) != null) { + setImageUrl(application.getThumbnailUrlCache().get(media.getFilename())); } else { setImageUrl(null); - MediaWikiApi mediaWikiApi = app.getMWApi(); - currentThumbnailTask = new ThumbnailFetchTask(media, mediaWikiApi); + currentThumbnailTask = new ThumbnailFetchTask(media, mwApi); currentThumbnailTask.execute(media.getFilename()); } } @@ -60,6 +62,7 @@ public class MediaWikiImageView extends SimpleDraweeView { } private void init() { + ((CommonsApplication) getContext().getApplicationContext()).injector().inject(this); setHierarchy(GenericDraweeHierarchyBuilder .newInstance(getResources()) .setPlaceholderImage(VectorDrawableCompat.create(getResources(), diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index cd83ca8f7..96367950a 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -25,6 +25,7 @@ import fr.free.nrw.commons.WelcomeActivity; import fr.free.nrw.commons.PageTitle; import fr.free.nrw.commons.contributions.ContributionsActivity; +import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; import static android.view.KeyEvent.KEYCODE_ENTER; @@ -36,6 +37,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { public static final String PARAM_USERNAME = "fr.free.nrw.commons.login.username"; @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; @Inject AccountUtil accountUtil; private SharedPreferences prefs = null; @@ -145,7 +147,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { canonicializeUsername(usernameEdit.getText().toString()), passwordEdit.getText().toString(), twoFactorEdit.getText().toString(), - accountUtil, application + accountUtil, application, mwApi ); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java index 49e2f93b8..7c63551eb 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java @@ -11,6 +11,7 @@ import java.io.IOException; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.mwapi.EventLog; +import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; class LoginTask extends AsyncTask { @@ -21,14 +22,16 @@ class LoginTask extends AsyncTask { private String twoFactorCode = ""; private AccountUtil accountUtil; private CommonsApplication app; + private MediaWikiApi mwApi; - public LoginTask(LoginActivity loginActivity, String username, String password, String twoFactorCode, AccountUtil accountUtil, CommonsApplication application) { + public LoginTask(LoginActivity loginActivity, String username, String password, String twoFactorCode, AccountUtil accountUtil, CommonsApplication application, MediaWikiApi mwApi) { this.loginActivity = loginActivity; this.username = username; this.password = password; this.twoFactorCode = twoFactorCode; this.accountUtil = accountUtil; this.app = application; + this.mwApi = mwApi; } @Override @@ -46,9 +49,9 @@ class LoginTask extends AsyncTask { protected String doInBackground(String... params) { try { if (twoFactorCode.isEmpty()) { - return app.getMWApi().login(username, password); + return mwApi.login(username, password); } else { - return app.getMWApi().login(username, password, twoFactorCode); + return mwApi.login(username, password, twoFactorCode); } } catch (IOException e) { // Do something better! @@ -61,7 +64,7 @@ class LoginTask extends AsyncTask { super.onPostExecute(result); Timber.d("Login done!"); - EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, app) + EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, app, mwApi) .param("username", username) .param("result", result) .log(); diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java index 2d1dc20fc..617f974b2 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java @@ -8,10 +8,11 @@ import android.os.IBinder; import javax.inject.Inject; import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.mwapi.MediaWikiApi; public class WikiAccountAuthenticatorService extends Service { - @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; @Inject AccountUtil accountUtil; private WikiAccountAuthenticator wikiAccountAuthenticator = null; @@ -23,7 +24,7 @@ public class WikiAccountAuthenticatorService extends Service { ((CommonsApplication)getApplication()).injector().inject(this); if (wikiAccountAuthenticator == null) { - wikiAccountAuthenticator = new WikiAccountAuthenticator(this, accountUtil, application.getMWApi()); + wikiAccountAuthenticator = new WikiAccountAuthenticator(this, accountUtil, mwApi); } return wikiAccountAuthenticator.getIBinder(); } 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 e87195f22..726c18dfd 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 @@ -38,6 +38,7 @@ import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.data.Category; +import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.upload.MwVolleyApi; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -66,7 +67,7 @@ public class CategorizationFragment extends DaggerFragment { @BindView(R.id.categoriesExplanation) TextView categoriesSkip; - @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; private RVRendererAdapter categoriesAdapter; private OnCategoriesSaveHandler onCategoriesSaveHandler; @@ -253,7 +254,7 @@ public class CategorizationFragment extends DaggerFragment { SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity()); String title = titleDesc.getString("Title", ""); - return application.getMWApi() + return mwApi .searchTitles(title, SEARCH_CATS_LIMIT) .map(name -> new CategoryItem(name, false)); } @@ -276,7 +277,7 @@ public class CategorizationFragment extends DaggerFragment { } //otherwise, search API for matching categories - return application.getMWApi() + return mwApi .allCategories(term, SEARCH_CATS_LIMIT) .map(name -> new CategoryItem(name, false)); } @@ -287,7 +288,7 @@ public class CategorizationFragment extends DaggerFragment { return Observable.empty(); } - return application.getMWApi() + return mwApi .searchCategories(term, SEARCH_CATS_LIMIT) .map(s -> new CategoryItem(s, false)); } 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 e9e20c9f2..c354a995c 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 @@ -28,7 +28,7 @@ import timber.log.Timber; public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { private static int COMMIT_THRESHOLD = 10; - @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; public ContributionsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); @@ -41,22 +41,23 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { return limit; // FIXME: Parameterize! } - private static final String[] existsQuery = { Contribution.Table.COLUMN_FILENAME }; + private static final String[] existsQuery = {Contribution.Table.COLUMN_FILENAME}; private static final String existsSelection = Contribution.Table.COLUMN_FILENAME + " = ?"; + private boolean fileExists(ContentProviderClient client, String filename) { Cursor cursor = null; try { cursor = client.query(ContributionsContentProvider.BASE_URI, existsQuery, existsSelection, - new String[] { filename }, + new String[]{filename}, "" ); return cursor.getCount() != 0; } catch (RemoteException e) { throw new RuntimeException(e); } finally { - if ( cursor != null ) { + if (cursor != null) { cursor.close(); } } @@ -64,21 +65,20 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { @Override public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) { - ((CommonsApplication)getContext().getApplicationContext()).injector().inject(this); + ((CommonsApplication) getContext().getApplicationContext()).injector().inject(this); // This code is fraught with possibilities of race conditions, but lalalalala I can't hear you! String user = account.name; - MediaWikiApi api = application.getMWApi(); SharedPreferences prefs = getContext().getSharedPreferences("prefs", Context.MODE_PRIVATE); String lastModified = prefs.getString("lastSyncTimestamp", ""); Date curTime = new Date(); LogEventResult result; Boolean done = false; String queryContinue = null; - while(!done) { + while (!done) { try { - result = api.logEvents(user, lastModified, queryContinue, getLimit()); + result = mwApi.logEvents(user, lastModified, queryContinue, getLimit()); } catch (IOException e) { // There isn't really much we can do, eh? // FIXME: Perhaps add EventLogging? @@ -97,7 +97,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { continue; } String filename = image.getFilename(); - if(fileExists(contentProviderClient, filename)) { + if (fileExists(contentProviderClient, filename)) { Timber.d("Skipping %s", filename); continue; } @@ -107,7 +107,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { contrib.setState(Contribution.STATE_COMPLETED); imageValues.add(contrib.toContentValues()); - if(imageValues.size() % COMMIT_THRESHOLD == 0) { + if (imageValues.size() % COMMIT_THRESHOLD == 0) { try { contentProviderClient.bulkInsert(ContributionsContentProvider.BASE_URI, imageValues.toArray(new ContentValues[]{})); } catch (RemoteException e) { @@ -117,7 +117,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { } } - if(imageValues.size() != 0) { + if (imageValues.size() != 0) { try { contentProviderClient.bulkInsert(ContributionsContentProvider.BASE_URI, imageValues.toArray(new ContentValues[]{})); } catch (RemoteException e) { @@ -126,7 +126,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { } queryContinue = result.getQueryContinue(); - if(TextUtils.isEmpty(queryContinue)) { + if (TextUtils.isEmpty(queryContinue)) { done = true; } } diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index 8ea0a86d0..ede3d6a20 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -7,6 +7,7 @@ import dagger.android.AndroidInjectionModule; import dagger.android.AndroidInjector; import dagger.android.support.AndroidSupportInjectionModule; import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.MediaWikiImageView; import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; import fr.free.nrw.commons.contributions.ContributionsSyncAdapter; import fr.free.nrw.commons.modifications.ModificationsSyncAdapter; @@ -31,6 +32,8 @@ public interface CommonsApplicationComponent extends AndroidInjector photosList = null; @@ -181,7 +182,7 @@ public class MultipleShareActivity // 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(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", photosList.size()) @@ -248,7 +249,7 @@ public class MultipleShareActivity @Override protected void onAuthCookieAcquired(String authCookie) { - application.getMWApi().setAuthCookie(authCookie); + mwApi.setAuthCookie(authCookie); Intent intent = getIntent(); if(intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { @@ -291,7 +292,7 @@ public class MultipleShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", photosList.size()) @@ -299,7 +300,7 @@ public class MultipleShareActivity .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) 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 3043e506d..0ac51cc8c 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 @@ -45,6 +45,7 @@ import fr.free.nrw.commons.modifications.ModificationsContentProvider; import fr.free.nrw.commons.modifications.ModifierSequence; import fr.free.nrw.commons.modifications.TemplateRemoveModifier; import fr.free.nrw.commons.mwapi.EventLog; +import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; import static fr.free.nrw.commons.upload.ExistingFileAsync.Result.DUPLICATE_PROCEED; @@ -66,6 +67,7 @@ public class ShareActivity private CategorizationFragment categorizationFragment; @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; private String source; private String mimeType; @@ -169,7 +171,7 @@ public class ShareActivity // 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(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", 1) @@ -191,7 +193,7 @@ public class ShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", 1) @@ -199,7 +201,7 @@ public class ShareActivity .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) @@ -210,8 +212,7 @@ public class ShareActivity @Override protected void onAuthCookieAcquired(String authCookie) { - application.getMWApi().setAuthCookie(authCookie); - + mwApi.setAuthCookie(authCookie); } @Override @@ -385,7 +386,7 @@ public class ShareActivity Timber.d("%s duplicate check: %s", mediaUri.toString(), result); duplicateCheckPassed = (result == DUPLICATE_PROCEED || result == NO_DUPLICATE); - }, application.getMWApi()); + }, mwApi); fileAsyncTask.execute(); } catch (IOException e) { Timber.d(e, "IO Exception: "); 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 fb1535dce..6b099f32c 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 @@ -48,6 +48,7 @@ public class UploadService extends HandlerService { public static final String EXTRA_CAMPAIGN = EXTRA_PREFIX + ".campaign"; @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; private NotificationManager notificationManager; private ContentProviderClient contributionsProviderClient; @@ -182,8 +183,6 @@ public class UploadService extends HandlerService { @SuppressLint("StringFormatInvalid") private void uploadContribution(Contribution contribution) { - MediaWikiApi api = application.getMWApi(); - InputStream file = null; String notificationTag = contribution.getLocalUri().toString(); @@ -222,7 +221,7 @@ public class UploadService extends HandlerService { filename = findUniqueFilename(filename); unfinishedUploads.add(filename); } - if (!api.validateLogin()) { + if (!mwApi.validateLogin()) { // Need to revalidate! if (application.revalidateAuthToken()) { Timber.d("Successfully revalidated token!"); @@ -240,7 +239,7 @@ public class UploadService extends HandlerService { getString(R.string.upload_progress_notification_title_finishing, contribution.getDisplayTitle()), contribution ); - UploadResult uploadResult = api.uploadFile(filename, file, contribution.getDataLength(), contribution.getPageContents(), contribution.getEditSummary(), notificationUpdater); + UploadResult uploadResult = mwApi.uploadFile(filename, file, contribution.getDataLength(), contribution.getPageContents(), contribution.getEditSummary(), notificationUpdater); Timber.d("Response is %s", uploadResult.toString()); @@ -249,7 +248,7 @@ public class UploadService extends HandlerService { String resultStatus = uploadResult.getResultStatus(); if (!resultStatus.equals("Success")) { showFailedNotification(contribution); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("source", contribution.getSource()) .param("multiple", contribution.getMultiple()) @@ -263,7 +262,7 @@ public class UploadService extends HandlerService { contribution.setDateUploaded(uploadResult.getDateUploaded()); contribution.save(); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) .param("username", application.getCurrentAccount().name) .param("source", contribution.getSource()) //FIXME .param("filename", contribution.getFilename()) @@ -304,7 +303,6 @@ public class UploadService extends HandlerService { } private String findUniqueFilename(String fileName) throws IOException { - MediaWikiApi api = application.getMWApi(); String sequenceFileName; for (int sequenceNumber = 1; true; sequenceNumber++) { if (sequenceNumber == 1) { @@ -320,7 +318,7 @@ public class UploadService extends HandlerService { sequenceFileName = regexMatcher.replaceAll("$1 " + sequenceNumber + "$2"); } } - if (!api.fileExistsWithName(sequenceFileName) + if (!mwApi.fileExistsWithName(sequenceFileName) && !unfinishedUploads.contains(sequenceFileName)) { break; } From cfe17cafa69d0cff866fe16966b45d14d1788d69 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 22:26:03 -0500 Subject: [PATCH 07/17] Moved other singletons over to being managed by Dagger --- .../free/nrw/commons/CommonsApplication.java | 50 +++---------------- .../free/nrw/commons/MediaWikiImageView.java | 10 ++-- .../category/CategoryContentProvider.java | 4 +- .../ContributionsContentProvider.java | 12 +++-- .../commons/di/CommonsApplicationModule.java | 29 +++++++++++ .../ModificationsContentProvider.java | 12 +++-- .../nrw/commons/nearby/NearbyActivity.java | 9 ++-- .../nrw/commons/nearby/NearbyController.java | 9 ++-- .../nrw/commons/upload/ShareActivity.java | 8 +-- 9 files changed, 69 insertions(+), 74 deletions(-) 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 0fd838cb6..c888660e1 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -9,7 +9,6 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.database.sqlite.SQLiteDatabase; import android.preference.PreferenceManager; -import android.support.v4.util.LruCache; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.stetho.Stetho; @@ -27,7 +26,6 @@ import javax.inject.Inject; import dagger.android.AndroidInjector; import dagger.android.DaggerApplication; import fr.free.nrw.commons.auth.AccountUtil; -import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.data.DBOpenHelper; @@ -35,9 +33,7 @@ import fr.free.nrw.commons.di.CommonsApplicationComponent; import fr.free.nrw.commons.di.CommonsApplicationModule; import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent; import fr.free.nrw.commons.modifications.ModifierSequence; -import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi; -import fr.free.nrw.commons.nearby.NearbyPlaces; import fr.free.nrw.commons.utils.FileUtils; import timber.log.Timber; @@ -54,6 +50,7 @@ public class CommonsApplication extends DaggerApplication { @Inject MediaWikiApi mediaWikiApi; @Inject AccountUtil accountUtil; + @Inject DBOpenHelper dbOpenHelper; private Account currentAccount = null; // Unlike a savings account... public static final String API_URL = "https://commons.wikimedia.org/w/api.php"; @@ -73,37 +70,8 @@ public class CommonsApplication extends DaggerApplication { public static final String FEEDBACK_EMAIL = "commons-app-android@googlegroups.com"; public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App (%s) Feedback"; - private LruCache thumbnailUrlCache = new LruCache<>(1024); - private CacheController cacheData = null; - private DBOpenHelper dbOpenHelper = null; - private NearbyPlaces nearbyPlaces = null; private CommonsApplicationComponent component; - public CacheController getCacheData() { - if (cacheData == null) { - cacheData = new CacheController(); - } - return cacheData; - } - - public LruCache getThumbnailUrlCache() { - return thumbnailUrlCache; - } - - public synchronized DBOpenHelper getDBOpenHelper() { - if (dbOpenHelper == null) { - dbOpenHelper = new DBOpenHelper(this); - } - return dbOpenHelper; - } - - public synchronized NearbyPlaces getNearbyPlaces() { - if (nearbyPlaces == null) { - nearbyPlaces = new NearbyPlaces(); - } - return nearbyPlaces; - } - @Override public void onCreate() { super.onCreate(); @@ -127,9 +95,6 @@ public class CommonsApplication extends DaggerApplication { System.setProperty("in.yuvi.http.fluent.PROGRESS_TRIGGER_THRESHOLD", "3.0"); Fresco.initialize(this); - - //For caching area -> categories - cacheData = new CacheController(); } @Override @@ -150,24 +115,24 @@ public class CommonsApplication extends DaggerApplication { * @return Account|null */ public Account getCurrentAccount() { - if(currentAccount == null) { + if (currentAccount == null) { AccountManager accountManager = AccountManager.get(this); Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); - if(allAccounts.length != 0) { + if (allAccounts.length != 0) { currentAccount = allAccounts[0]; } } return currentAccount; } - + public Boolean revalidateAuthToken() { AccountManager accountManager = AccountManager.get(this); Account curAccount = getCurrentAccount(); - - if(curAccount == null) { + + if (curAccount == null) { return false; // This should never happen } - + accountManager.invalidateAuthToken(accountUtil.accountType(), mediaWikiApi.getAuthCookie()); try { String authCookie = accountManager.blockingGetAuthToken(curAccount, "", false); @@ -218,7 +183,6 @@ public class CommonsApplication extends DaggerApplication { * Deletes all tables and re-creates them. */ public void updateAllDatabases() { - DBOpenHelper dbOpenHelper = getDBOpenHelper(); dbOpenHelper.getReadableDatabase().close(); SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); diff --git a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java index 5d7a4cc48..836793aff 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java @@ -4,6 +4,7 @@ import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.graphics.drawable.VectorDrawableCompat; +import android.support.v4.util.LruCache; import android.text.TextUtils; import android.util.AttributeSet; import android.widget.Toast; @@ -19,6 +20,8 @@ import timber.log.Timber; public class MediaWikiImageView extends SimpleDraweeView { @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; + @Inject LruCache thumbnailUrlCache; + private ThumbnailFetchTask currentThumbnailTask; public MediaWikiImageView(Context context) { @@ -44,8 +47,8 @@ public class MediaWikiImageView extends SimpleDraweeView { return; } - if (application.getThumbnailUrlCache().get(media.getFilename()) != null) { - setImageUrl(application.getThumbnailUrlCache().get(media.getFilename())); + if (thumbnailUrlCache.get(media.getFilename()) != null) { + setImageUrl(thumbnailUrlCache.get(media.getFilename())); } else { setImageUrl(null); currentThumbnailTask = new ThumbnailFetchTask(media, mwApi); @@ -91,8 +94,7 @@ public class MediaWikiImageView extends SimpleDraweeView { } else { // only cache meaningful thumbnails received from network. try { - CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); - app.getThumbnailUrlCache().put(media.getFilename(), result); + thumbnailUrlCache.put(media.getFilename(), result); } catch (NullPointerException npe) { Timber.e("error when adding pic to cache " + npe); 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 9d493b30c..e4aa4fe1f 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 @@ -40,13 +40,11 @@ public class CategoryContentProvider extends ContentProvider { } @Inject CommonsApplication application; - - private DBOpenHelper dbOpenHelper; + @Inject DBOpenHelper dbOpenHelper; @Override public boolean onCreate() { AndroidInjection.inject(this); - dbOpenHelper = application.getDBOpenHelper(); return false; } 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 59603f898..2ac0ad360 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 @@ -14,6 +14,7 @@ import javax.inject.Inject; import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; public class ContributionsContentProvider extends ContentProvider{ @@ -37,6 +38,7 @@ public class ContributionsContentProvider extends ContentProvider{ } @Inject CommonsApplication application; + @Inject DBOpenHelper dbOpenHelper; @Override public boolean onCreate() { @@ -51,7 +53,7 @@ public class ContributionsContentProvider extends ContentProvider{ int uriType = uriMatcher.match(uri); - SQLiteDatabase db = application.getDBOpenHelper().getReadableDatabase(); + SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor; switch(uriType) { @@ -85,7 +87,7 @@ public class ContributionsContentProvider extends ContentProvider{ @Override public Uri insert(@NonNull Uri uri, ContentValues contentValues) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); long id = 0; switch (uriType) { case CONTRIBUTIONS: @@ -103,7 +105,7 @@ public class ContributionsContentProvider extends ContentProvider{ int rows = 0; int uriType = uriMatcher.match(uri); - SQLiteDatabase db = application.getDBOpenHelper().getReadableDatabase(); + SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); switch(uriType) { case CONTRIBUTIONS_ID: @@ -124,7 +126,7 @@ public class ContributionsContentProvider extends ContentProvider{ public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { Timber.d("Hello, bulk insert! (ContributionsContentProvider)"); int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); sqlDB.beginTransaction(); switch (uriType) { case CONTRIBUTIONS: @@ -152,7 +154,7 @@ public class ContributionsContentProvider extends ContentProvider{ In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. */ int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); int rowsUpdated = 0; switch (uriType) { case CONTRIBUTIONS: 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 9af4e3853..019eec6a9 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,12 +1,17 @@ package fr.free.nrw.commons.di; +import android.support.v4.util.LruCache; + import javax.inject.Singleton; import dagger.Module; import dagger.Provides; import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.caching.CacheController; +import fr.free.nrw.commons.data.DBOpenHelper; import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi; +import fr.free.nrw.commons.nearby.NearbyPlaces; @Module public class CommonsApplicationModule { @@ -26,4 +31,28 @@ public class CommonsApplicationModule { public MediaWikiApi provideMediaWikiApi() { return new ApacheHttpClientMediaWikiApi(CommonsApplication.API_URL); } + + @Provides + @Singleton + public CacheController provideCacheController() { + return new CacheController(); + } + + @Provides + @Singleton + public DBOpenHelper provideDBOpenHelper(CommonsApplication application) { + return new DBOpenHelper(application); + } + + @Provides + @Singleton + public NearbyPlaces provideNearbyPlaces() { + return new NearbyPlaces(); + } + + @Provides + @Singleton + public LruCache provideLruCache() { + return new LruCache<>(1024); + } } 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 8b8d965e3..d3b0a3283 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 @@ -14,6 +14,7 @@ import javax.inject.Inject; import dagger.android.AndroidInjection; import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; public class ModificationsContentProvider extends ContentProvider{ @@ -37,6 +38,7 @@ public class ModificationsContentProvider extends ContentProvider{ } @Inject CommonsApplication application; + @Inject DBOpenHelper dbOpenHelper; @Override public boolean onCreate() { @@ -58,7 +60,7 @@ public class ModificationsContentProvider extends ContentProvider{ throw new IllegalArgumentException("Unknown URI" + uri); } - SQLiteDatabase db = application.getDBOpenHelper().getReadableDatabase(); + SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); @@ -74,7 +76,7 @@ public class ModificationsContentProvider extends ContentProvider{ @Override public Uri insert(@NonNull Uri uri, ContentValues contentValues) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); long id = 0; switch (uriType) { case MODIFICATIONS: @@ -90,7 +92,7 @@ public class ModificationsContentProvider extends ContentProvider{ @Override public int delete(@NonNull Uri uri, String s, String[] strings) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); switch (uriType) { case MODIFICATIONS_ID: String id = uri.getLastPathSegment(); @@ -108,7 +110,7 @@ public class ModificationsContentProvider extends ContentProvider{ public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { Timber.d("Hello, bulk insert! (ModificationsContentProvider)"); int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); sqlDB.beginTransaction(); switch (uriType) { case MODIFICATIONS: @@ -136,7 +138,7 @@ public class ModificationsContentProvider extends ContentProvider{ In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. */ int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = application.getDBOpenHelper().getWritableDatabase(); + SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); int rowsUpdated = 0; switch (uriType) { case MODIFICATIONS: diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java index 7e7d4f719..70bb38476 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java @@ -31,7 +31,6 @@ import javax.inject.Inject; import butterknife.BindView; import butterknife.ButterKnife; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.location.LocationServiceManager; @@ -43,7 +42,7 @@ public class NearbyActivity extends NavigationBaseActivity { @BindView(R.id.progressBar) ProgressBar progressBar; - @Inject CommonsApplication application; + @Inject NearbyPlaces nearbyPlaces; private boolean isMapViewActive = false; private static final int LOCATION_REQUEST = 1; @@ -94,7 +93,7 @@ public class NearbyActivity extends NavigationBaseActivity { locationManager = new LocationServiceManager(this); locationManager.registerLocationManager(); curLatLang = locationManager.getLatestLocation(); - nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(application)); + nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(nearbyPlaces)); nearbyAsyncTask.execute(); } @@ -233,7 +232,7 @@ public class NearbyActivity extends NavigationBaseActivity { } private void refreshView() { - nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(application)); + nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(nearbyPlaces)); nearbyAsyncTask.execute(); } @@ -262,7 +261,7 @@ public class NearbyActivity extends NavigationBaseActivity { @Override protected List doInBackground(Void... params) { - return nearbyController.loadAttractionsFromLocation(curLatLang, application); + return nearbyController.loadAttractionsFromLocation(curLatLang, NearbyActivity.this); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index 46ad80dad..619db6e0a 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.utils.UiUtils; @@ -27,11 +26,10 @@ import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween; public class NearbyController { private static final int MAX_RESULTS = 1000; + private final NearbyPlaces nearbyPlaces; - private final CommonsApplication application; - - public NearbyController(CommonsApplication application) { - this.application = application; + public NearbyController(NearbyPlaces nearbyPlaces) { + this.nearbyPlaces = nearbyPlaces; } /** @@ -45,7 +43,6 @@ public class NearbyController { if (curLatLng == null) { return Collections.emptyList(); } - NearbyPlaces nearbyPlaces = application.getNearbyPlaces(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); List places = prefs.getBoolean("useWikidata", true) ? nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage()) 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 0ac51cc8c..15aad438e 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 @@ -37,6 +37,7 @@ import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.auth.AuthenticatedActivity; +import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.category.CategorizationFragment; import fr.free.nrw.commons.category.OnCategoriesSaveHandler; import fr.free.nrw.commons.contributions.Contribution; @@ -68,6 +69,7 @@ public class ShareActivity @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; + @Inject CacheController cacheController; private String source; private String mimeType; @@ -137,7 +139,7 @@ public class ShareActivity if (!cacheFound) { //Has to be called after apiCall.request() - application.getCacheData().cacheCategory(); + cacheController.cacheCategory(); Timber.d("Cache the categories found"); } @@ -482,12 +484,12 @@ public class ShareActivity if (imageObj.imageCoordsExists) { double decLongitude = imageObj.getDecLongitude(); double decLatitude = imageObj.getDecLatitude(); - application.getCacheData().setQtPoint(decLongitude, decLatitude); + cacheController.setQtPoint(decLongitude, decLatitude); } MwVolleyApi apiCall = new MwVolleyApi(application); - List displayCatList = application.getCacheData().findCategory(); + List displayCatList = cacheController.findCategory(); boolean catListEmpty = displayCatList.isEmpty(); // If no categories found in cache, call MediaWiki API to match image coords with nearby Commons categories From 388f5883018c5319896cd367929393cfa6d80f4f Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 22:54:44 -0500 Subject: [PATCH 08/17] Correctly configured injection for fragments and services. --- .../fr/free/nrw/commons/HandlerService.java | 5 ++- .../auth/WikiAccountAuthenticatorService.java | 5 ++- .../di/CommonsApplicationComponent.java | 6 +-- .../nrw/commons/di/FragmentBuilderModule.java | 45 +++++++++++++++++++ .../nrw/commons/di/ServiceBuilderModule.java | 26 +++++++++++ .../commons/nearby/NearbyListFragment.java | 3 +- .../commons/nearby/NoPermissionsFragment.java | 3 +- .../upload/MultipleUploadListFragment.java | 3 +- .../commons/upload/SingleUploadFragment.java | 3 +- .../nrw/commons/upload/UploadService.java | 2 - 10 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java create mode 100644 app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java diff --git a/app/src/main/java/fr/free/nrw/commons/HandlerService.java b/app/src/main/java/fr/free/nrw/commons/HandlerService.java index 61fa1f1c5..69a1ea4b9 100644 --- a/app/src/main/java/fr/free/nrw/commons/HandlerService.java +++ b/app/src/main/java/fr/free/nrw/commons/HandlerService.java @@ -1,6 +1,5 @@ package fr.free.nrw.commons; -import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Handler; @@ -9,7 +8,9 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; -public abstract class HandlerService extends Service { +import dagger.android.DaggerService; + +public abstract class HandlerService extends DaggerService { private volatile Looper threadLooper; private volatile ServiceHandler threadHandler; private String serviceName; diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java index 617f974b2..0df6b6b35 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java @@ -7,13 +7,15 @@ import android.os.IBinder; import javax.inject.Inject; +import dagger.android.DaggerService; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.mwapi.MediaWikiApi; -public class WikiAccountAuthenticatorService extends Service { +public class WikiAccountAuthenticatorService extends DaggerService { @Inject MediaWikiApi mwApi; @Inject AccountUtil accountUtil; + private WikiAccountAuthenticator wikiAccountAuthenticator = null; @Override @@ -22,7 +24,6 @@ public class WikiAccountAuthenticatorService extends Service { return null; } - ((CommonsApplication)getApplication()).injector().inject(this); if (wikiAccountAuthenticator == null) { wikiAccountAuthenticator = new WikiAccountAuthenticator(this, accountUtil, mwApi); } diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index ede3d6a20..c4e79c343 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -19,15 +19,13 @@ import fr.free.nrw.commons.upload.UploadService; AndroidInjectionModule.class, AndroidSupportInjectionModule.class, ActivityBuilderModule.class, + FragmentBuilderModule.class, + ServiceBuilderModule.class, ContentProviderBuilderModule.class }) public interface CommonsApplicationComponent extends AndroidInjector { void inject(CommonsApplication application); - void inject(WikiAccountAuthenticatorService service); - - void inject(UploadService service); - void inject(ContributionsSyncAdapter syncAdapter); void inject(ModificationsSyncAdapter syncAdapter); diff --git a/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java new file mode 100644 index 000000000..ddb91fb3d --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java @@ -0,0 +1,45 @@ +package fr.free.nrw.commons.di; + +import dagger.Module; +import dagger.android.ContributesAndroidInjector; +import fr.free.nrw.commons.category.CategorizationFragment; +import fr.free.nrw.commons.contributions.ContributionsListFragment; +import fr.free.nrw.commons.media.MediaDetailFragment; +import fr.free.nrw.commons.media.MediaDetailPagerFragment; +import fr.free.nrw.commons.nearby.NearbyListFragment; +import fr.free.nrw.commons.nearby.NoPermissionsFragment; +import fr.free.nrw.commons.settings.SettingsFragment; +import fr.free.nrw.commons.upload.MultipleUploadListFragment; +import fr.free.nrw.commons.upload.SingleUploadFragment; + +@Module +public abstract class FragmentBuilderModule { + + @ContributesAndroidInjector + abstract CategorizationFragment bindCategorizationFragment(); + + @ContributesAndroidInjector + abstract ContributionsListFragment bindContributionsListFragment(); + + @ContributesAndroidInjector + abstract MediaDetailFragment bindMediaDetailFragment(); + + @ContributesAndroidInjector + abstract MediaDetailPagerFragment bindMediaDetailPagerFragment(); + + @ContributesAndroidInjector + abstract NearbyListFragment bindNearbyListFragment(); + + @ContributesAndroidInjector + abstract NoPermissionsFragment bindNoPermissionsFragment(); + + @ContributesAndroidInjector + abstract SettingsFragment bindSettingsFragment(); + + @ContributesAndroidInjector + abstract MultipleUploadListFragment bindMultipleUploadListFragment(); + + @ContributesAndroidInjector + abstract SingleUploadFragment bindSingleUploadFragment(); + +} diff --git a/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java new file mode 100644 index 000000000..3d3bc7712 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java @@ -0,0 +1,26 @@ +package fr.free.nrw.commons.di; + +import dagger.Module; +import dagger.android.ContributesAndroidInjector; +import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; +import fr.free.nrw.commons.category.CategorizationFragment; +import fr.free.nrw.commons.contributions.ContributionsListFragment; +import fr.free.nrw.commons.media.MediaDetailFragment; +import fr.free.nrw.commons.media.MediaDetailPagerFragment; +import fr.free.nrw.commons.nearby.NearbyListFragment; +import fr.free.nrw.commons.nearby.NoPermissionsFragment; +import fr.free.nrw.commons.settings.SettingsFragment; +import fr.free.nrw.commons.upload.MultipleUploadListFragment; +import fr.free.nrw.commons.upload.SingleUploadFragment; +import fr.free.nrw.commons.upload.UploadService; + +@Module +public abstract class ServiceBuilderModule { + + @ContributesAndroidInjector + abstract UploadService bindUploadService(); + + @ContributesAndroidInjector + abstract WikiAccountAuthenticatorService bindWikiAccountAuthenticatorService(); + +} diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java index 00b8a2840..83aebcf4f 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java @@ -17,12 +17,13 @@ import java.lang.reflect.Type; import java.util.Collections; import java.util.List; +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.R; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.utils.UriDeserializer; import timber.log.Timber; -public class NearbyListFragment extends Fragment { +public class NearbyListFragment extends DaggerFragment { private static final Type LIST_TYPE = new TypeToken>() { }.getType(); private static final Type CUR_LAT_LNG_TYPE = new TypeToken() { diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java index 5065a7d93..ba9a8de7f 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java @@ -7,13 +7,14 @@ import android.view.View; import android.view.ViewGroup; import butterknife.ButterKnife; +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.R; import timber.log.Timber; /** * Tells user that Nearby Places cannot be displayed if location permissions are denied */ -public class NoPermissionsFragment extends Fragment { +public class NoPermissionsFragment extends DaggerFragment { public NoPermissionsFragment() { } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java index 629d41639..b81b2e7af 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java @@ -28,11 +28,12 @@ import android.widget.TextView; import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; import com.facebook.drawee.view.SimpleDraweeView; +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.R; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.media.MediaDetailPagerFragment; -public class MultipleUploadListFragment extends Fragment { +public class MultipleUploadListFragment extends DaggerFragment { public interface OnMultipleUploadInitiatedHandler { void OnMultipleUploadInitiated(); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java index 161054053..bf0ecf9ae 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java @@ -34,12 +34,13 @@ import butterknife.ButterKnife; import butterknife.OnClick; import butterknife.OnItemSelected; import butterknife.OnTouch; +import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.settings.Prefs; import timber.log.Timber; -public class SingleUploadFragment extends Fragment { +public class SingleUploadFragment extends DaggerFragment { private SharedPreferences prefs; private String license; 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 6b099f32c..c51f055cb 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 @@ -117,8 +117,6 @@ public class UploadService extends HandlerService { @Override public void onCreate() { - ((CommonsApplication)getApplicationContext()).injector().inject(this); - super.onCreate(); notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); From d0a85dbd8287680ba6f963502354499b1a633913 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 25 Aug 2017 23:08:50 -0500 Subject: [PATCH 09/17] Moved single-use code out of Utils over to where it's actually used. --- .../free/nrw/commons/CommonsApplication.java | 6 - .../java/fr/free/nrw/commons/LicenseList.java | 34 +++- .../main/java/fr/free/nrw/commons/Utils.java | 191 ------------------ .../commons/contributions/Contribution.java | 25 ++- .../ContributionsListFragment.java | 8 +- .../ContributionsSyncAdapter.java | 11 +- .../ModificationsSyncAdapter.java | 7 +- .../mwapi/ApacheHttpClientMediaWikiApi.java | 16 +- .../nrw/commons/ui/widget/HtmlTextView.java | 24 ++- .../nrw/commons/upload/ShareActivity.java | 43 +++- .../commons/upload/SingleUploadFragment.java | 21 +- .../nrw/commons/upload/UploadController.java | 15 +- 12 files changed, 184 insertions(+), 217 deletions(-) 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 c888660e1..87a5a6f5c 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -144,12 +144,6 @@ public class CommonsApplication extends DaggerApplication { } } - public boolean deviceHasCamera() { - PackageManager pm = getPackageManager(); - return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) || - pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); - } - public void clearApplicationData(Context context) { File cacheDirectory = context.getCacheDir(); File applicationDirectory = new File(cacheDirectory.getParent()); diff --git a/app/src/main/java/fr/free/nrw/commons/LicenseList.java b/app/src/main/java/fr/free/nrw/commons/LicenseList.java index 28d5b3f34..7c91620ff 100644 --- a/app/src/main/java/fr/free/nrw/commons/LicenseList.java +++ b/app/src/main/java/fr/free/nrw/commons/LicenseList.java @@ -5,7 +5,9 @@ import android.content.res.Resources; import android.support.annotation.Nullable; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Locale; @@ -21,7 +23,7 @@ public class LicenseList { public LicenseList(Activity activity) { res = activity.getResources(); XmlPullParser parser = res.getXml(R.xml.wikimedia_licenses); - while (Utils.xmlFastForward(parser, XMLNS_LICENSE, "license")) { + while (xmlFastForward(parser, XMLNS_LICENSE, "license")) { String id = parser.getAttributeValue(null, "id"); String template = parser.getAttributeValue(null, "template"); String url = parser.getAttributeValue(null, "url"); @@ -76,4 +78,34 @@ public class LicenseList { } return template; } + + /** + * Fast-forward an XmlPullParser to the next instance of the given element + * in the input stream (namespaced). + * + * @param parser + * @param namespace + * @param element + * @return true on match, false on failure + */ + private boolean xmlFastForward(XmlPullParser parser, String namespace, String element) { + try { + while (parser.next() != XmlPullParser.END_DOCUMENT) { + if (parser.getEventType() == XmlPullParser.START_TAG && + parser.getNamespace().equals(namespace) && + parser.getName().equals(element)) { + // We found it! + return true; + } + } + return false; + } catch (XmlPullParserException e) { + e.printStackTrace(); + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + } \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/Utils.java b/app/src/main/java/fr/free/nrw/commons/Utils.java index a3fcb746c..1a5b6f078 100644 --- a/app/src/main/java/fr/free/nrw/commons/Utils.java +++ b/app/src/main/java/fr/free/nrw/commons/Utils.java @@ -1,26 +1,10 @@ package fr.free.nrw.commons; -import android.content.Context; -import android.os.Build; -import android.preference.PreferenceManager; -import android.text.Html; -import android.text.Spanned; - import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; -import org.w3c.dom.Node; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; import java.io.UnsupportedEncodingException; -import java.math.BigInteger; import java.net.URLEncoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -29,70 +13,10 @@ import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - import fr.free.nrw.commons.settings.Prefs; -import timber.log.Timber; - public class Utils { - // Get SHA1 of file from input stream - public static String getSHA1(InputStream is) { - - MessageDigest digest; - try { - digest = MessageDigest.getInstance("SHA1"); - } catch (NoSuchAlgorithmException e) { - Timber.e(e, "Exception while getting Digest"); - return ""; - } - - byte[] buffer = new byte[8192]; - int read; - try { - while ((read = is.read(buffer)) > 0) { - digest.update(buffer, 0, read); - } - byte[] md5sum = digest.digest(); - BigInteger bigInt = new BigInteger(1, md5sum); - String output = bigInt.toString(16); - // Fill to 40 chars - output = String.format("%40s", output).replace(' ', '0'); - Timber.i("File SHA1: %s", output); - - return output; - } catch (IOException e) { - Timber.e(e, "IO Exception"); - return ""; - } finally { - try { - is.close(); - } catch (IOException e) { - Timber.e(e, "Exception on closing MD5 input stream"); - } - } - } - - /** Fix Html.fromHtml is deprecated problem - * @param source provided Html string - * @return returned Spanned of appropriate method according to version check - * */ - public static Spanned fromHtml(String source) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY); - } else { - //noinspection deprecation - return Html.fromHtml(source); - } - } - /** * Strips localization symbols from a string. * Removes the suffix after "@" and quotes. @@ -109,49 +33,12 @@ public class Utils { } } - public static Date parseMWDate(String mwDate) { - SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC - try { - return isoFormat.parse(mwDate); - } catch (ParseException e) { - throw new RuntimeException(e); - } - } - - public static String toMWDate(Date date) { - SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC - isoFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - return isoFormat.format(date); - } - public static String makeThumbBaseUrl(String filename) { String name = new PageTitle(filename).getPrefixedText(); String sha = new String(Hex.encodeHex(DigestUtils.md5(name))); return String.format("%s/%s/%s/%s", CommonsApplication.IMAGE_URL_BASE, sha.substring(0, 1), sha.substring(0, 2), urlEncode(name)); } - public static String getStringFromDOM(Node dom) { - Transformer transformer = null; - try { - transformer = TransformerFactory.newInstance().newTransformer(); - } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - StringWriter outputStream = new StringWriter(); - DOMSource domSource = new DOMSource(dom); - StreamResult strResult = new StreamResult(outputStream); - - try { - transformer.transform(domSource, strResult); - } catch (TransformerException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return outputStream.toString(); - } - public static String urlEncode(String url) { try { return URLEncoder.encode(url, "utf-8"); @@ -160,39 +47,10 @@ public class Utils { } } - public static long countBytes(InputStream stream) throws IOException { - long count = 0; - BufferedInputStream bis = new BufferedInputStream(stream); - while (bis.read() != -1) { - count++; - } - return count; - } - public static String capitalize(String string) { return string.substring(0, 1).toUpperCase(Locale.getDefault()) + string.substring(1); } - public static String licenseTemplateFor(String license) { - switch (license) { - case Prefs.Licenses.CC_BY_3: - return "{{self|cc-by-3.0}}"; - case Prefs.Licenses.CC_BY_4: - return "{{self|cc-by-4.0}}"; - case Prefs.Licenses.CC_BY_SA_3: - return "{{self|cc-by-sa-3.0}}"; - case Prefs.Licenses.CC_BY_SA_4: - return "{{self|cc-by-sa-4.0}}"; - case Prefs.Licenses.CC0: - return "{{self|cc-zero}}"; - case Prefs.Licenses.CC_BY: - return "{{self|cc-by-3.0}}"; - case Prefs.Licenses.CC_BY_SA: - return "{{self|cc-by-sa-3.0}}"; - } - throw new RuntimeException("Unrecognized license value: " + license); - } - public static int licenseNameFor(String license) { switch (license) { case Prefs.Licenses.CC_BY_3: @@ -213,51 +71,6 @@ public class Utils { throw new RuntimeException("Unrecognized license value: " + license); } - public static String licenseUrlFor(String license) { - switch (license) { - case Prefs.Licenses.CC_BY_3: - return "https://creativecommons.org/licenses/by/3.0/"; - case Prefs.Licenses.CC_BY_4: - return "https://creativecommons.org/licenses/by/4.0/"; - case Prefs.Licenses.CC_BY_SA_3: - return "https://creativecommons.org/licenses/by-sa/3.0/"; - case Prefs.Licenses.CC_BY_SA_4: - return "https://creativecommons.org/licenses/by-sa/4.0/"; - case Prefs.Licenses.CC0: - return "https://creativecommons.org/publicdomain/zero/1.0/"; - } - throw new RuntimeException("Unrecognized license value: " + license); - } - - /** - * Fast-forward an XmlPullParser to the next instance of the given element - * in the input stream (namespaced). - * - * @param parser - * @param namespace - * @param element - * @return true on match, false on failure - */ - public static boolean xmlFastForward(XmlPullParser parser, String namespace, String element) { - try { - while (parser.next() != XmlPullParser.END_DOCUMENT) { - if (parser.getEventType() == XmlPullParser.START_TAG && - parser.getNamespace().equals(namespace) && - parser.getName().equals(element)) { - // We found it! - return true; - } - } - return false; - } catch (XmlPullParserException e) { - e.printStackTrace(); - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - public static String fixExtension(String title, String extension) { Pattern jpegPattern = Pattern.compile("\\.jpeg$", Pattern.CASE_INSENSITIVE); @@ -272,8 +85,4 @@ public class Utils { return title; } - public static boolean isNullOrWhiteSpace(String value) { - return value == null || value.trim().isEmpty(); - } - } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java index 983f361a4..9d47bcc7f 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java @@ -7,6 +7,7 @@ import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.Parcel; import android.os.RemoteException; +import android.support.annotation.NonNull; import android.text.TextUtils; import java.text.SimpleDateFormat; @@ -16,7 +17,6 @@ import java.util.Locale; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Media; -import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.settings.Prefs; public class Contribution extends Media { @@ -149,7 +149,7 @@ public class Contribution extends Media { } buffer.append("== {{int:license-header}} ==\n") - .append(Utils.licenseTemplateFor(getLicense())).append("\n\n") + .append(licenseTemplateFor(getLicense())).append("\n\n") .append("{{Uploaded from Mobile|platform=Android|version=").append(BuildConfig.VERSION_NAME).append("}}\n") .append(getTrackingTemplates()); return buffer.toString(); @@ -377,4 +377,25 @@ public class Contribution extends Media { } } } + + @NonNull + private String licenseTemplateFor(String license) { + switch (license) { + case Prefs.Licenses.CC_BY_3: + return "{{self|cc-by-3.0}}"; + case Prefs.Licenses.CC_BY_4: + return "{{self|cc-by-4.0}}"; + case Prefs.Licenses.CC_BY_SA_3: + return "{{self|cc-by-sa-3.0}}"; + case Prefs.Licenses.CC_BY_SA_4: + return "{{self|cc-by-sa-4.0}}"; + case Prefs.Licenses.CC0: + return "{{self|cc-zero}}"; + case Prefs.Licenses.CC_BY: + return "{{self|cc-by-3.0}}"; + case Prefs.Licenses.CC_BY_SA: + return "{{self|cc-by-sa-3.0}}"; + } + throw new RuntimeException("Unrecognized license value: " + license); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index 364448723..b6e36e31f 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -196,11 +196,17 @@ public class ContributionsListFragment extends DaggerFragment { menu.clear(); // See http://stackoverflow.com/a/8495697/17865 inflater.inflate(R.menu.fragment_contributions_list, menu); - if (!application.deviceHasCamera()) { + if (!deviceHasCamera()) { menu.findItem(R.id.menu_from_camera).setEnabled(false); } } + public boolean deviceHasCamera() { + PackageManager pm = getContext().getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) || + pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 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 c354a995c..bd54c8568 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 @@ -13,9 +13,12 @@ import android.os.RemoteException; import android.text.TextUtils; import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Locale; +import java.util.TimeZone; import javax.inject.Inject; @@ -130,7 +133,13 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { done = true; } } - prefs.edit().putString("lastSyncTimestamp", Utils.toMWDate(curTime)).apply(); + prefs.edit().putString("lastSyncTimestamp", toMWDate(curTime)).apply(); Timber.d("Oh hai, everyone! Look, a kitty!"); } + + private String toMWDate(Date date) { + SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC + isoFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return isoFormat.format(date); + } } 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 5bd7c9ee3..1e886f225 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 @@ -17,7 +17,6 @@ import java.io.IOException; import javax.inject.Inject; import fr.free.nrw.commons.CommonsApplication; -import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.ContributionsContentProvider; import fr.free.nrw.commons.mwapi.MediaWikiApi; @@ -59,7 +58,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { return; } - if (Utils.isNullOrWhiteSpace(authCookie)) { + if (isNullOrWhiteSpace(authCookie)) { Timber.d("Could not authenticate :("); return; } @@ -133,4 +132,8 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { } } } + + private boolean isNullOrWhiteSpace(String value) { + return value == null || value.trim().isEmpty(); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index 7af42b0fe..e7efd4cba 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -25,6 +25,8 @@ import org.mediawiki.api.MWApi; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -33,7 +35,6 @@ import java.util.Locale; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.PageTitle; -import fr.free.nrw.commons.Utils; import in.yuvi.http.fluent.Http; import io.reactivex.Observable; import io.reactivex.Single; @@ -337,7 +338,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { logEvents.add(new LogEventResult.LogEvent( image.getString("@pageid"), image.getString("@title"), - Utils.parseMWDate(image.getString("@timestamp"))) + parseMWDate(image.getString("@timestamp"))) ); } return logEvents; @@ -399,7 +400,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { String errorCode = result.getString("/api/error/@code"); return new UploadResult(resultStatus, errorCode); } else { - Date dateUploaded = Utils.parseMWDate(result.getString("/api/upload/imageinfo/@timestamp")); + Date dateUploaded = parseMWDate(result.getString("/api/upload/imageinfo/@timestamp")); String canonicalFilename = "File:" + result.getString("/api/upload/@filename").replace("_", " "); // Title vs Filename String imageUrl = result.getString("/api/upload/imageinfo/@url"); return new UploadResult(resultStatus, dateUploaded, canonicalFilename, imageUrl); @@ -425,4 +426,13 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { return Integer.parseInt(uploadCount); }); } + + private Date parseMWDate(String mwDate) { + SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC + try { + return isoFormat.parse(mwDate); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/ui/widget/HtmlTextView.java b/app/src/main/java/fr/free/nrw/commons/ui/widget/HtmlTextView.java index 5afa5cac3..e7f5eaeeb 100644 --- a/app/src/main/java/fr/free/nrw/commons/ui/widget/HtmlTextView.java +++ b/app/src/main/java/fr/free/nrw/commons/ui/widget/HtmlTextView.java @@ -1,12 +1,13 @@ package fr.free.nrw.commons.ui.widget; import android.content.Context; +import android.os.Build; import android.support.v7.widget.AppCompatTextView; +import android.text.Html; +import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.util.AttributeSet; -import fr.free.nrw.commons.Utils; - /** * An {@link AppCompatTextView} which formats the text to HTML displayable text and makes any * links clickable. @@ -17,10 +18,25 @@ public class HtmlTextView extends AppCompatTextView { super(context, attrs); setMovementMethod(LinkMovementMethod.getInstance()); - setText(Utils.fromHtml(getText().toString())); + setText(fromHtml(getText().toString())); } public void setHtmlText(String newText) { - setText(Utils.fromHtml(newText)); + setText(fromHtml(newText)); + } + + /** + * Fix Html.fromHtml is deprecated problem + * + * @param source provided Html string + * @return returned Spanned of appropriate method according to version check + */ + private static Spanned fromHtml(String source) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY); + } else { + //noinspection deprecation + return Html.fromHtml(source); + } } } 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 15aad438e..88082ad6e 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 @@ -27,6 +27,9 @@ import com.facebook.drawee.view.SimpleDraweeView; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Date; import java.util.List; @@ -35,7 +38,6 @@ import javax.inject.Inject; import butterknife.ButterKnife; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.auth.AuthenticatedActivity; import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.category.CategorizationFragment; @@ -380,7 +382,7 @@ public class ShareActivity try { InputStream inputStream = getContentResolver().openInputStream(mediaUri); Timber.d("Input stream created from %s", mediaUri.toString()); - String fileSHA1 = Utils.getSHA1(inputStream); + String fileSHA1 = getSHA1(inputStream); Timber.d("File SHA1 is: %s", fileSHA1); ExistingFileAsync fileAsyncTask = @@ -536,4 +538,41 @@ public class ShareActivity } return super.onOptionsItemSelected(item); } + + // Get SHA1 of file from input stream + private String getSHA1(InputStream is) { + + MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA1"); + } catch (NoSuchAlgorithmException e) { + Timber.e(e, "Exception while getting Digest"); + return ""; + } + + byte[] buffer = new byte[8192]; + int read; + try { + while ((read = is.read(buffer)) > 0) { + digest.update(buffer, 0, read); + } + byte[] md5sum = digest.digest(); + BigInteger bigInt = new BigInteger(1, md5sum); + String output = bigInt.toString(16); + // Fill to 40 chars + output = String.format("%40s", output).replace(' ', '0'); + Timber.i("File SHA1: %s", output); + + return output; + } catch (IOException e) { + Timber.e(e, "IO Exception"); + return ""; + } finally { + try { + is.close(); + } catch (IOException e) { + Timber.e(e, "Exception on closing MD5 input stream"); + } + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java index bf0ecf9ae..f2827e832 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java @@ -8,7 +8,7 @@ import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; +import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.TextWatcher; @@ -184,7 +184,7 @@ public class SingleUploadFragment extends DaggerFragment { if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); - intent.setData(Uri.parse(Utils.licenseUrlFor(license))); + intent.setData(Uri.parse(licenseUrlFor(license))); startActivity(intent); return true; } else { @@ -280,6 +280,23 @@ public class SingleUploadFragment extends DaggerFragment { } } + @NonNull + private String licenseUrlFor(String license) { + switch (license) { + case Prefs.Licenses.CC_BY_3: + return "https://creativecommons.org/licenses/by/3.0/"; + case Prefs.Licenses.CC_BY_4: + return "https://creativecommons.org/licenses/by/4.0/"; + case Prefs.Licenses.CC_BY_SA_3: + return "https://creativecommons.org/licenses/by-sa/3.0/"; + case Prefs.Licenses.CC_BY_SA_4: + return "https://creativecommons.org/licenses/by-sa/4.0/"; + case Prefs.Licenses.CC0: + return "https://creativecommons.org/publicdomain/zero/1.0/"; + } + throw new RuntimeException("Unrecognized license value: " + license); + } + private class TitleTextWatcher implements TextWatcher { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java index e3cdd56dc..04deee553 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java @@ -13,13 +13,14 @@ import android.preference.PreferenceManager; import android.provider.MediaStore; import android.text.TextUtils; +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; import java.util.Date; import java.util.concurrent.Executors; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; -import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.settings.Prefs; import timber.log.Timber; @@ -109,7 +110,7 @@ public class UploadController { .getLength(); if(length == -1) { // Let us find out the long way! - length = Utils.countBytes(application.getContentResolver() + length = countBytes(application.getContentResolver() .openInputStream(contribution.getLocalUri())); } contribution.setDataLength(length); @@ -165,4 +166,14 @@ public class UploadController { } }.executeOnExecutor(Executors.newFixedThreadPool(1)); // TODO remove this by using a sensible thread handling strategy } + + + private long countBytes(InputStream stream) throws IOException { + long count = 0; + BufferedInputStream bis = new BufferedInputStream(stream); + while (bis.read() != -1) { + count++; + } + return count; + } } From 9c0cbe7ad58d0a6f8d9eb8943611c365ee11fdcf Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sat, 9 Sep 2017 14:03:00 -0500 Subject: [PATCH 10/17] Further reduce code calling back to the CommonsApplication by pulling out a SessionManager to manage our current account. --- .../free/nrw/commons/CommonsApplication.java | 92 ++----------------- .../free/nrw/commons/MediaWikiImageView.java | 1 - .../fr/free/nrw/commons/auth/AccountUtil.java | 13 +-- .../commons/auth/AuthenticatedActivity.java | 6 +- .../free/nrw/commons/auth/LoginActivity.java | 10 +- .../fr/free/nrw/commons/auth/LoginTask.java | 11 ++- .../free/nrw/commons/auth/SessionManager.java | 71 ++++++++++++++ .../free/nrw/commons/auth/SignupActivity.java | 12 +-- .../category/CategoryContentProvider.java | 2 - .../contributions/ContributionsActivity.java | 60 ++++++------ .../ContributionsContentProvider.java | 2 - .../ContributionsListFragment.java | 6 -- .../commons/di/CommonsApplicationModule.java | 14 ++- .../media/MediaDetailPagerFragment.java | 32 ++++--- .../ModificationsContentProvider.java | 2 - .../fr/free/nrw/commons/mwapi/EventLog.java | 10 +- .../fr/free/nrw/commons/mwapi/LogBuilder.java | 9 +- .../commons/settings/SettingsFragment.java | 8 +- .../commons/theme/NavigationBaseActivity.java | 23 +++-- .../free/nrw/commons/upload/GPSExtractor.java | 20 ++-- .../commons/upload/MultipleShareActivity.java | 71 +++++++------- .../free/nrw/commons/upload/MwVolleyApi.java | 10 +- .../nrw/commons/upload/ShareActivity.java | 31 +++---- .../nrw/commons/upload/UploadController.java | 36 +++++--- .../nrw/commons/upload/UploadService.java | 15 +-- 25 files changed, 273 insertions(+), 294 deletions(-) create mode 100644 app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java 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 f922eb077..40ef35bc0 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -1,11 +1,5 @@ package fr.free.nrw.commons; -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AccountManagerCallback; -import android.accounts.AccountManagerFuture; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; import android.content.Context; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; @@ -20,13 +14,12 @@ import org.acra.ReportingInteractionMode; import org.acra.annotation.ReportsCrashes; import java.io.File; -import java.io.IOException; import javax.inject.Inject; import dagger.android.AndroidInjector; import dagger.android.DaggerApplication; -import fr.free.nrw.commons.auth.AccountUtil; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.data.DBOpenHelper; @@ -37,6 +30,8 @@ import fr.free.nrw.commons.modifications.ModifierSequence; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.theme.NavigationBaseActivity; import fr.free.nrw.commons.utils.FileUtils; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; import timber.log.Timber; // TODO: Use ProGuard to rip out reporting when publishing @@ -51,10 +46,9 @@ import timber.log.Timber; public class CommonsApplication extends DaggerApplication { @Inject MediaWikiApi mediaWikiApi; - @Inject AccountUtil accountUtil; + @Inject SessionManager sessionManager; @Inject DBOpenHelper dbOpenHelper; - private Account currentAccount = null; // Unlike a savings account... public static final String API_URL = "https://commons.wikimedia.org/w/api.php"; public static final String IMAGE_URL_BASE = "https://upload.wikimedia.org/wikipedia/commons"; public static final String HOME_URL = "https://commons.wikimedia.org/wiki/"; @@ -113,39 +107,6 @@ public class CommonsApplication extends DaggerApplication { return component; } - /** - * @return Account|null - */ - public Account getCurrentAccount() { - if (currentAccount == null) { - AccountManager accountManager = AccountManager.get(this); - Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); - if (allAccounts.length != 0) { - currentAccount = allAccounts[0]; - } - } - return currentAccount; - } - - public Boolean revalidateAuthToken() { - AccountManager accountManager = AccountManager.get(this); - Account curAccount = getCurrentAccount(); - - if (curAccount == null) { - return false; // This should never happen - } - - accountManager.invalidateAuthToken(accountUtil.accountType(), mediaWikiApi.getAuthCookie()); - try { - String authCookie = accountManager.blockingGetAuthToken(curAccount, "", false); - mediaWikiApi.setAuthCookie(authCookie); - return true; - } catch (OperationCanceledException | NullPointerException | IOException | AuthenticatorException e) { - e.printStackTrace(); - return false; - } - } - public void clearApplicationData(Context context, NavigationBaseActivity.LogoutListener logoutListener) { File cacheDirectory = context.getCacheDir(); File applicationDirectory = new File(cacheDirectory.getParent()); @@ -158,36 +119,10 @@ public class CommonsApplication extends DaggerApplication { } } - AccountManager accountManager = AccountManager.get(this); - Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); - - AccountManagerCallback amCallback = new AccountManagerCallback() { - - private int index = 0; - - void setIndex(int index) { - this.index = index; - } - - int getIndex() { - return index; - } - - @Override - public void run(AccountManagerFuture accountManagerFuture) { - setIndex(getIndex() + 1); - - try { - if (accountManagerFuture != null) { - if (accountManagerFuture.getResult()) { - Timber.d("Account removed successfully."); - } - } - } catch (OperationCanceledException | IOException | AuthenticatorException e) { - e.printStackTrace(); - } - - if (getIndex() == allAccounts.length) { + sessionManager.clearAllAccounts() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(() -> { Timber.d("All accounts have been removed"); //TODO: fix preference manager PreferenceManager.getDefaultSharedPreferences(CommonsApplication.this).edit().clear().commit(); @@ -197,22 +132,15 @@ public class CommonsApplication extends DaggerApplication { context.getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().clear().commit(); preferences.edit().putBoolean("firstrun", false).apply(); updateAllDatabases(); - currentAccount = null; logoutListener.onLogoutComplete(); - } - } - }; - - for (Account account : allAccounts) { - accountManager.removeAccount(account, amCallback, null); - } + }); } /** * Deletes all tables and re-creates them. */ - public void updateAllDatabases() { + private void updateAllDatabases() { dbOpenHelper.getReadableDatabase().close(); SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); diff --git a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java index 836793aff..7ffe498b8 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaWikiImageView.java @@ -18,7 +18,6 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; public class MediaWikiImageView extends SimpleDraweeView { - @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; @Inject LruCache thumbnailUrlCache; 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 557746f9b..8790a1606 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 @@ -4,24 +4,21 @@ import android.accounts.Account; import android.accounts.AccountAuthenticatorResponse; import android.accounts.AccountManager; import android.content.ContentResolver; +import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import javax.inject.Inject; - -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.contributions.ContributionsContentProvider; import fr.free.nrw.commons.modifications.ModificationsContentProvider; import timber.log.Timber; public class AccountUtil { - private final CommonsApplication application; + private Context context; - @Inject - public AccountUtil(CommonsApplication application) { - this.application = application; + public AccountUtil(Context context) { + this.context = context; } public void createAccount(@Nullable AccountAuthenticatorResponse response, @@ -60,7 +57,7 @@ public class AccountUtil { } private AccountManager accountManager() { - return AccountManager.get(application); + return AccountManager.get(context); } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index e17380578..4bb265be9 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -7,8 +7,6 @@ import android.os.Bundle; import javax.inject.Inject; -import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.theme.NavigationBaseActivity; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -17,8 +15,8 @@ import timber.log.Timber; public abstract class AuthenticatedActivity extends NavigationBaseActivity { - @Inject CommonsApplication app; @Inject AccountUtil accountUtil; + @Inject SessionManager sessionManager; private String authCookie; @@ -59,7 +57,7 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { return; } AccountManager accountManager = AccountManager.get(this); - Account curAccount = app.getCurrentAccount(); + Account curAccount = sessionManager.getCurrentAccount(); if(curAccount == null) { addAccount(accountManager); } else { diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index 96367950a..6570cadbd 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -19,11 +19,9 @@ import javax.inject.Inject; import dagger.android.AndroidInjection; import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.PageTitle; import fr.free.nrw.commons.R; import fr.free.nrw.commons.WelcomeActivity; - -import fr.free.nrw.commons.PageTitle; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; @@ -36,9 +34,9 @@ public class LoginActivity extends AccountAuthenticatorActivity { public static final String PARAM_USERNAME = "fr.free.nrw.commons.login.username"; - @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; @Inject AccountUtil accountUtil; + @Inject SessionManager sessionManager; private SharedPreferences prefs = null; @@ -114,7 +112,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { WelcomeActivity.startYourself(this); prefs.edit().putBoolean("firstrun", false).apply(); } - if (application.getCurrentAccount() != null) { + if (sessionManager.getCurrentAccount() != null) { startMainActivity(); } } @@ -147,7 +145,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { canonicializeUsername(usernameEdit.getText().toString()), passwordEdit.getText().toString(), twoFactorEdit.getText().toString(), - accountUtil, application, mwApi + accountUtil, this, mwApi ); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java index 7c63551eb..5011cf752 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java @@ -3,6 +3,7 @@ package fr.free.nrw.commons.auth; import android.accounts.AccountAuthenticatorResponse; import android.accounts.AccountManager; import android.app.ProgressDialog; +import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; @@ -21,16 +22,18 @@ class LoginTask extends AsyncTask { private String password; private String twoFactorCode = ""; private AccountUtil accountUtil; - private CommonsApplication app; + private Context context; private MediaWikiApi mwApi; - public LoginTask(LoginActivity loginActivity, String username, String password, String twoFactorCode, AccountUtil accountUtil, CommonsApplication application, MediaWikiApi mwApi) { + public LoginTask(LoginActivity loginActivity, String username, String password, + String twoFactorCode, AccountUtil accountUtil, + Context context, MediaWikiApi mwApi) { this.loginActivity = loginActivity; this.username = username; this.password = password; this.twoFactorCode = twoFactorCode; this.accountUtil = accountUtil; - this.app = application; + this.context = context; this.mwApi = mwApi; } @@ -64,7 +67,7 @@ class LoginTask extends AsyncTask { super.onPostExecute(result); Timber.d("Login done!"); - EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, app, mwApi) + EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, context, mwApi) .param("username", username) .param("result", result) .log(); diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java b/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java new file mode 100644 index 000000000..d838cda56 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java @@ -0,0 +1,71 @@ +package fr.free.nrw.commons.auth; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.content.Context; + +import java.io.IOException; + +import fr.free.nrw.commons.mwapi.MediaWikiApi; +import io.reactivex.Completable; +import io.reactivex.Observable; + +/** + * Manage the current logged in user session. + */ +public class SessionManager { + private final Context context; + private final AccountUtil accountUtil; + private final MediaWikiApi mediaWikiApi; + private Account currentAccount; // Unlike a savings account... ;-) + + public SessionManager(Context context, AccountUtil accountUtil, MediaWikiApi mediaWikiApi) { + this.context = context; + this.accountUtil = accountUtil; + this.mediaWikiApi = mediaWikiApi; + this.currentAccount = null; + } + + /** + * @return Account|null + */ + public Account getCurrentAccount() { + if (currentAccount == null) { + AccountManager accountManager = AccountManager.get(context); + Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); + if (allAccounts.length != 0) { + currentAccount = allAccounts[0]; + } + } + return currentAccount; + } + + public Boolean revalidateAuthToken() { + AccountManager accountManager = AccountManager.get(context); + Account curAccount = getCurrentAccount(); + + if (curAccount == null) { + return false; // This should never happen + } + + accountManager.invalidateAuthToken(accountUtil.accountType(), mediaWikiApi.getAuthCookie()); + try { + String authCookie = accountManager.blockingGetAuthToken(curAccount, "", false); + mediaWikiApi.setAuthCookie(authCookie); + return true; + } catch (OperationCanceledException | NullPointerException | IOException | AuthenticatorException e) { + e.printStackTrace(); + return false; + } + } + + public Completable clearAllAccounts() { + AccountManager accountManager = AccountManager.get(context); + Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); + return Completable.fromObservable(Observable.fromArray(allAccounts) + .map(a -> accountManager.removeAccount(a, null, null).getResult())) + .doOnComplete(() -> currentAccount = null); + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java index 9a27a116c..a30c6a013 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java @@ -6,16 +6,11 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; -import javax.inject.Inject; - -import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.theme.BaseActivity; import timber.log.Timber; public class SignupActivity extends BaseActivity { - @Inject CommonsApplication application; private WebView webView; @Override @@ -41,11 +36,8 @@ public class SignupActivity extends BaseActivity { //Signup success, so clear cookies, notify user, and load LoginActivity again Timber.d("Overriding URL %s", url); - Toast toast = Toast.makeText( - application, - "Account created!", - Toast.LENGTH_LONG - ); + Toast toast = Toast.makeText(SignupActivity.this, + "Account created!", Toast.LENGTH_LONG); toast.show(); // terminate on task completion. finish(); 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 e4aa4fe1f..4c597dcce 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 @@ -13,7 +13,6 @@ import android.text.TextUtils; import javax.inject.Inject; import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; @@ -39,7 +38,6 @@ public class CategoryContentProvider extends ContentProvider { return Uri.parse(BASE_URI.toString() + "/" + id); } - @Inject CommonsApplication application; @Inject DBOpenHelper dbOpenHelper; @Override 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 f4a70410a..3ea00778b 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 @@ -27,12 +27,11 @@ import java.util.ArrayList; import javax.inject.Inject; import butterknife.ButterKnife; -import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.auth.AuthenticatedActivity; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.media.MediaDetailPagerFragment; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.settings.Prefs; @@ -42,16 +41,15 @@ import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; import timber.log.Timber; -public class ContributionsActivity - extends AuthenticatedActivity - implements LoaderManager.LoaderCallbacks, - AdapterView.OnItemClickListener, - MediaDetailPagerFragment.MediaDetailProvider, - FragmentManager.OnBackStackChangedListener, - ContributionsListFragment.SourceRefresher { +public class ContributionsActivity extends AuthenticatedActivity + implements LoaderManager.LoaderCallbacks, + AdapterView.OnItemClickListener, + MediaDetailPagerFragment.MediaDetailProvider, + FragmentManager.OnBackStackChangedListener, + ContributionsListFragment.SourceRefresher { - @Inject CommonsApplication application; @Inject MediaWikiApi mediaWikiApi; + @Inject SessionManager sessionManager; private Cursor allContributions; private ContributionsListFragment contributionsList; @@ -77,7 +75,7 @@ public class ContributionsActivity private ServiceConnection uploadServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder binder) { - uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService(); + uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder) binder).getService(); isUploadServiceConnected = true; } @@ -93,7 +91,7 @@ public class ContributionsActivity compositeDisposable.clear(); getSupportFragmentManager().removeOnBackStackChangedListener(this); super.onDestroy(); - if(isUploadServiceConnected) { + if (isUploadServiceConnected) { unbindService(uploadServiceConnection); } } @@ -103,9 +101,9 @@ public class ContributionsActivity super.onResume(); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); boolean isSettingsChanged = - sharedPreferences.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,false); + sharedPreferences.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,false); + editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); editor.apply(); if (isSettingsChanged) { refreshSource(); @@ -115,7 +113,7 @@ public class ContributionsActivity @Override protected void onAuthCookieAcquired(String authCookie) { // Do a sync everytime we get here! - ContentResolver.requestSync(application.getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle()); + ContentResolver.requestSync(sessionManager.getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle()); Intent uploadServiceIntent = new Intent(this, UploadService.class); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); startService(uploadServiceIntent); @@ -134,12 +132,12 @@ public class ContributionsActivity // Activity can call methods in the fragment by acquiring a // reference to the Fragment from FragmentManager, using findFragmentById() - contributionsList = (ContributionsListFragment)getSupportFragmentManager() + contributionsList = (ContributionsListFragment) getSupportFragmentManager() .findFragmentById(R.id.contributionsListFragment); getSupportFragmentManager().addOnBackStackChangedListener(this); if (savedInstanceState != null) { - mediaDetails = (MediaDetailPagerFragment)getSupportFragmentManager() + mediaDetails = (MediaDetailPagerFragment) getSupportFragmentManager() .findFragmentById(R.id.contributionsFragmentContainer); } requestAuthToken(); @@ -153,11 +151,13 @@ public class ContributionsActivity outState.putBoolean("mediaDetailsVisible", (mediaDetails != null && mediaDetails.isVisible())); } - /** Replace whatever is in the current contributionsFragmentContainer view with mediaDetailPagerFragment, - / and preserve previous state in back stack. - / Called when user selects a contribution. */ + /** + * Replace whatever is in the current contributionsFragmentContainer view with mediaDetailPagerFragment, + * / and preserve previous state in back stack. + * / Called when user selects a contribution. + */ private void showDetail(int i) { - if(mediaDetails == null ||!mediaDetails.isVisible()) { + if (mediaDetails == null || !mediaDetails.isVisible()) { mediaDetails = new MediaDetailPagerFragment(); this.getSupportFragmentManager() .beginTransaction() @@ -172,7 +172,7 @@ public class ContributionsActivity public void retryUpload(int i) { allContributions.moveToPosition(i); Contribution c = Contribution.fromCursor(allContributions); - if(c.getState() == Contribution.STATE_FAILED) { + if (c.getState() == Contribution.STATE_FAILED) { uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c); Timber.d("Restarting for %s", c.toContentValues()); } else { @@ -183,7 +183,7 @@ public class ContributionsActivity public void deleteUpload(int i) { allContributions.moveToPosition(i); Contribution c = Contribution.fromCursor(allContributions); - if(c.getState() == Contribution.STATE_FAILED) { + if (c.getState() == Contribution.STATE_FAILED) { Timber.d("Deleting failed contrib %s", c.toContentValues()); c.setContentProviderClient(getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY)); c.delete(); @@ -194,9 +194,9 @@ public class ContributionsActivity @Override public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { + switch (item.getItemId()) { case android.R.id.home: - if(mediaDetails.isVisible()) { + if (mediaDetails.isVisible()) { getSupportFragmentManager().popBackStack(); } return true; @@ -232,11 +232,11 @@ public class ContributionsActivity @Override public void onLoadFinished(Loader cursorLoader, Cursor cursor) { - if(contributionsList.getAdapter() == null) { + if (contributionsList.getAdapter() == null) { contributionsList .setAdapter(new ContributionsListAdapter(getApplicationContext(), cursor, 0)); } else { - ((CursorAdapter)contributionsList.getAdapter()).swapCursor(cursor); + ((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor); } setUploadCount(); @@ -256,14 +256,14 @@ public class ContributionsActivity if (contributionsList.getAdapter() == null) { // not yet ready to return data return null; - } else { + } else { return Contribution.fromCursor((Cursor) contributionsList.getAdapter().getItem(i)); } } @Override public int getTotalMediaCount() { - if(contributionsList.getAdapter() == null) { + if (contributionsList.getAdapter() == null) { return 0; } return contributionsList.getAdapter().getCount(); @@ -272,7 +272,7 @@ public class ContributionsActivity private void setUploadCount() { compositeDisposable.add( mediaWikiApi - .getUploadCount(application.getCurrentAccount().name) + .getUploadCount(sessionManager.getCurrentAccount().name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( 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 2ac0ad360..ec88b6299 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 @@ -13,7 +13,6 @@ import android.text.TextUtils; import javax.inject.Inject; import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; @@ -37,7 +36,6 @@ public class ContributionsContentProvider extends ContentProvider{ return Uri.parse(BASE_URI.toString() + "/" + id); } - @Inject CommonsApplication application; @Inject DBOpenHelper dbOpenHelper; @Override diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index b6e36e31f..d244f970c 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -7,7 +7,6 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; @@ -21,12 +20,9 @@ import android.widget.GridView; import android.widget.ListAdapter; import android.widget.TextView; -import javax.inject.Inject; - import butterknife.BindView; import butterknife.ButterKnife; import dagger.android.support.DaggerFragment; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.nearby.NearbyActivity; import timber.log.Timber; @@ -44,8 +40,6 @@ public class ContributionsListFragment extends DaggerFragment { @BindView(R.id.waitingMessage) TextView waitingMessage; @BindView(R.id.emptyMessage) TextView emptyMessage; - @Inject CommonsApplication application; - private ContributionController controller; @Override 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 019eec6a9..c146748d9 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 @@ -7,6 +7,8 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; import fr.free.nrw.commons.CommonsApplication; +import fr.free.nrw.commons.auth.AccountUtil; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.data.DBOpenHelper; import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; @@ -22,8 +24,14 @@ public class CommonsApplicationModule { } @Provides - public CommonsApplication providesCommonsApplication() { - return application; + public AccountUtil providesAccountUtil() { + return new AccountUtil(application); + } + + @Provides + @Singleton + public SessionManager providesSessionManager(AccountUtil accountUtil, MediaWikiApi mediaWikiApi) { + return new SessionManager(application, accountUtil, mediaWikiApi); } @Provides @@ -40,7 +48,7 @@ public class CommonsApplicationModule { @Provides @Singleton - public DBOpenHelper provideDBOpenHelper(CommonsApplication application) { + public DBOpenHelper provideDBOpenHelper() { return new DBOpenHelper(application); } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index a2f7eae2d..94f640240 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -33,6 +33,7 @@ import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.mwapi.EventLog; @@ -52,8 +53,8 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage void unregisterDataSetObserver(DataSetObserver observer); } - @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; + @Inject SessionManager sessionManager; private ViewPager pager; private Boolean editable; @@ -85,7 +86,7 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage @Override public int getCount() { - return ((MediaDetailProvider)getActivity()).getTotalMediaCount(); + return ((MediaDetailProvider) getActivity()).getTotalMediaCount(); } } @@ -131,13 +132,13 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage @Override public boolean onOptionsItemSelected(MenuItem item) { - MediaDetailProvider provider = (MediaDetailProvider)getActivity(); + MediaDetailProvider provider = (MediaDetailProvider) getActivity(); Media m = provider.getMediaAtPosition(pager.getCurrentItem()); - switch(item.getItemId()) { + switch (item.getItemId()) { case R.id.menu_share_current_image: // Share - this is just logs it, intent set in onCreateOptionsMenu, around line 252 - EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT, getContext().getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("filename", m.getFilename()) .log(); return true; @@ -154,12 +155,12 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage return true; case R.id.menu_retry_current_image: // Retry - ((ContributionsActivity)getActivity()).retryUpload(pager.getCurrentItem()); + ((ContributionsActivity) getActivity()).retryUpload(pager.getCurrentItem()); getActivity().getSupportFragmentManager().popBackStack(); return true; case R.id.menu_cancel_current_image: // todo: delete image - ((ContributionsActivity)getActivity()).deleteUpload(pager.getCurrentItem()); + ((ContributionsActivity) getActivity()).deleteUpload(pager.getCurrentItem()); getActivity().getSupportFragmentManager().popBackStack(); return true; default: @@ -175,7 +176,7 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage */ private void downloadMedia(Media m) { String imageUrl = m.getImageUrl(), - fileName = m.getFilename(); + fileName = m.getFilename(); // Strip 'File:' from beginning of filename, we really shouldn't store it fileName = fileName.replaceFirst("^File:", ""); Uri imageUri = Uri.parse(imageUrl); @@ -190,13 +191,16 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage req.allowScanningByMediaScanner(); req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && + !(ContextCompat.checkSelfPermission(getContext(), + Manifest.permission.READ_EXTERNAL_STORAGE) == + PackageManager.PERMISSION_GRANTED)) { Snackbar.make(getView(), R.string.storage_permission_rationale, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.ok, view -> ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1)).show(); } else { - final DownloadManager manager = (DownloadManager)getActivity().getSystemService(Context.DOWNLOAD_SERVICE); + final DownloadManager manager = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(req); } } @@ -207,7 +211,7 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage menu.clear(); // see http://stackoverflow.com/a/8495697/17865 inflater.inflate(R.menu.fragment_image_detail, menu); if (pager != null) { - MediaDetailProvider provider = (MediaDetailProvider)getActivity(); + MediaDetailProvider provider = (MediaDetailProvider) getActivity(); Media m = provider.getMediaAtPosition(pager.getCurrentItem()); if (m != null) { // Enable default set of actions, then re-enable different set of actions only if it is a failed contrib @@ -230,8 +234,8 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage } if (m instanceof Contribution) { - Contribution c = (Contribution)m; - switch(c.getState()) { + Contribution c = (Contribution) m; + switch (c.getState()) { case Contribution.STATE_FAILED: menu.findItem(R.id.menu_retry_current_image).setEnabled(true).setVisible(true); menu.findItem(R.id.menu_cancel_current_image).setEnabled(true).setVisible(true); 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 d3b0a3283..8bd3049a8 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 @@ -13,7 +13,6 @@ import android.text.TextUtils; import javax.inject.Inject; import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; @@ -37,7 +36,6 @@ public class ModificationsContentProvider extends ContentProvider{ return Uri.parse(BASE_URI.toString() + "/" + id); } - @Inject CommonsApplication application; @Inject DBOpenHelper dbOpenHelper; @Override diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java b/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java index d5b0a106c..1a867cd00 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java @@ -1,8 +1,8 @@ package fr.free.nrw.commons.mwapi; +import android.content.Context; import android.os.Build; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Utils; public class EventLog { @@ -16,14 +16,14 @@ public class EventLog { } } - private static LogBuilder schema(String schema, long revision, CommonsApplication application, MediaWikiApi mwApi) { - return new LogBuilder(schema, revision, application, mwApi); + private static LogBuilder schema(String schema, long revision, Context context, MediaWikiApi mwApi) { + return new LogBuilder(schema, revision, context, mwApi); } - public static LogBuilder schema(Object[] scid, CommonsApplication application, MediaWikiApi mwApi) { + public static LogBuilder schema(Object[] scid, Context context, MediaWikiApi mwApi) { if (scid.length != 2) { throw new IllegalArgumentException("Needs an object array with schema as first param and revision as second"); } - return schema((String) scid[0], (Long) scid[1], application, mwApi); + return schema((String) scid[0], (Long) scid[1], context, mwApi); } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java b/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java index 4de72236b..f15a576ed 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java @@ -1,5 +1,6 @@ package fr.free.nrw.commons.mwapi; +import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Build; @@ -18,17 +19,17 @@ import fr.free.nrw.commons.settings.Prefs; @SuppressWarnings("WeakerAccess") public class LogBuilder { - private final CommonsApplication application; + private final Context context; private final MediaWikiApi mwApi; private final JSONObject data; private final long rev; private final String schema; - LogBuilder(String schema, long revision, CommonsApplication application, MediaWikiApi mwApi) { + LogBuilder(String schema, long revision, Context context, MediaWikiApi mwApi) { this.data = new JSONObject(); this.schema = schema; this.rev = revision; - this.application = application; + this.context = context; this.mwApi = mwApi; } @@ -61,7 +62,7 @@ public class LogBuilder { // Use *only* for tracking the user preference change for EventLogging // Attempting to use anywhere else will cause kitten explosions public void log(boolean force) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(application); + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); if (!settings.getBoolean(Prefs.TRACKING_ENABLED, true) && !force) { return; // User has disabled tracking } diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index 730ff2fed..4527d1761 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -2,25 +2,19 @@ package fr.free.nrw.commons.settings; import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; -import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; -import javax.inject.Inject; - import dagger.android.AndroidInjection; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; public class SettingsFragment extends PreferenceFragment { - @Inject CommonsApplication application; @Override public void onAttach(Context context) { @@ -53,7 +47,7 @@ public class SettingsFragment extends PreferenceFragment { final EditTextPreference uploadLimit = (EditTextPreference) findPreference("uploads"); final SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(application); + .getDefaultSharedPreferences(getActivity().getApplicationContext()); int uploads = sharedPref.getInt(Prefs.UPLOADS_SHOWING, 100); uploadLimit.setText(uploads + ""); uploadLimit.setSummary(uploads + ""); diff --git a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java index 4b4579d50..d256e4c21 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java @@ -120,18 +120,17 @@ public class NavigationBaseActivity extends BaseActivity new AlertDialog.Builder(this) .setMessage(R.string.logout_verification) .setCancelable(false) - .setPositiveButton(R.string.yes, (dialog, which) -> { - ((CommonsApplication) getApplicationContext()) - .clearApplicationData(NavigationBaseActivity.this, () -> { - Timber.d("Logout complete callback received."); - Intent nearbyIntent = new Intent( - NavigationBaseActivity.this, LoginActivity.class); - nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(nearbyIntent); - finish(); - }); - }) + .setPositiveButton(R.string.yes, (dialog, which) -> + ((CommonsApplication) getApplicationContext()) + .clearApplicationData(NavigationBaseActivity.this, () -> { + Timber.d("Logout complete callback received."); + Intent nearbyIntent = new Intent( + NavigationBaseActivity.this, LoginActivity.class); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(nearbyIntent); + finish(); + })) .setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel()) .show(); return true; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java index 39e8d4c48..77bd18703 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java @@ -16,7 +16,6 @@ import android.support.annotation.RequiresApi; import java.io.FileDescriptor; import java.io.IOException; -import fr.free.nrw.commons.CommonsApplication; import timber.log.Timber; /** @@ -26,7 +25,7 @@ import timber.log.Timber; */ public class GPSExtractor { - private final CommonsApplication application; + private final Context context; private ExifInterface exif; private double decLatitude; private double decLongitude; @@ -39,30 +38,30 @@ public class GPSExtractor { /** * Construct from the file descriptor of the image (only for API 24 or newer). * @param fileDescriptor the file descriptor of the image - * @param application the application + * @param context the context */ @RequiresApi(24) - public GPSExtractor(@NonNull FileDescriptor fileDescriptor, CommonsApplication application) { + public GPSExtractor(@NonNull FileDescriptor fileDescriptor, Context context) { + this.context = context; try { exif = new ExifInterface(fileDescriptor); } catch (IOException | IllegalArgumentException e) { Timber.w(e); } - this.application = application; } /** * Construct from the file path of the image. * @param path file path of the image - * @param application the application + * @param context the context */ - public GPSExtractor(@NonNull String path, CommonsApplication application) { + public GPSExtractor(@NonNull String path, Context context) { try { exif = new ExifInterface(path); } catch (IOException | IllegalArgumentException e) { Timber.w(e); } - this.application = application; + this.context = context; } /** @@ -71,7 +70,7 @@ public class GPSExtractor { */ private boolean gpsPreferenceEnabled() { SharedPreferences sharedPref - = PreferenceManager.getDefaultSharedPreferences(application); + = PreferenceManager.getDefaultSharedPreferences(context); boolean gpsPref = sharedPref.getBoolean("allowGps", false); Timber.d("Gps pref set to: %b", gpsPref); return gpsPref; @@ -81,8 +80,7 @@ public class GPSExtractor { * Registers a LocationManager to listen for current location */ protected void registerLocationManager() { - locationManager = (LocationManager) application - .getSystemService(Context.LOCATION_SERVICE); + locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); String provider = locationManager.getBestProvider(criteria, true); myLocationListener = new MyLocationListener(); 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 87adac0e6..dfbacf469 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 @@ -31,6 +31,7 @@ import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.auth.AuthenticatedActivity; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.category.CategorizationFragment; import fr.free.nrw.commons.category.OnCategoriesSaveHandler; import fr.free.nrw.commons.contributions.Contribution; @@ -43,15 +44,15 @@ import fr.free.nrw.commons.mwapi.EventLog; import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; -public class MultipleShareActivity - extends AuthenticatedActivity - implements MediaDetailPagerFragment.MediaDetailProvider, - AdapterView.OnItemClickListener, - FragmentManager.OnBackStackChangedListener, - MultipleUploadListFragment.OnMultipleUploadInitiatedHandler, +public class MultipleShareActivity extends AuthenticatedActivity + implements MediaDetailPagerFragment.MediaDetailProvider, + AdapterView.OnItemClickListener, + FragmentManager.OnBackStackChangedListener, + MultipleUploadListFragment.OnMultipleUploadInitiatedHandler, OnCategoriesSaveHandler { - @Inject CommonsApplication application; + @Inject MediaWikiApi mwApi; + @Inject SessionManager sessionManager; private ArrayList photosList = null; @@ -68,7 +69,7 @@ public class MultipleShareActivity @Override public int getTotalMediaCount() { - if(photosList == null) { + if (photosList == null) { return 0; } return photosList.size(); @@ -76,7 +77,7 @@ public class MultipleShareActivity @Override public void notifyDatasetChanged() { - if(uploadsList != null) { + if (uploadsList != null) { uploadsList.notifyDatasetChanged(); } } @@ -129,7 +130,7 @@ public class MultipleShareActivity dialog.setTitle(getResources().getQuantityString(R.plurals.starting_multiple_uploads, photosList.size(), photosList.size())); dialog.show(); - for(int i = 0; i < photosList.size(); i++) { + for (int i = 0; i < photosList.size(); i++) { Contribution up = photosList.get(i); final int uploadCount = i + 1; // Goddamn Java @@ -137,11 +138,7 @@ public class MultipleShareActivity dialog.setProgress(uploadCount); if (uploadCount == photosList.size()) { dialog.dismiss(); - Toast startingToast = Toast.makeText( - application, - R.string.uploading_started, - Toast.LENGTH_LONG - ); + Toast startingToast = Toast.makeText(this, R.string.uploading_started, Toast.LENGTH_LONG); startingToast.show(); } }); @@ -150,7 +147,7 @@ public class MultipleShareActivity uploadsList.setImageOnlyMode(true); categorizationFragment = (CategorizationFragment) getSupportFragmentManager().findFragmentByTag("categorization"); - if(categorizationFragment == null) { + if (categorizationFragment == null) { categorizationFragment = new CategorizationFragment(); } // FIXME: Stops the keyboard from being shown 'stale' while moving out of this fragment into the next @@ -167,9 +164,9 @@ public class MultipleShareActivity @Override public void onCategoriesSave(List categories) { - if(categories.size() > 0) { - ContentProviderClient client = getContentResolver().acquireContentProviderClient(ModificationsContentProvider.AUTHORITY); - for(Contribution contribution: photosList) { + if (categories.size() > 0) { + ContentProviderClient client = getContentResolver().acquireContentProviderClient(ModificationsContentProvider.AUTHORITY); + for (Contribution contribution : photosList) { ModifierSequence categoriesSequence = new ModifierSequence(contribution.getContentUri()); categoriesSequence.queueModifier(new CategoryModifier(categories.toArray(new String[]{}))); @@ -181,9 +178,9 @@ public class MultipleShareActivity } // 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(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", photosList.size()) .param("source", Contribution.SOURCE_EXTERNAL) @@ -194,9 +191,9 @@ public class MultipleShareActivity @Override public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { + switch (item.getItemId()) { case android.R.id.home: - if(mediaDetails.isVisible()) { + if (mediaDetails.isVisible()) { getSupportFragmentManager().popBackStack(); } return true; @@ -207,13 +204,13 @@ public class MultipleShareActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - uploadController = new UploadController(application); + uploadController = new UploadController(sessionManager, this); setContentView(R.layout.activity_multiple_uploads); ButterKnife.bind(this); initDrawer(); - if(savedInstanceState != null) { + if (savedInstanceState != null) { photosList = savedInstanceState.getParcelableArrayList("uploadsList"); } @@ -229,7 +226,7 @@ public class MultipleShareActivity } private void showDetail(int i) { - if(mediaDetails == null ||!mediaDetails.isVisible()) { + if (mediaDetails == null || !mediaDetails.isVisible()) { mediaDetails = new MediaDetailPagerFragment(true); getSupportFragmentManager() .beginTransaction() @@ -252,11 +249,11 @@ public class MultipleShareActivity mwApi.setAuthCookie(authCookie); Intent intent = getIntent(); - if(intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { - if(photosList == null) { + if (intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { + if (photosList == null) { photosList = new ArrayList<>(); ArrayList urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); - for(int i=0; i < urisList.size(); i++) { + for (int i = 0; i < urisList.size(); i++) { Contribution up = new Contribution(); Uri uri = urisList.get(i); up.setLocalUri(uri); @@ -269,8 +266,8 @@ public class MultipleShareActivity } uploadsList = (MultipleUploadListFragment) getSupportFragmentManager().findFragmentByTag("uploadsList"); - if(uploadsList == null) { - uploadsList = new MultipleUploadListFragment(); + if (uploadsList == null) { + uploadsList = new MultipleUploadListFragment(); getSupportFragmentManager() .beginTransaction() .add(R.id.uploadsFragmentContainer, uploadsList, "uploadsList") @@ -291,17 +288,17 @@ public class MultipleShareActivity @Override public void onBackPressed() { super.onBackPressed(); - if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + if (categorizationFragment != null && categorizationFragment.isVisible()) { + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", photosList.size()) .param("source", Contribution.SOURCE_EXTERNAL) .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) .param("result", "cancelled") diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java b/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java index 4b774ba68..f4cf5eecb 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MwVolleyApi.java @@ -1,5 +1,6 @@ package fr.free.nrw.commons.upload; +import android.content.Context; import android.net.Uri; import com.android.volley.Cache; @@ -20,7 +21,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import fr.free.nrw.commons.CommonsApplication; import timber.log.Timber; /** @@ -37,11 +37,11 @@ public class MwVolleyApi { private static List categoryList; private static final String MWURL = "https://commons.wikimedia.org/"; - private final CommonsApplication application; + private final Context context; - public MwVolleyApi(CommonsApplication application) { + public MwVolleyApi(Context context) { + this.context = context; categorySet = new HashSet<>(); - this.application = application; } public static List getGpsCat() { @@ -95,7 +95,7 @@ public class MwVolleyApi { private synchronized RequestQueue getQueue() { if (REQUEST_QUEUE == null) { - REQUEST_QUEUE = Volley.newRequestQueue(application); + REQUEST_QUEUE = Volley.newRequestQueue(context); } return REQUEST_QUEUE; } 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 88082ad6e..9e381a436 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 @@ -39,6 +39,7 @@ import butterknife.ButterKnife; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.auth.AuthenticatedActivity; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.caching.CacheController; import fr.free.nrw.commons.category.CategorizationFragment; import fr.free.nrw.commons.category.OnCategoriesSaveHandler; @@ -69,9 +70,9 @@ public class ShareActivity private static final int REQUEST_PERM_ON_SUBMIT_STORAGE = 4; private CategorizationFragment categorizationFragment; - @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; @Inject CacheController cacheController; + @Inject SessionManager sessionManager; private String source; private String mimeType; @@ -132,11 +133,7 @@ public class ShareActivity private void uploadBegins() { getFileMetadata(locationPermitted); - Toast startingToast = Toast.makeText( - application, - R.string.uploading_started, - Toast.LENGTH_LONG - ); + Toast startingToast = Toast.makeText(this, R.string.uploading_started, Toast.LENGTH_LONG); startingToast.show(); if (!cacheFound) { @@ -173,10 +170,10 @@ public class ShareActivity // 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(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! + ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", 1) .param("source", contribution.getSource()) @@ -197,16 +194,16 @@ public class ShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", 1) .param("source", contribution.getSource()) .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) .param("result", "cancelled") @@ -229,7 +226,7 @@ public class ShareActivity @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - uploadController = new UploadController(application); + uploadController = new UploadController(sessionManager, this); setContentView(R.layout.activity_share); ButterKnife.bind(this); initBack(); @@ -454,12 +451,12 @@ public class ShareActivity = getContentResolver().openFileDescriptor(mediaUri, "r"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (descriptor != null) { - imageObj = new GPSExtractor(descriptor.getFileDescriptor(), application); + imageObj = new GPSExtractor(descriptor.getFileDescriptor(), this); } } else { String filePath = getPathOfMediaOrCopy(); if (filePath != null) { - imageObj = new GPSExtractor(filePath, application); + imageObj = new GPSExtractor(filePath, this); } } } @@ -489,7 +486,7 @@ public class ShareActivity cacheController.setQtPoint(decLongitude, decLatitude); } - MwVolleyApi apiCall = new MwVolleyApi(application); + MwVolleyApi apiCall = new MwVolleyApi(this); List displayCatList = cacheController.findCategory(); boolean catListEmpty = displayCatList.isEmpty(); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java index 04deee553..55ecf1dd9 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java @@ -1,6 +1,7 @@ package fr.free.nrw.commons.upload; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; @@ -21,20 +22,23 @@ import java.util.concurrent.Executors; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.settings.Prefs; import timber.log.Timber; public class UploadController { private UploadService uploadService; - private final CommonsApplication application; + private SessionManager sessionManager; + private Context context; public interface ContributionUploadProgress { void onUploadStarted(Contribution contribution); } - public UploadController(CommonsApplication application) { - this.application = application; + public UploadController(SessionManager sessionManager, Context context) { + this.sessionManager = sessionManager; + this.context = context; } private boolean isUploadServiceConnected; @@ -53,15 +57,15 @@ public class UploadController { }; public void prepareService() { - Intent uploadServiceIntent = new Intent(application, UploadService.class); + Intent uploadServiceIntent = new Intent(context, UploadService.class); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); - application.startService(uploadServiceIntent); - application.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); + context.startService(uploadServiceIntent); + context.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); } public void cleanup() { if(isUploadServiceConnected) { - application.unbindService(uploadServiceConnection); + context.unbindService(uploadServiceConnection); } } @@ -69,7 +73,9 @@ public class UploadController { Contribution contribution; //TODO: Modify this to include coords - contribution = new Contribution(mediaUri, null, title, description, -1, null, null, application.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY, decimalCoords); + contribution = new Contribution(mediaUri, null, title, description, -1, + null, null, sessionManager.getCurrentAccount().name, + CommonsApplication.DEFAULT_EDIT_SUMMARY, decimalCoords); contribution.setTag("mimeType", mimeType); contribution.setSource(source); @@ -79,12 +85,11 @@ public class UploadController { } public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) { - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(application); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); //Set creator, desc, and license if(TextUtils.isEmpty(contribution.getCreator())) { - contribution.setCreator(application.getCurrentAccount().name); + contribution.setCreator(sessionManager.getCurrentAccount().name); } if(contribution.getDescription() == null) { @@ -103,14 +108,15 @@ public class UploadController { @Override protected Contribution doInBackground(Void... voids /* stare into you */) { long length; + ContentResolver contentResolver = context.getContentResolver(); try { if(contribution.getDataLength() <= 0) { - length = application.getContentResolver() + length = contentResolver .openAssetFileDescriptor(contribution.getLocalUri(), "r") .getLength(); if(length == -1) { // Let us find out the long way! - length = countBytes(application.getContentResolver() + length = countBytes(contentResolver .openInputStream(contribution.getLocalUri())); } contribution.setDataLength(length); @@ -127,7 +133,7 @@ public class UploadController { Boolean imagePrefix = false; if (mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) { - mimeType = application.getContentResolver().getType(contribution.getLocalUri()); + mimeType = contentResolver.getType(contribution.getLocalUri()); } if (mimeType != null) { @@ -138,7 +144,7 @@ public class UploadController { if (imagePrefix && contribution.getDateCreated() == null) { Timber.d("local uri " + contribution.getLocalUri()); - Cursor cursor = application.getContentResolver().query(contribution.getLocalUri(), + Cursor cursor = contentResolver.query(contribution.getLocalUri(), new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null); if (cursor != null && cursor.getCount() != 0 && cursor.getColumnCount() != 0) { cursor.moveToFirst(); 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 c51f055cb..9bbaa1b92 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 @@ -28,6 +28,7 @@ import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; import fr.free.nrw.commons.R; import fr.free.nrw.commons.Utils; +import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.contributions.ContributionsContentProvider; @@ -47,8 +48,8 @@ public class UploadService extends HandlerService { public static final String EXTRA_SOURCE = EXTRA_PREFIX + ".source"; public static final String EXTRA_CAMPAIGN = EXTRA_PREFIX + ".campaign"; - @Inject CommonsApplication application; @Inject MediaWikiApi mwApi; + @Inject SessionManager sessionManager; private NotificationManager notificationManager; private ContentProviderClient contributionsProviderClient; @@ -221,7 +222,7 @@ public class UploadService extends HandlerService { } if (!mwApi.validateLogin()) { // Need to revalidate! - if (application.revalidateAuthToken()) { + if (sessionManager.revalidateAuthToken()) { Timber.d("Successfully revalidated token!"); } else { Timber.d("Unable to revalidate :("); @@ -246,8 +247,8 @@ public class UploadService extends HandlerService { String resultStatus = uploadResult.getResultStatus(); if (!resultStatus.equals("Success")) { showFailedNotification(contribution); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("source", contribution.getSource()) .param("multiple", contribution.getMultiple()) .param("result", uploadResult.getErrorCode()) @@ -260,8 +261,8 @@ public class UploadService extends HandlerService { contribution.setDateUploaded(uploadResult.getDateUploaded()); contribution.save(); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, application, mwApi) - .param("username", application.getCurrentAccount().name) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + .param("username", sessionManager.getCurrentAccount().name) .param("source", contribution.getSource()) //FIXME .param("filename", contribution.getFilename()) .param("multiple", contribution.getMultiple()) @@ -278,7 +279,7 @@ public class UploadService extends HandlerService { toUpload--; if (toUpload == 0) { // Sync modifications right after all uplaods are processed - ContentResolver.requestSync(application.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle()); + ContentResolver.requestSync(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle()); stopForeground(true); } } From a208c9f2735d54010e42c9de6b566395561e5557 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 10 Sep 2017 10:23:47 -0500 Subject: [PATCH 11/17] Further reduced coupling between classes and the need to @Inject the account utils class, fixed imports. --- .../main/java/fr/free/nrw/commons/Utils.java | 4 -- .../fr/free/nrw/commons/auth/AccountUtil.java | 21 +++++---- .../commons/auth/AuthenticatedActivity.java | 15 ++++--- .../fr/free/nrw/commons/auth/LoginTask.java | 12 ++++-- .../free/nrw/commons/auth/SessionManager.java | 12 +++--- .../auth/WikiAccountAuthenticator.java | 43 ++++++++++++------- .../auth/WikiAccountAuthenticatorService.java | 11 ++--- .../category/CategorizationFragment.java | 2 - .../di/CommonsApplicationComponent.java | 2 - .../commons/di/CommonsApplicationModule.java | 4 +- .../di/ContentProviderBuilderModule.java | 3 -- .../nrw/commons/di/ServiceBuilderModule.java | 9 ---- .../commons/media/MediaDetailFragment.java | 2 - .../free/nrw/commons/mwapi/MediaWikiApi.java | 1 - .../commons/nearby/NearbyListFragment.java | 1 - .../nrw/commons/nearby/NearbyMapFragment.java | 3 -- .../commons/nearby/NoPermissionsFragment.java | 1 - .../upload/MultipleUploadListFragment.java | 1 - .../ApacheHttpClientMediaWikiApiTest.java | 3 -- 19 files changed, 66 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/Utils.java b/app/src/main/java/fr/free/nrw/commons/Utils.java index 1a5b6f078..4d16e8a6e 100644 --- a/app/src/main/java/fr/free/nrw/commons/Utils.java +++ b/app/src/main/java/fr/free/nrw/commons/Utils.java @@ -5,11 +5,7 @@ import org.apache.commons.codec.digest.DigestUtils; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.Locale; -import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; 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 8790a1606..e5b76c0f9 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 @@ -6,16 +6,20 @@ import android.accounts.AccountManager; import android.content.ContentResolver; import android.content.Context; import android.os.Bundle; -import android.support.annotation.NonNull; 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; + public class AccountUtil { - private Context context; + static final String ACCOUNT_TYPE = "fr.free.nrw.commons"; + private final Context context; public AccountUtil(Context context) { this.context = context; @@ -24,7 +28,7 @@ public class AccountUtil { public void createAccount(@Nullable AccountAuthenticatorResponse response, String username, String password) { - Account account = new Account(username, accountType()); + Account account = new Account(username, ACCOUNT_TYPE); boolean created = accountManager().addAccountExplicitly(account, password, null); Timber.d("account creation " + (created ? "successful" : "failure")); @@ -32,8 +36,8 @@ public class AccountUtil { if (created) { if (response != null) { Bundle bundle = new Bundle(); - bundle.putString(AccountManager.KEY_ACCOUNT_NAME, username); - bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType()); + bundle.putString(KEY_ACCOUNT_NAME, username); + bundle.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE); response.onResult(bundle); @@ -41,7 +45,7 @@ public class AccountUtil { } else { if (response != null) { - response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, ""); + response.onError(ERROR_CODE_REMOTE_EXCEPTION, ""); } Timber.d("account creation failure"); } @@ -51,11 +55,6 @@ public class AccountUtil { ContentResolver.setSyncAutomatically(account, ModificationsContentProvider.AUTHORITY, true); // Enable sync by default! } - @NonNull - public String accountType() { - return "fr.free.nrw.commons"; - } - private AccountManager accountManager() { return AccountManager.get(context); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index 4bb265be9..dd8c6265e 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -13,9 +13,11 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; import timber.log.Timber; +import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; +import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE; + public abstract class AuthenticatedActivity extends NavigationBaseActivity { - @Inject AccountUtil accountUtil; @Inject SessionManager sessionManager; private String authCookie; @@ -31,20 +33,21 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { } private void addAccount(AccountManager accountManager) { - Single.just(accountManager.addAccount(accountUtil.accountType(), null, null, null, AuthenticatedActivity.this, null, null)) + Single.just(accountManager.addAccount(ACCOUNT_TYPE, null, null, + null, AuthenticatedActivity.this, null, null)) .subscribeOn(Schedulers.io()) .map(AccountManagerFuture::getResult) .doOnEvent((bundle, throwable) -> { - if (!bundle.containsKey(AccountManager.KEY_ACCOUNT_NAME)) { + if (!bundle.containsKey(KEY_ACCOUNT_NAME)) { throw new RuntimeException("Bundle doesn't contain account-name key: " - + AccountManager.KEY_ACCOUNT_NAME); + + KEY_ACCOUNT_NAME); } }) - .map(bundle -> bundle.getString(AccountManager.KEY_ACCOUNT_NAME)) + .map(bundle -> bundle.getString(KEY_ACCOUNT_NAME)) .doOnError(Timber::e) .observeOn(AndroidSchedulers.mainThread()) .subscribe(s -> { - Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); + Account[] allAccounts = accountManager.getAccountsByType(ACCOUNT_TYPE); Account curAccount = allAccounts[0]; getAuthCookie(curAccount, accountManager); }, diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java index 5011cf752..18475a42a 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java @@ -1,7 +1,6 @@ package fr.free.nrw.commons.auth; import android.accounts.AccountAuthenticatorResponse; -import android.accounts.AccountManager; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; @@ -15,6 +14,11 @@ import fr.free.nrw.commons.mwapi.EventLog; import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; +import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE; +import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; +import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; +import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE; + class LoginTask extends AsyncTask { private LoginActivity loginActivity; @@ -87,11 +91,11 @@ class LoginTask extends AsyncTask { Bundle extras = loginActivity.getIntent().getExtras(); if (extras != null) { Timber.d("Bundle of extras: %s", extras); - response = extras.getParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); + response = extras.getParcelable(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); if (response != null) { Bundle authResult = new Bundle(); - authResult.putString(AccountManager.KEY_ACCOUNT_NAME, username); - authResult.putString(AccountManager.KEY_ACCOUNT_TYPE, accountUtil.accountType()); + authResult.putString(KEY_ACCOUNT_NAME, username); + authResult.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE); response.onResult(authResult); } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java b/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java index d838cda56..779b73b34 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java @@ -12,18 +12,18 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi; import io.reactivex.Completable; import io.reactivex.Observable; +import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE; + /** * Manage the current logged in user session. */ public class SessionManager { private final Context context; - private final AccountUtil accountUtil; private final MediaWikiApi mediaWikiApi; private Account currentAccount; // Unlike a savings account... ;-) - public SessionManager(Context context, AccountUtil accountUtil, MediaWikiApi mediaWikiApi) { + public SessionManager(Context context, MediaWikiApi mediaWikiApi) { this.context = context; - this.accountUtil = accountUtil; this.mediaWikiApi = mediaWikiApi; this.currentAccount = null; } @@ -34,7 +34,7 @@ public class SessionManager { public Account getCurrentAccount() { if (currentAccount == null) { AccountManager accountManager = AccountManager.get(context); - Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); + Account[] allAccounts = accountManager.getAccountsByType(ACCOUNT_TYPE); if (allAccounts.length != 0) { currentAccount = allAccounts[0]; } @@ -50,7 +50,7 @@ public class SessionManager { return false; // This should never happen } - accountManager.invalidateAuthToken(accountUtil.accountType(), mediaWikiApi.getAuthCookie()); + accountManager.invalidateAuthToken(ACCOUNT_TYPE, mediaWikiApi.getAuthCookie()); try { String authCookie = accountManager.blockingGetAuthToken(curAccount, "", false); mediaWikiApi.setAuthCookie(authCookie); @@ -63,7 +63,7 @@ public class SessionManager { public Completable clearAllAccounts() { AccountManager accountManager = AccountManager.get(context); - Account[] allAccounts = accountManager.getAccountsByType(accountUtil.accountType()); + Account[] allAccounts = accountManager.getAccountsByType(ACCOUNT_TYPE); return Completable.fromObservable(Observable.fromArray(allAccounts) .map(a -> accountManager.removeAccount(a, null, null).getResult())) .doOnComplete(() -> currentAccount = null); diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java index 79f48d375..b10af5589 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java @@ -15,31 +15,41 @@ import java.io.IOException; import fr.free.nrw.commons.mwapi.MediaWikiApi; +import static android.accounts.AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION; +import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE; +import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; +import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; +import static android.accounts.AccountManager.KEY_AUTHTOKEN; +import static android.accounts.AccountManager.KEY_BOOLEAN_RESULT; +import static android.accounts.AccountManager.KEY_ERROR_CODE; +import static android.accounts.AccountManager.KEY_ERROR_MESSAGE; +import static android.accounts.AccountManager.KEY_INTENT; +import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE; +import static fr.free.nrw.commons.auth.LoginActivity.PARAM_USERNAME; + public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { private final Context context; - private final AccountUtil accountUtil; private MediaWikiApi mediaWikiApi; - public WikiAccountAuthenticator(Context context, AccountUtil accountUtil, MediaWikiApi mwApi) { + public WikiAccountAuthenticator(Context context, MediaWikiApi mwApi) { super(context); this.context = context; - this.accountUtil = accountUtil; this.mediaWikiApi = mwApi; } private Bundle unsupportedOperation() { Bundle bundle = new Bundle(); - bundle.putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION); + bundle.putInt(KEY_ERROR_CODE, ERROR_CODE_UNSUPPORTED_OPERATION); // HACK: the docs indicate that this is a required key bit it's not displayed to the user. - bundle.putString(AccountManager.KEY_ERROR_MESSAGE, ""); + bundle.putString(KEY_ERROR_MESSAGE, ""); return bundle; } private boolean supportedAccountType(@Nullable String type) { - return accountUtil.accountType().equals(type); + return ACCOUNT_TYPE.equals(type); } @Override @@ -57,10 +67,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { private Bundle addAccount(AccountAuthenticatorResponse response) { Intent Intent = new Intent(context, LoginActivity.class); - Intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); + Intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); Bundle bundle = new Bundle(); - bundle.putParcelable(AccountManager.KEY_INTENT, Intent); + bundle.putParcelable(KEY_INTENT, Intent); return bundle; } @@ -80,12 +90,13 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { private String getAuthCookie(String username, String password) throws IOException { //TODO add 2fa support here String result = mediaWikiApi.login(username, password); - if(result.equals("PASS")) { + if (result.equals("PASS")) { return mediaWikiApi.getAuthCookie(); } else { return null; } } + @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { // Extract the username and password from the Account Manager, and ask @@ -103,9 +114,9 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { } if (authCookie != null) { final Bundle result = new Bundle(); - result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); - result.putString(AccountManager.KEY_ACCOUNT_TYPE, accountUtil.accountType()); - result.putString(AccountManager.KEY_AUTHTOKEN, authCookie); + result.putString(KEY_ACCOUNT_NAME, account.name); + result.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE); + result.putString(KEY_AUTHTOKEN, authCookie); return result; } } @@ -114,10 +125,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { // need to re-prompt them for their credentials. We do that by creating // an intent to display our AuthenticatorActivity panel. final Intent intent = new Intent(context, LoginActivity.class); - intent.putExtra(LoginActivity.PARAM_USERNAME, account.name); - intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); + intent.putExtra(PARAM_USERNAME, account.name); + intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); final Bundle bundle = new Bundle(); - bundle.putParcelable(AccountManager.KEY_INTENT, intent); + bundle.putParcelable(KEY_INTENT, intent); return bundle; } @@ -135,7 +146,7 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { @NonNull Account account, @NonNull String[] features) throws NetworkErrorException { Bundle bundle = new Bundle(); - bundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); + bundle.putBoolean(KEY_BOOLEAN_RESULT, false); return bundle; } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java index 0df6b6b35..b0f3e6063 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticatorService.java @@ -1,31 +1,28 @@ package fr.free.nrw.commons.auth; -import android.accounts.AccountManager; -import android.app.Service; import android.content.Intent; import android.os.IBinder; import javax.inject.Inject; import dagger.android.DaggerService; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.mwapi.MediaWikiApi; +import static android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT; + public class WikiAccountAuthenticatorService extends DaggerService { @Inject MediaWikiApi mwApi; - @Inject AccountUtil accountUtil; - private WikiAccountAuthenticator wikiAccountAuthenticator = null; @Override public IBinder onBind(Intent intent) { - if (!intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) { + if (!intent.getAction().equals(ACTION_AUTHENTICATOR_INTENT)) { return null; } if (wikiAccountAuthenticator == null) { - wikiAccountAuthenticator = new WikiAccountAuthenticator(this, accountUtil, mwApi); + wikiAccountAuthenticator = new WikiAccountAuthenticator(this, mwApi); } return wikiAccountAuthenticator.getIBinder(); } 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 726c18dfd..ab6141392 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 @@ -4,7 +4,6 @@ import android.content.ContentProviderClient; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -35,7 +34,6 @@ import javax.inject.Inject; import butterknife.BindView; import butterknife.ButterKnife; import dagger.android.support.DaggerFragment; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.mwapi.MediaWikiApi; diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index c4e79c343..1fe5fed5d 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -8,10 +8,8 @@ import dagger.android.AndroidInjector; import dagger.android.support.AndroidSupportInjectionModule; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.MediaWikiImageView; -import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; import fr.free.nrw.commons.contributions.ContributionsSyncAdapter; import fr.free.nrw.commons.modifications.ModificationsSyncAdapter; -import fr.free.nrw.commons.upload.UploadService; @Singleton @Component(modules = { 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 c146748d9..b3370da80 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 @@ -30,8 +30,8 @@ public class CommonsApplicationModule { @Provides @Singleton - public SessionManager providesSessionManager(AccountUtil accountUtil, MediaWikiApi mediaWikiApi) { - return new SessionManager(application, accountUtil, mediaWikiApi); + public SessionManager providesSessionManager(MediaWikiApi mediaWikiApi) { + return new SessionManager(application, mediaWikiApi); } @Provides diff --git a/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java index ac9af26a8..d50363bf7 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ContentProviderBuilderModule.java @@ -2,10 +2,7 @@ package fr.free.nrw.commons.di; import dagger.Module; import dagger.android.ContributesAndroidInjector; -import fr.free.nrw.commons.auth.LoginActivity; -import fr.free.nrw.commons.auth.SignupActivity; import fr.free.nrw.commons.category.CategoryContentProvider; -import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.contributions.ContributionsContentProvider; import fr.free.nrw.commons.modifications.ModificationsContentProvider; diff --git a/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java index 3d3bc7712..335b13168 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java @@ -3,15 +3,6 @@ package fr.free.nrw.commons.di; import dagger.Module; import dagger.android.ContributesAndroidInjector; import fr.free.nrw.commons.auth.WikiAccountAuthenticatorService; -import fr.free.nrw.commons.category.CategorizationFragment; -import fr.free.nrw.commons.contributions.ContributionsListFragment; -import fr.free.nrw.commons.media.MediaDetailFragment; -import fr.free.nrw.commons.media.MediaDetailPagerFragment; -import fr.free.nrw.commons.nearby.NearbyListFragment; -import fr.free.nrw.commons.nearby.NoPermissionsFragment; -import fr.free.nrw.commons.settings.SettingsFragment; -import fr.free.nrw.commons.upload.MultipleUploadListFragment; -import fr.free.nrw.commons.upload.SingleUploadFragment; import fr.free.nrw.commons.upload.UploadService; @Module diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index a46bbae12..fa621218a 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -6,7 +6,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -25,7 +24,6 @@ import java.util.Locale; import javax.inject.Inject; import dagger.android.support.DaggerFragment; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.License; import fr.free.nrw.commons.LicenseList; import fr.free.nrw.commons.Media; diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java index 292c0a5de..310c97a8a 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java @@ -5,7 +5,6 @@ import android.support.annotation.Nullable; import java.io.IOException; import java.io.InputStream; -import java.util.List; import io.reactivex.Observable; import io.reactivex.Single; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java index 83aebcf4f..817571668 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java @@ -2,7 +2,6 @@ package fr.free.nrw.commons.nearby; import android.net.Uri; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java index efa88819c..d9e1aa633 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java @@ -4,7 +4,6 @@ import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -13,7 +12,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.mapbox.mapboxsdk.Mapbox; -import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; @@ -22,7 +20,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; -import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.services.android.telemetry.MapboxTelemetry; import java.lang.reflect.Type; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java index ba9a8de7f..ca0ae0a89 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NoPermissionsFragment.java @@ -1,7 +1,6 @@ package fr.free.nrw.commons.nearby; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java index b81b2e7af..36ff9c1eb 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java @@ -5,7 +5,6 @@ import android.graphics.Point; import android.net.Uri; import android.os.Bundle; import android.support.graphics.drawable.VectorDrawableCompat; -import android.support.v4.app.Fragment; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; diff --git a/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java b/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java index 1d9db63c6..e27ca19ea 100644 --- a/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java +++ b/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java @@ -14,13 +14,10 @@ import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; -import java.util.Observer; import java.util.Set; import fr.free.nrw.commons.BuildConfig; -import io.reactivex.Single; import io.reactivex.observers.TestObserver; -import io.reactivex.subscribers.TestSubscriber; import okhttp3.HttpUrl; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; From 1b840502a9ded56d99ae27b5a574263ae62ff626 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Wed, 27 Sep 2017 20:48:42 -0500 Subject: [PATCH 12/17] Small code cleanup --- .../main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java | 1 + .../java/fr/free/nrw/commons/di/CommonsApplicationComponent.java | 1 + .../java/fr/free/nrw/commons/di/CommonsApplicationModule.java | 1 + .../fr/free/nrw/commons/di/ContentProviderBuilderModule.java | 1 + .../main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java | 1 + .../main/java/fr/free/nrw/commons/di/ServiceBuilderModule.java | 1 + 6 files changed, 6 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java index d89c3ac84..27e16ce23 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java @@ -13,6 +13,7 @@ import fr.free.nrw.commons.upload.MultipleShareActivity; import fr.free.nrw.commons.upload.ShareActivity; @Module +@SuppressWarnings({"WeakerAccess", "unused"}) public abstract class ActivityBuilderModule { @ContributesAndroidInjector diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index 1fe5fed5d..2881f33fd 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -31,6 +31,7 @@ public interface CommonsApplicationComponent extends AndroidInjector Date: Wed, 27 Sep 2017 21:30:41 -0500 Subject: [PATCH 13/17] @Injected shared preferences where needed --- .../free/nrw/commons/CommonsApplication.java | 17 +++++------ .../free/nrw/commons/auth/LoginActivity.java | 9 +++--- .../fr/free/nrw/commons/auth/LoginTask.java | 10 +++---- .../category/CategorizationFragment.java | 6 ++-- .../contributions/ContributionsActivity.java | 18 +++++------- .../ContributionsListFragment.java | 6 ++-- .../ContributionsSyncAdapter.java | 5 ++-- .../commons/di/CommonsApplicationModule.java | 29 +++++++++++++++++++ .../media/MediaDetailPagerFragment.java | 5 +++- .../fr/free/nrw/commons/mwapi/EventLog.java | 10 +++---- .../fr/free/nrw/commons/mwapi/LogBuilder.java | 12 +++----- .../nrw/commons/nearby/NearbyActivity.java | 7 +++-- .../nrw/commons/nearby/NearbyController.java | 6 ++-- .../commons/settings/SettingsFragment.java | 12 ++++---- .../free/nrw/commons/upload/GPSExtractor.java | 12 ++++---- .../commons/upload/MultipleShareActivity.java | 13 +++++---- .../nrw/commons/upload/ShareActivity.java | 18 +++++++----- .../commons/upload/SingleUploadFragment.java | 28 +++++++++--------- .../nrw/commons/upload/UploadController.java | 7 ++--- .../nrw/commons/upload/UploadService.java | 7 +++-- 20 files changed, 137 insertions(+), 100 deletions(-) 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 63f460ffd..9b6e8067a 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -3,7 +3,6 @@ package fr.free.nrw.commons; import android.content.Context; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; -import android.preference.PreferenceManager; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.stetho.Stetho; @@ -16,6 +15,7 @@ import org.acra.annotation.ReportsCrashes; import java.io.File; import javax.inject.Inject; +import javax.inject.Named; import dagger.android.AndroidInjector; import dagger.android.DaggerApplication; @@ -27,7 +27,6 @@ import fr.free.nrw.commons.di.CommonsApplicationComponent; import fr.free.nrw.commons.di.CommonsApplicationModule; import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent; import fr.free.nrw.commons.modifications.ModifierSequence; -import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.utils.FileUtils; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; @@ -44,9 +43,11 @@ import timber.log.Timber; ) public class CommonsApplication extends DaggerApplication { - @Inject MediaWikiApi mediaWikiApi; @Inject SessionManager sessionManager; @Inject DBOpenHelper dbOpenHelper; + @Inject @Named("default_preferences") SharedPreferences defaultPrefs; + @Inject @Named("application_preferences") SharedPreferences applicationPrefs; + @Inject @Named("prefs") SharedPreferences otherPrefs; public static final Object[] EVENT_UPLOAD_ATTEMPT = {"MobileAppUploadAttempts", 5334329L}; public static final Object[] EVENT_LOGIN_ATTEMPT = {"MobileAppLoginAttempts", 5257721L}; @@ -117,12 +118,10 @@ public class CommonsApplication extends DaggerApplication { .subscribe(() -> { Timber.d("All accounts have been removed"); //TODO: fix preference manager - PreferenceManager.getDefaultSharedPreferences(CommonsApplication.this).edit().clear().commit(); - SharedPreferences preferences = context - .getSharedPreferences("fr.free.nrw.commons", MODE_PRIVATE); - preferences.edit().clear().commit(); - context.getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().clear().commit(); - preferences.edit().putBoolean("firstrun", false).apply(); + defaultPrefs.edit().clear().commit(); + applicationPrefs.edit().clear().commit(); + applicationPrefs.edit().putBoolean("firstrun", false).apply(); + otherPrefs.edit().clear().commit(); updateAllDatabases(); logoutListener.onLogoutComplete(); diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index 6570cadbd..2e2627bf8 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -16,6 +16,7 @@ import android.widget.TextView; import android.widget.Toast; import javax.inject.Inject; +import javax.inject.Named; import dagger.android.AndroidInjection; import fr.free.nrw.commons.BuildConfig; @@ -37,8 +38,8 @@ public class LoginActivity extends AccountAuthenticatorActivity { @Inject MediaWikiApi mwApi; @Inject AccountUtil accountUtil; @Inject SessionManager sessionManager; - - private SharedPreferences prefs = null; + @Inject @Named("application_preferences") SharedPreferences prefs = null; + @Inject @Named("default_preferences") SharedPreferences defaultPrefs; private Button loginButton; private EditText usernameEdit; @@ -60,8 +61,6 @@ public class LoginActivity extends AccountAuthenticatorActivity { passwordEdit = (EditText) findViewById(R.id.loginPassword); twoFactorEdit = (EditText) findViewById(R.id.loginTwoFactor); - prefs = getSharedPreferences("fr.free.nrw.commons", MODE_PRIVATE); - usernameEdit.addTextChangedListener(textWatcher); passwordEdit.addTextChangedListener(textWatcher); twoFactorEdit.addTextChangedListener(textWatcher); @@ -145,7 +144,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { canonicializeUsername(usernameEdit.getText().toString()), passwordEdit.getText().toString(), twoFactorEdit.getText().toString(), - accountUtil, this, mwApi + accountUtil, mwApi, defaultPrefs ); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java index 18475a42a..a777187d0 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginTask.java @@ -2,7 +2,7 @@ package fr.free.nrw.commons.auth; import android.accounts.AccountAuthenticatorResponse; import android.app.ProgressDialog; -import android.content.Context; +import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Bundle; @@ -26,19 +26,19 @@ class LoginTask extends AsyncTask { private String password; private String twoFactorCode = ""; private AccountUtil accountUtil; - private Context context; private MediaWikiApi mwApi; + private SharedPreferences prefs; public LoginTask(LoginActivity loginActivity, String username, String password, String twoFactorCode, AccountUtil accountUtil, - Context context, MediaWikiApi mwApi) { + MediaWikiApi mwApi, SharedPreferences prefs) { this.loginActivity = loginActivity; this.username = username; this.password = password; this.twoFactorCode = twoFactorCode; this.accountUtil = accountUtil; - this.context = context; this.mwApi = mwApi; + this.prefs = prefs; } @Override @@ -71,7 +71,7 @@ class LoginTask extends AsyncTask { super.onPostExecute(result); Timber.d("Login done!"); - EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, context, mwApi) + EventLog.schema(CommonsApplication.EVENT_LOGIN_ATTEMPT, mwApi, prefs) .param("username", username) .param("result", result) .log(); 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 96e6936ac..9883c3441 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 @@ -3,7 +3,6 @@ package fr.free.nrw.commons.category; import android.content.ContentProviderClient; import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -30,6 +29,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; import javax.inject.Inject; +import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; @@ -66,6 +66,7 @@ public class CategorizationFragment extends DaggerFragment { TextView categoriesSkip; @Inject MediaWikiApi mwApi; + @Inject @Named("default_preferences") SharedPreferences prefs; private RVRendererAdapter categoriesAdapter; private OnCategoriesSaveHandler onCategoriesSaveHandler; @@ -250,8 +251,7 @@ public class CategorizationFragment extends DaggerFragment { private Observable titleCategories() { //Retrieve the title that was saved when user tapped submit icon - SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity()); - String title = titleDesc.getString("Title", ""); + String title = prefs.getString("Title", ""); return mwApi .searchTitles(title, SEARCH_CATS_LIMIT) 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 a9384d2fa..42ffd5a97 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 @@ -9,7 +9,6 @@ import android.database.Cursor; import android.database.DataSetObserver; import android.os.Bundle; import android.os.IBinder; -import android.preference.PreferenceManager; import android.support.v4.app.FragmentManager; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -24,6 +23,7 @@ import android.widget.AdapterView; import java.util.ArrayList; import javax.inject.Inject; +import javax.inject.Named; import butterknife.ButterKnife; import fr.free.nrw.commons.HandlerService; @@ -45,7 +45,9 @@ import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED; import static fr.free.nrw.commons.contributions.Contribution.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;public class ContributionsActivity +import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING; + +public class ContributionsActivity extends AuthenticatedActivity implements LoaderManager.LoaderCallbacks, AdapterView.OnItemClickListener, @@ -55,6 +57,7 @@ import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING;public class @Inject MediaWikiApi mediaWikiApi; @Inject SessionManager sessionManager; + @Inject @Named("default_preferences") SharedPreferences prefs; private Cursor allContributions; private ContributionsListFragment contributionsList; @@ -108,12 +111,8 @@ import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING;public class @Override protected void onResume() { super.onResume(); - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - boolean isSettingsChanged = - sharedPreferences.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); - editor.apply(); + boolean isSettingsChanged = prefs.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); + prefs.edit().putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false).apply(); if (isSettingsChanged) { refreshSource(); } @@ -235,8 +234,7 @@ import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING;public class @Override public Loader onCreateLoader(int i, Bundle bundle) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - int uploads = sharedPref.getInt(UPLOADS_SHOWING, 100); + int uploads = prefs.getInt(UPLOADS_SHOWING, 100); return new CursorLoader(this, BASE_URI, ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT + "LIMIT " + uploads); diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index 8570e7c6e..6f4e7884c 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -19,6 +19,9 @@ import android.widget.GridView; import android.widget.ListAdapter; import android.widget.TextView; +import javax.inject.Inject; +import javax.inject.Named; + import butterknife.BindView; import butterknife.ButterKnife; import dagger.android.support.DaggerFragment; @@ -28,7 +31,6 @@ import timber.log.Timber; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.app.Activity.RESULT_OK; -import static android.content.Context.MODE_PRIVATE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.view.View.GONE; @@ -37,6 +39,7 @@ public class ContributionsListFragment extends DaggerFragment { @BindView(R.id.contributionsList) GridView contributionsList; @BindView(R.id.waitingMessage) TextView waitingMessage; @BindView(R.id.emptyMessage) TextView emptyMessage; + @Inject @Named("prefs") SharedPreferences prefs; private ContributionController controller; @Override @@ -51,7 +54,6 @@ public class ContributionsListFragment extends DaggerFragment { } //TODO: Should this be in onResume? - SharedPreferences prefs = getActivity().getSharedPreferences("prefs", MODE_PRIVATE); String lastModified = prefs.getString("lastSyncTimestamp", ""); Timber.d("Last Sync Timestamp: %s", lastModified); 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 8b331e885..a99cbf933 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 @@ -21,6 +21,7 @@ import java.util.Locale; import java.util.TimeZone; import javax.inject.Inject; +import javax.inject.Named; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Utils; @@ -28,11 +29,11 @@ import fr.free.nrw.commons.mwapi.LogEventResult; import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; -import static android.content.Context.MODE_PRIVATE; import static fr.free.nrw.commons.contributions.Contribution.STATE_COMPLETED; import static fr.free.nrw.commons.contributions.Contribution.Table.COLUMN_FILENAME; import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; +@SuppressWarnings("WeakerAccess") public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { private static final String[] existsQuery = {COLUMN_FILENAME}; @@ -42,6 +43,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { @SuppressWarnings("WeakerAccess") @Inject MediaWikiApi mwApi; + @Inject @Named("prefs") SharedPreferences prefs; public ContributionsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); @@ -79,7 +81,6 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { ((CommonsApplication) getContext().getApplicationContext()).injector().inject(this); // This code is fraught with possibilities of race conditions, but lalalalala I can't hear you! String user = account.name; - SharedPreferences prefs = getContext().getSharedPreferences("prefs", MODE_PRIVATE); String lastModified = prefs.getString("lastSyncTimestamp", ""); Date curTime = new Date(); LogEventResult result; 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 0754a02b1..4da020059 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,7 +1,10 @@ package fr.free.nrw.commons.di; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; import android.support.v4.util.LruCache; +import javax.inject.Named; import javax.inject.Singleton; import dagger.Module; @@ -15,6 +18,9 @@ import fr.free.nrw.commons.data.DBOpenHelper; import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.nearby.NearbyPlaces; +import fr.free.nrw.commons.upload.UploadController; + +import static android.content.Context.MODE_PRIVATE; @Module @SuppressWarnings({"WeakerAccess", "unused"}) @@ -30,6 +36,29 @@ public class CommonsApplicationModule { return new AccountUtil(application); } + @Provides + @Named("application_preferences") + public SharedPreferences providesApplicationSharedPreferences() { + return application.getSharedPreferences("fr.free.nrw.commons", MODE_PRIVATE); + } + + @Provides + @Named("default_preferences") + public SharedPreferences providesDefaultSharedPreferences() { + return PreferenceManager.getDefaultSharedPreferences(application); + } + + @Provides + @Named("prefs") + public SharedPreferences providesOtherSharedPreferences() { + return application.getSharedPreferences("prefs", MODE_PRIVATE); + } + + @Provides + public UploadController providesUploadController(SessionManager sessionManager, @Named("default_preferences") SharedPreferences sharedPreferences) { + return new UploadController(sessionManager, application, sharedPreferences); + } + @Provides @Singleton public SessionManager providesSessionManager(MediaWikiApi mediaWikiApi) { diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index 49a40b546..1aced4049 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -3,6 +3,7 @@ package fr.free.nrw.commons.media; import android.annotation.SuppressLint; import android.app.DownloadManager; import android.content.Intent; +import android.content.SharedPreferences; import android.database.DataSetObserver; import android.net.Uri; import android.os.Build; @@ -25,6 +26,7 @@ import android.view.View; import android.view.ViewGroup; import javax.inject.Inject; +import javax.inject.Named; import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.CommonsApplication; @@ -46,6 +48,7 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage @Inject MediaWikiApi mwApi; @Inject SessionManager sessionManager; + @Inject @Named("default_preferences") SharedPreferences prefs; private ViewPager pager; private Boolean editable; @@ -109,7 +112,7 @@ public class MediaDetailPagerFragment extends DaggerFragment implements ViewPage case R.id.menu_share_current_image: // Share - this is just logs it, intent set in onCreateOptionsMenu, around line 252 CommonsApplication app = (CommonsApplication) getActivity().getApplication(); - EventLog.schema(EVENT_SHARE_ATTEMPT, getContext().getApplicationContext(), mwApi) + EventLog.schema(EVENT_SHARE_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("filename", m.getFilename()) .log(); diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java b/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java index 1a867cd00..4446da738 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/EventLog.java @@ -1,6 +1,6 @@ package fr.free.nrw.commons.mwapi; -import android.content.Context; +import android.content.SharedPreferences; import android.os.Build; import fr.free.nrw.commons.Utils; @@ -16,14 +16,14 @@ public class EventLog { } } - private static LogBuilder schema(String schema, long revision, Context context, MediaWikiApi mwApi) { - return new LogBuilder(schema, revision, context, mwApi); + private static LogBuilder schema(String schema, long revision, MediaWikiApi mwApi, SharedPreferences prefs) { + return new LogBuilder(schema, revision, mwApi, prefs); } - public static LogBuilder schema(Object[] scid, Context context, MediaWikiApi mwApi) { + public static LogBuilder schema(Object[] scid, MediaWikiApi mwApi, SharedPreferences prefs) { if (scid.length != 2) { throw new IllegalArgumentException("Needs an object array with schema as first param and revision as second"); } - return schema((String) scid[0], (Long) scid[1], context, mwApi); + return schema((String) scid[0], (Long) scid[1], mwApi, prefs); } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java b/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java index 29f44995e..7a4b294fa 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/LogBuilder.java @@ -1,10 +1,8 @@ package fr.free.nrw.commons.mwapi; -import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Build; -import android.preference.PreferenceManager; import org.json.JSONException; import org.json.JSONObject; @@ -13,23 +11,22 @@ import java.net.MalformedURLException; import java.net.URL; import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.settings.Prefs; @SuppressWarnings("WeakerAccess") public class LogBuilder { - private final Context context; private final MediaWikiApi mwApi; private final JSONObject data; private final long rev; private final String schema; + private final SharedPreferences prefs; - LogBuilder(String schema, long revision, Context context, MediaWikiApi mwApi) { + LogBuilder(String schema, long revision, MediaWikiApi mwApi, SharedPreferences prefs) { + this.prefs = prefs; this.data = new JSONObject(); this.schema = schema; this.rev = revision; - this.context = context; this.mwApi = mwApi; } @@ -62,8 +59,7 @@ public class LogBuilder { // Use *only* for tracking the user preference change for EventLogging // Attempting to use anywhere else will cause kitten explosions public void log(boolean force) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); - if (!settings.getBoolean(Prefs.TRACKING_ENABLED, true) && !force) { + if (!prefs.getBoolean(Prefs.TRACKING_ENABLED, true) && !force) { return; // User has disabled tracking } LogTask logTask = new LogTask(mwApi); diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java index 70bb38476..eac0b46df 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyActivity.java @@ -3,6 +3,7 @@ package fr.free.nrw.commons.nearby; import android.Manifest; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.location.LocationManager; import android.net.Uri; @@ -28,6 +29,7 @@ import com.google.gson.GsonBuilder; import java.util.List; import javax.inject.Inject; +import javax.inject.Named; import butterknife.BindView; import butterknife.ButterKnife; @@ -43,6 +45,7 @@ public class NearbyActivity extends NavigationBaseActivity { @BindView(R.id.progressBar) ProgressBar progressBar; @Inject NearbyPlaces nearbyPlaces; + @Inject @Named("default_preferences") SharedPreferences prefs; private boolean isMapViewActive = false; private static final int LOCATION_REQUEST = 1; @@ -93,7 +96,7 @@ public class NearbyActivity extends NavigationBaseActivity { locationManager = new LocationServiceManager(this); locationManager.registerLocationManager(); curLatLang = locationManager.getLatestLocation(); - nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(nearbyPlaces)); + nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(nearbyPlaces, prefs)); nearbyAsyncTask.execute(); } @@ -232,7 +235,7 @@ public class NearbyActivity extends NavigationBaseActivity { } private void refreshView() { - nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(nearbyPlaces)); + nearbyAsyncTask = new NearbyAsyncTask(this, new NearbyController(nearbyPlaces, prefs)); nearbyAsyncTask.execute(); } diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index 619db6e0a..f1be66d00 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -3,7 +3,6 @@ package fr.free.nrw.commons.nearby; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Bitmap; -import android.preference.PreferenceManager; import android.support.graphics.drawable.VectorDrawableCompat; import com.mapbox.mapboxsdk.annotations.IconFactory; @@ -27,9 +26,11 @@ import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween; public class NearbyController { private static final int MAX_RESULTS = 1000; private final NearbyPlaces nearbyPlaces; + private final SharedPreferences prefs; - public NearbyController(NearbyPlaces nearbyPlaces) { + public NearbyController(NearbyPlaces nearbyPlaces, SharedPreferences prefs) { this.nearbyPlaces = nearbyPlaces; + this.prefs = prefs; } /** @@ -43,7 +44,6 @@ public class NearbyController { if (curLatLng == null) { return Collections.emptyList(); } - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); List places = prefs.getBoolean("useWikidata", true) ? nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage()) : nearbyPlaces.getFromWikiNeedsPictures(); diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index 4527d1761..9422d0b25 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -8,7 +8,9 @@ import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; + +import javax.inject.Inject; +import javax.inject.Named; import dagger.android.AndroidInjection; import fr.free.nrw.commons.R; @@ -16,6 +18,8 @@ import fr.free.nrw.commons.Utils; public class SettingsFragment extends PreferenceFragment { + @Inject @Named("default_preferences") SharedPreferences prefs; + @Override public void onAttach(Context context) { AndroidInjection.inject(this); @@ -46,14 +50,12 @@ public class SettingsFragment extends PreferenceFragment { }); final EditTextPreference uploadLimit = (EditTextPreference) findPreference("uploads"); - final SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(getActivity().getApplicationContext()); - int uploads = sharedPref.getInt(Prefs.UPLOADS_SHOWING, 100); + int uploads = prefs.getInt(Prefs.UPLOADS_SHOWING, 100); uploadLimit.setText(uploads + ""); uploadLimit.setSummary(uploads + ""); uploadLimit.setOnPreferenceChangeListener((preference, newValue) -> { int value = Integer.parseInt(newValue.toString()); - final SharedPreferences.Editor editor = sharedPref.edit(); + final SharedPreferences.Editor editor = prefs.edit(); if (value > 500) { new AlertDialog.Builder(getActivity()) .setTitle(R.string.maximum_limit) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java index 77bd18703..340598678 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java @@ -8,7 +8,6 @@ import android.location.LocationListener; import android.location.LocationManager; import android.media.ExifInterface; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; @@ -26,6 +25,7 @@ import timber.log.Timber; public class GPSExtractor { private final Context context; + private SharedPreferences prefs; private ExifInterface exif; private double decLatitude; private double decLongitude; @@ -41,8 +41,9 @@ public class GPSExtractor { * @param context the context */ @RequiresApi(24) - public GPSExtractor(@NonNull FileDescriptor fileDescriptor, Context context) { + public GPSExtractor(@NonNull FileDescriptor fileDescriptor, Context context, SharedPreferences prefs) { this.context = context; + this.prefs = prefs; try { exif = new ExifInterface(fileDescriptor); } catch (IOException | IllegalArgumentException e) { @@ -55,7 +56,8 @@ public class GPSExtractor { * @param path file path of the image * @param context the context */ - public GPSExtractor(@NonNull String path, Context context) { + public GPSExtractor(@NonNull String path, Context context, SharedPreferences prefs) { + this.prefs = prefs; try { exif = new ExifInterface(path); } catch (IOException | IllegalArgumentException e) { @@ -69,9 +71,7 @@ public class GPSExtractor { * @return true if enabled, false if disabled */ private boolean gpsPreferenceEnabled() { - SharedPreferences sharedPref - = PreferenceManager.getDefaultSharedPreferences(context); - boolean gpsPref = sharedPref.getBoolean("allowGps", false); + boolean gpsPref = prefs.getBoolean("allowGps", false); Timber.d("Gps pref set to: %b", gpsPref); return gpsPref; } 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 dfbacf469..1c8e9012e 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 @@ -6,6 +6,7 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.database.DataSetObserver; import android.net.Uri; @@ -25,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import javax.inject.Named; import butterknife.ButterKnife; import fr.free.nrw.commons.CommonsApplication; @@ -53,6 +55,8 @@ public class MultipleShareActivity extends AuthenticatedActivity @Inject MediaWikiApi mwApi; @Inject SessionManager sessionManager; + @Inject UploadController uploadController; + @Inject @Named("default_preferences") SharedPreferences prefs; private ArrayList photosList = null; @@ -60,8 +64,6 @@ public class MultipleShareActivity extends AuthenticatedActivity private MediaDetailPagerFragment mediaDetails; private CategorizationFragment categorizationFragment; - private UploadController uploadController; - @Override public Media getMediaAtPosition(int i) { return photosList.get(i); @@ -179,7 +181,7 @@ public class MultipleShareActivity extends AuthenticatedActivity // 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! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", photosList.size()) @@ -204,7 +206,6 @@ public class MultipleShareActivity extends AuthenticatedActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - uploadController = new UploadController(sessionManager, this); setContentView(R.layout.activity_multiple_uploads); ButterKnife.bind(this); @@ -289,7 +290,7 @@ public class MultipleShareActivity extends AuthenticatedActivity public void onBackPressed() { super.onBackPressed(); if (categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", photosList.size()) @@ -297,7 +298,7 @@ public class MultipleShareActivity extends AuthenticatedActivity .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) 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 9e381a436..05823910d 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 @@ -3,6 +3,7 @@ package fr.free.nrw.commons.upload; import android.Manifest; import android.content.ContentResolver; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; @@ -34,6 +35,7 @@ import java.util.Date; import java.util.List; import javax.inject.Inject; +import javax.inject.Named; import butterknife.ButterKnife; import fr.free.nrw.commons.CommonsApplication; @@ -73,6 +75,8 @@ public class ShareActivity @Inject MediaWikiApi mwApi; @Inject CacheController cacheController; @Inject SessionManager sessionManager; + @Inject UploadController uploadController; + @Inject @Named("default_preferences") SharedPreferences prefs; private String source; private String mimeType; @@ -81,8 +85,6 @@ public class ShareActivity private Contribution contribution; private SimpleDraweeView backgroundImageView; - private UploadController uploadController; - private boolean cacheFound; private GPSExtractor imageObj; @@ -172,7 +174,7 @@ public class ShareActivity // 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! - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categories.size()) .param("files-count", 1) @@ -194,7 +196,7 @@ public class ShareActivity public void onBackPressed() { super.onBackPressed(); if(categorizationFragment != null && categorizationFragment.isVisible()) { - EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_CATEGORIZATION_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("categories-count", categorizationFragment.getCurrentSelectedCount()) .param("files-count", 1) @@ -202,7 +204,7 @@ public class ShareActivity .param("result", "cancelled") .log(); } else { - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("source", getIntent().getStringExtra(UploadService.EXTRA_SOURCE)) .param("multiple", true) @@ -226,7 +228,7 @@ public class ShareActivity @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - uploadController = new UploadController(sessionManager, this); + setContentView(R.layout.activity_share); ButterKnife.bind(this); initBack(); @@ -451,12 +453,12 @@ public class ShareActivity = getContentResolver().openFileDescriptor(mediaUri, "r"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (descriptor != null) { - imageObj = new GPSExtractor(descriptor.getFileDescriptor(), this); + imageObj = new GPSExtractor(descriptor.getFileDescriptor(), this, prefs); } } else { String filePath = getPathOfMediaOrCopy(); if (filePath != null) { - imageObj = new GPSExtractor(filePath, this); + imageObj = new GPSExtractor(filePath, this, prefs); } } } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java index a742a6a1c..8038bd791 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java @@ -28,6 +28,9 @@ import android.widget.TextView; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Named; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -50,7 +53,8 @@ public class SingleUploadFragment extends DaggerFragment { @BindView(R.id.share_license_summary) TextView licenseSummaryView; @BindView(R.id.licenseSpinner) Spinner licenseSpinner; - private SharedPreferences prefs; + @Inject @Named("default_preferences") SharedPreferences prefs; + private String license; private OnUploadActionInitiated uploadActionInitiatedHandler; private TitleTextWatcher textWatcher = new TitleTextWatcher(); @@ -73,11 +77,10 @@ public class SingleUploadFragment extends DaggerFragment { String desc = descEdit.getText().toString(); //Save the title/desc in short-lived cache so next time this fragment is loaded, we can access these - SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity()); - SharedPreferences.Editor editor = titleDesc.edit(); - editor.putString("Title", title); - editor.putString("Desc", desc); - editor.apply(); + prefs.edit() + .putString("Title", title) + .putString("Desc", desc) + .apply(); uploadActionInitiatedHandler.uploadActionInitiated(title, desc); return true; @@ -91,7 +94,6 @@ public class SingleUploadFragment extends DaggerFragment { View rootView = inflater.inflate(R.layout.fragment_single_upload, container, false); ButterKnife.bind(this, rootView); - ArrayList licenseItems = new ArrayList<>(); licenseItems.add(getString(R.string.license_name_cc0)); licenseItems.add(getString(R.string.license_name_cc_by)); @@ -99,7 +101,6 @@ public class SingleUploadFragment extends DaggerFragment { licenseItems.add(getString(R.string.license_name_cc_by_four)); licenseItems.add(getString(R.string.license_name_cc_by_sa_four)); - prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); license = prefs.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3); // check if this is the first time we have uploaded @@ -172,9 +173,9 @@ public class SingleUploadFragment extends DaggerFragment { } setLicenseSummary(license); - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(Prefs.DEFAULT_LICENSE, license); - editor.commit(); + prefs.edit() + .putString(Prefs.DEFAULT_LICENSE, license) + .commit(); } @OnTouch(R.id.share_license_summary) @@ -193,9 +194,8 @@ public class SingleUploadFragment extends DaggerFragment { @OnClick(R.id.titleDescButton) void setTitleDescButton() { //Retrieve last title and desc entered - SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity()); - String title = titleDesc.getString("Title", ""); - String desc = titleDesc.getString("Desc", ""); + String title = prefs.getString("Title", ""); + String desc = prefs.getString("Desc", ""); Timber.d("Title: %s, Desc: %s", title, desc); titleEdit.setText(title); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java index 55ecf1dd9..79648258a 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java @@ -10,7 +10,6 @@ import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.IBinder; -import android.preference.PreferenceManager; import android.provider.MediaStore; import android.text.TextUtils; @@ -31,14 +30,16 @@ public class UploadController { private UploadService uploadService; private SessionManager sessionManager; private Context context; + private SharedPreferences prefs; public interface ContributionUploadProgress { void onUploadStarted(Contribution contribution); } - public UploadController(SessionManager sessionManager, Context context) { + public UploadController(SessionManager sessionManager, Context context, SharedPreferences sharedPreferences) { this.sessionManager = sessionManager; this.context = context; + this.prefs = sharedPreferences; } private boolean isUploadServiceConnected; @@ -85,8 +86,6 @@ public class UploadController { } public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); - //Set creator, desc, and license if(TextUtils.isEmpty(contribution.getCreator())) { contribution.setCreator(sessionManager.getCurrentAccount().name); 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 9bbaa1b92..5fa7c1902 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 @@ -8,6 +8,7 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.BitmapFactory; import android.os.Bundle; import android.support.v4.app.NotificationCompat; @@ -23,6 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; +import javax.inject.Named; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.HandlerService; @@ -50,6 +52,7 @@ public class UploadService extends HandlerService { @Inject MediaWikiApi mwApi; @Inject SessionManager sessionManager; + @Inject @Named("default_preferences") SharedPreferences prefs; private NotificationManager notificationManager; private ContentProviderClient contributionsProviderClient; @@ -247,7 +250,7 @@ public class UploadService extends HandlerService { String resultStatus = uploadResult.getResultStatus(); if (!resultStatus.equals("Success")) { showFailedNotification(contribution); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("source", contribution.getSource()) .param("multiple", contribution.getMultiple()) @@ -261,7 +264,7 @@ public class UploadService extends HandlerService { contribution.setDateUploaded(uploadResult.getDateUploaded()); contribution.save(); - EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, getApplicationContext(), mwApi) + EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT, mwApi, prefs) .param("username", sessionManager.getCurrentAccount().name) .param("source", contribution.getSource()) //FIXME .param("filename", contribution.getFilename()) From b305acd3954165d0c7499fce81ceca7129939613 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Wed, 27 Sep 2017 21:53:00 -0500 Subject: [PATCH 14/17] View injection with Butterknife --- .../free/nrw/commons/auth/LoginActivity.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index 2e2627bf8..1900fc91d 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -18,6 +18,8 @@ import android.widget.Toast; import javax.inject.Inject; import javax.inject.Named; +import butterknife.BindView; +import butterknife.ButterKnife; import dagger.android.AndroidInjection; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.PageTitle; @@ -41,10 +43,12 @@ public class LoginActivity extends AccountAuthenticatorActivity { @Inject @Named("application_preferences") SharedPreferences prefs = null; @Inject @Named("default_preferences") SharedPreferences defaultPrefs; - private Button loginButton; - private EditText usernameEdit; - private EditText passwordEdit; - private EditText twoFactorEdit; + @BindView(R.id.loginButton) Button loginButton; + @BindView(R.id.signupButton) Button signupButton; + @BindView(R.id.loginUsername) EditText usernameEdit; + @BindView(R.id.loginPassword) EditText passwordEdit; + @BindView(R.id.loginTwoFactor) EditText twoFactorEdit; + ProgressDialog progressDialog; private LoginTextWatcher textWatcher = new LoginTextWatcher(); @@ -54,12 +58,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); - - loginButton = (Button) findViewById(R.id.loginButton); - Button signupButton = (Button) findViewById(R.id.signupButton); - usernameEdit = (EditText) findViewById(R.id.loginUsername); - passwordEdit = (EditText) findViewById(R.id.loginPassword); - twoFactorEdit = (EditText) findViewById(R.id.loginTwoFactor); + ButterKnife.bind(this); usernameEdit.addTextChangedListener(textWatcher); passwordEdit.addTextChangedListener(textWatcher); From 17e1ff20d7c947f59a0b2b66c2ca07450ce191c1 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sat, 25 Nov 2017 11:46:41 -0600 Subject: [PATCH 15/17] Update based on code-review feedback. --- app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java index 6d304aa07..2cf18e7d7 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java @@ -155,7 +155,7 @@ public class FileUtils { } /** - * Check if the URI is owned by the current application. + * Check if the URI is owned by the current app. */ public static boolean isSelfOwned(Context context, Uri uri) { return uri.getAuthority().equals(context.getPackageName() + ".provider"); From 6d77243329af06186259605c387636bbbc76722b Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sat, 25 Nov 2017 12:52:42 -0600 Subject: [PATCH 16/17] Fixed issue found by tests running on Android API 21/22 --- .../fr/free/nrw/commons/settings/SettingsFragment.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index a78bb8bbb..2809eb0ab 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -38,14 +38,9 @@ public class SettingsFragment extends PreferenceFragment { @Inject @Named("default_preferences") SharedPreferences prefs; - @Override - public void onAttach(Context context) { - AndroidInjection.inject(this); - super.onAttach(context); - } - @Override public void onCreate(Bundle savedInstanceState) { + AndroidInjection.inject(this); super.onCreate(savedInstanceState); // Load the preferences from an XML resource From 07577d73a15a66ef6fb83b5e6736a16829692d4a Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sat, 25 Nov 2017 14:23:50 -0600 Subject: [PATCH 17/17] Refactoring based on code review feedback. --- .../free/nrw/commons/MediaDataExtractor.java | 21 +++++++------------ .../commons/media/MediaDetailFragment.java | 9 +++++--- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java index 104798518..0927f0338 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.inject.Inject; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -34,34 +35,26 @@ import timber.log.Timber; public class MediaDataExtractor { private final MediaWikiApi mediaWikiApi; private boolean fetched; - - private String filename; private ArrayList categories; private Map descriptions; private String license; private @Nullable LatLng coordinates; - private LicenseList licenseList; - /** - * @param mwApi instance of MediaWikiApi - * @param filename of the target media object, should include 'File:' prefix - */ - public MediaDataExtractor(String filename, LicenseList licenseList, MediaWikiApi mwApi) { - this.filename = filename; + @Inject + public MediaDataExtractor(MediaWikiApi mwApi) { this.categories = new ArrayList<>(); this.descriptions = new HashMap<>(); this.fetched = false; - this.licenseList = licenseList; this.mediaWikiApi = mwApi; } - /** + /* * Actually fetch the data over the network. * todo: use local caching? * * Warning: synchronous i/o, call on a background thread */ - public void fetch() throws IOException { + public void fetch(String filename, LicenseList licenseList) throws IOException { if (fetched) { throw new IllegalStateException("Tried to call MediaDataExtractor.fetch() again."); } @@ -72,7 +65,7 @@ public class MediaDataExtractor { extractCategories(result.getWikiSource()); // Description template info is extracted from preprocessor XML - processWikiParseTree(result.getParseTreeXmlSource()); + processWikiParseTree(result.getParseTreeXmlSource(), licenseList); fetched = true; } @@ -91,7 +84,7 @@ public class MediaDataExtractor { } } - private void processWikiParseTree(String source) throws IOException { + private void processWikiParseTree(String source, LicenseList licenseList) throws IOException { Document doc; try { DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index dc2295f97..718ee4f58 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -22,6 +22,7 @@ import java.util.Date; import java.util.Locale; import javax.inject.Inject; +import javax.inject.Provider; import dagger.android.support.DaggerFragment; import fr.free.nrw.commons.License; @@ -56,7 +57,9 @@ public class MediaDetailFragment extends DaggerFragment { return mf; } - @Inject MediaWikiApi mwApi; + @Inject + Provider mediaDataExtractorProvider; + private MediaWikiImageView image; private MediaDetailSpacer spacer; private int initialListTop = 0; @@ -192,13 +195,13 @@ public class MediaDetailFragment extends DaggerFragment { @Override protected void onPreExecute() { - extractor = new MediaDataExtractor(media.getFilename(), licenseList, mwApi); + extractor = mediaDataExtractorProvider.get(); } @Override protected Boolean doInBackground(Void... voids) { try { - extractor.fetch(); + extractor.fetch(media.getFilename(), licenseList); return Boolean.TRUE; } catch (IOException e) { Timber.d(e);