diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt
index 1303c35cc5ae..5c84cf6fdb5b 100644
--- a/scripts/analysis/findbugs-results.txt
+++ b/scripts/analysis/findbugs-results.txt
@@ -1 +1 @@
-497
+491
\ No newline at end of file
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 39a1a6644493..acf73c78a935 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -314,7 +314,7 @@
-
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package com.nextcloud.client.appinfo;
+
+/**
+ * This class provides general, static information about application
+ * build.
+ *
+ * All methods should be thread-safe.
+ */
+public interface AppInfo {
+
+ /**
+ * Get application version code as formatted string.
+ *
+ * @return Formatted version code as defined in AndroidManifest.xml
+ */
+ String getFormattedVersionCode();
+
+}
diff --git a/src/main/java/com/nextcloud/client/appinfo/AppInfoImpl.java b/src/main/java/com/nextcloud/client/appinfo/AppInfoImpl.java
new file mode 100644
index 000000000000..1256f5fa9fb1
--- /dev/null
+++ b/src/main/java/com/nextcloud/client/appinfo/AppInfoImpl.java
@@ -0,0 +1,30 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package com.nextcloud.client.appinfo;
+
+import com.owncloud.android.BuildConfig;
+
+class AppInfoImpl implements AppInfo {
+
+ @Override
+ public String getFormattedVersionCode() {
+ return Integer.toString(BuildConfig.VERSION_CODE);
+ }
+}
diff --git a/src/main/java/com/nextcloud/client/appinfo/AppInfoModule.java b/src/main/java/com/nextcloud/client/appinfo/AppInfoModule.java
new file mode 100644
index 000000000000..fa80efba4bca
--- /dev/null
+++ b/src/main/java/com/nextcloud/client/appinfo/AppInfoModule.java
@@ -0,0 +1,31 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package com.nextcloud.client.appinfo;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class AppInfoModule {
+ @Provides
+ AppInfo appInfo() {
+ return new AppInfoImpl();
+ }
+}
diff --git a/src/main/java/com/nextcloud/client/di/AppComponent.java b/src/main/java/com/nextcloud/client/di/AppComponent.java
index e6c5db32d13f..021d211b8ae7 100644
--- a/src/main/java/com/nextcloud/client/di/AppComponent.java
+++ b/src/main/java/com/nextcloud/client/di/AppComponent.java
@@ -22,16 +22,23 @@
import android.app.Application;
+import com.nextcloud.client.appinfo.AppInfoModule;
+import com.nextcloud.client.whatsnew.WhatsNewModule;
import com.owncloud.android.MainApp;
+import javax.inject.Singleton;
+
import dagger.BindsInstance;
import dagger.Component;
import dagger.android.support.AndroidSupportInjectionModule;
@Component(modules = {
AndroidSupportInjectionModule.class,
- AppModule.class
+ AppModule.class,
+ AppInfoModule.class,
+ WhatsNewModule.class,
})
+@Singleton
public interface AppComponent {
void inject(MainApp app);
diff --git a/src/main/java/com/nextcloud/client/di/AppModule.java b/src/main/java/com/nextcloud/client/di/AppModule.java
index 7e72a1be0300..977509b2e091 100644
--- a/src/main/java/com/nextcloud/client/di/AppModule.java
+++ b/src/main/java/com/nextcloud/client/di/AppModule.java
@@ -24,6 +24,7 @@
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.Resources;
import com.nextcloud.client.account.CurrentAccountProvider;
import com.nextcloud.client.account.UserAccountManager;
@@ -56,6 +57,11 @@ Context context(Application application) {
return application;
}
+ @Provides
+ Resources resources(Application application) {
+ return application.getResources();
+ }
+
@Provides
AppPreferences preferences(Application application) {
return AppPreferencesImpl.fromContext(application);
diff --git a/src/main/java/com/nextcloud/client/di/ComponentsModule.java b/src/main/java/com/nextcloud/client/di/ComponentsModule.java
index 9094f3b130d3..18c4a5b00225 100644
--- a/src/main/java/com/nextcloud/client/di/ComponentsModule.java
+++ b/src/main/java/com/nextcloud/client/di/ComponentsModule.java
@@ -56,7 +56,7 @@
import com.owncloud.android.ui.activity.UploadListActivity;
import com.owncloud.android.ui.activity.UploadPathActivity;
import com.owncloud.android.ui.activity.UserInfoActivity;
-import com.owncloud.android.ui.activity.WhatsNewActivity;
+import com.nextcloud.client.whatsnew.WhatsNewActivity;
import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
import com.owncloud.android.ui.errorhandling.ErrorShowActivity;
import com.owncloud.android.ui.fragment.ExtendedListFragment;
diff --git a/src/main/java/com/owncloud/android/ui/activity/WhatsNewActivity.java b/src/main/java/com/nextcloud/client/whatsnew/WhatsNewActivity.java
similarity index 76%
rename from src/main/java/com/owncloud/android/ui/activity/WhatsNewActivity.java
rename to src/main/java/com/nextcloud/client/whatsnew/WhatsNewActivity.java
index fc6c974eb621..c38968d0b6ba 100644
--- a/src/main/java/com/owncloud/android/ui/activity/WhatsNewActivity.java
+++ b/src/main/java/com/nextcloud/client/whatsnew/WhatsNewActivity.java
@@ -2,9 +2,11 @@
* Nextcloud Android client application
*
* @author Bartosz Przybylski
+ * @author Chris Narkiewicz
* Copyright (C) 2015 Bartosz Przybylski
* Copyright (C) 2015 ownCloud Inc.
* Copyright (C) 2016 Nextcloud.
+ * Copyright (C) 2019 Chris Narkiewicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -19,11 +21,8 @@
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see .
*/
+package com.nextcloud.client.whatsnew;
-package com.owncloud.android.ui.activity;
-
-import android.content.Context;
-import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
@@ -31,12 +30,11 @@
import android.widget.ImageButton;
import android.widget.TextView;
+import com.nextcloud.client.appinfo.AppInfo;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.preferences.AppPreferences;
-import com.owncloud.android.MainApp;
+import com.owncloud.android.BuildConfig;
import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountUtils;
-import com.owncloud.android.features.FeatureItem;
import com.owncloud.android.ui.adapter.FeaturesViewAdapter;
import com.owncloud.android.ui.adapter.FeaturesWebViewAdapter;
import com.owncloud.android.ui.whatsnew.ProgressIndicator;
@@ -57,6 +55,8 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
private ProgressIndicator mProgress;
private ViewPager mPager;
@Inject AppPreferences preferences;
+ @Inject AppInfo appInfo;
+ @Inject WhatsNewService whatsNew;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -73,12 +73,12 @@ protected void onCreate(Bundle savedInstanceState) {
if (showWebView) {
FeaturesWebViewAdapter featuresWebViewAdapter = new FeaturesWebViewAdapter(getSupportFragmentManager(),
- urls);
+ urls);
mProgress.setNumberOfSteps(featuresWebViewAdapter.getCount());
mPager.setAdapter(featuresWebViewAdapter);
} else {
FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(),
- getWhatsNew(this, preferences));
+ whatsNew.getWhatsNew());
mProgress.setNumberOfSteps(featuresViewAdapter.getCount());
mPager.setAdapter(featuresViewAdapter);
}
@@ -117,7 +117,7 @@ protected void onCreate(Bundle savedInstanceState) {
if (showWebView) {
tv.setText(R.string.app_name);
} else {
- tv.setText(String.format(getString(R.string.whats_new_title), MainApp.getVersionName()));
+ tv.setText(String.format(getString(R.string.whats_new_title), appInfo.getFormattedVersionCode()));
}
updateNextButtonIfNeeded();
@@ -140,21 +140,7 @@ private void updateNextButtonIfNeeded() {
}
private void onFinish() {
- preferences.setLastSeenVersionCode(MainApp.getVersionCode());
- }
-
- public static void runIfNeeded(Context context, AppPreferences preferences) {
- if (!context.getResources().getBoolean(R.bool.show_whats_new) || context instanceof WhatsNewActivity) {
- return;
- }
-
- if (shouldShow(context, preferences)) {
- context.startActivity(new Intent(context, WhatsNewActivity.class));
- }
- }
-
- private static boolean shouldShow(Context context, AppPreferences preferences) {
- return !(context instanceof PassCodeActivity) && getWhatsNew(context, preferences).length > 0;
+ preferences.setLastSeenVersionCode(BuildConfig.VERSION_CODE);
}
@Override
@@ -172,19 +158,5 @@ public void onPageSelected(int position) {
public void onPageScrollStateChanged(int state) {
// unused but to be implemented due to abstract parent
}
-
- static private boolean isFirstRun(Context context) {
- return AccountUtils.getCurrentOwnCloudAccount(context) == null;
- }
-
- private static FeatureItem[] getWhatsNew(Context context, AppPreferences preferences) {
- int itemVersionCode = 30030099;
-
- if (!isFirstRun(context) && MainApp.getVersionCode() >= itemVersionCode
- && preferences.getLastSeenVersionCode() < itemVersionCode) {
- return new FeatureItem[0];
- } else {
- return new FeatureItem[0];
- }
- }
}
+
diff --git a/src/main/java/com/nextcloud/client/whatsnew/WhatsNewModule.java b/src/main/java/com/nextcloud/client/whatsnew/WhatsNewModule.java
new file mode 100644
index 000000000000..88927dec52d2
--- /dev/null
+++ b/src/main/java/com/nextcloud/client/whatsnew/WhatsNewModule.java
@@ -0,0 +1,41 @@
+/* Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package com.nextcloud.client.whatsnew;
+
+import android.content.res.Resources;
+
+import com.nextcloud.client.account.CurrentAccountProvider;
+import com.nextcloud.client.preferences.AppPreferences;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class WhatsNewModule {
+
+ @Provides
+ @Singleton
+ WhatsNewService whatsNewService(Resources resources,
+ AppPreferences preferences,
+ CurrentAccountProvider accountProvider) {
+ return new WhatsNewService(resources, preferences, accountProvider);
+ }
+}
diff --git a/src/main/java/com/nextcloud/client/whatsnew/WhatsNewService.java b/src/main/java/com/nextcloud/client/whatsnew/WhatsNewService.java
new file mode 100644
index 000000000000..d3d622b6b9ee
--- /dev/null
+++ b/src/main/java/com/nextcloud/client/whatsnew/WhatsNewService.java
@@ -0,0 +1,75 @@
+/* Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package com.nextcloud.client.whatsnew;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+
+import com.nextcloud.client.account.CurrentAccountProvider;
+import com.nextcloud.client.preferences.AppPreferences;
+import com.owncloud.android.BuildConfig;
+import com.owncloud.android.R;
+import com.owncloud.android.features.FeatureItem;
+import com.owncloud.android.ui.activity.PassCodeActivity;
+
+public class WhatsNewService {
+
+ private Resources resources;
+ private AppPreferences preferences;
+ private CurrentAccountProvider accountProvider;
+
+ WhatsNewService(Resources resources,
+ AppPreferences preferences,
+ CurrentAccountProvider accountProvider) {
+ this.resources = resources;
+ this.preferences = preferences;
+ this.accountProvider = accountProvider;
+ }
+
+ public void launchActivityIfNeeded(Activity activity) {
+ if (!resources.getBoolean(R.bool.show_whats_new) || activity instanceof WhatsNewActivity) {
+ return;
+ }
+
+ if (shouldShow(activity)) {
+ activity.startActivity(new Intent(activity, WhatsNewActivity.class));
+ }
+ }
+
+ FeatureItem[] getWhatsNew() {
+ int itemVersionCode = 99999999;
+
+ if (!isFirstRun() && BuildConfig.VERSION_CODE >= itemVersionCode
+ && preferences.getLastSeenVersionCode() < itemVersionCode) {
+ return new FeatureItem[0];
+ } else {
+ return new FeatureItem[0];
+ }
+ }
+
+ private boolean shouldShow(Context callingContext) {
+ return !(callingContext instanceof PassCodeActivity) && getWhatsNew().length > 0;
+ }
+
+ public boolean isFirstRun() {
+ return accountProvider.getCurrentAccount() == null;
+ }
+}
diff --git a/src/main/java/com/owncloud/android/MainApp.java b/src/main/java/com/owncloud/android/MainApp.java
index 0e70e7ccd9fe..e6e0edcf13cd 100644
--- a/src/main/java/com/owncloud/android/MainApp.java
+++ b/src/main/java/com/owncloud/android/MainApp.java
@@ -45,10 +45,12 @@
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;
import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.appinfo.AppInfo;
import com.nextcloud.client.di.ActivityInjector;
import com.nextcloud.client.di.DaggerAppComponent;
import com.nextcloud.client.preferences.AppPreferences;
import com.nextcloud.client.preferences.AppPreferencesImpl;
+import com.nextcloud.client.whatsnew.WhatsNewService;
import com.owncloud.android.authentication.PassCodeManager;
import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.MediaFolder;
@@ -67,7 +69,6 @@
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
import com.owncloud.android.ui.activity.SyncedFoldersActivity;
-import com.owncloud.android.ui.activity.WhatsNewActivity;
import com.owncloud.android.ui.notifications.NotificationUtils;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.FilesSyncHelper;
@@ -150,6 +151,12 @@ public class MainApp extends MultiDexApplication implements
@Inject
protected UploadsStorageManager uploadsStorageManager;
+ @Inject
+ protected AppInfo appInfo;
+
+ @Inject
+ protected WhatsNewService whatsNew;
+
private PassCodeManager passCodeManager;
@SuppressWarnings("unused")
@@ -241,7 +248,7 @@ public void onCreate() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log_OC.d(activity.getClass().getSimpleName(), "onCreate(Bundle) starting");
- WhatsNewActivity.runIfNeeded(activity, preferences);
+ whatsNew.launchActivityIfNeeded(activity);
}
@Override
@@ -306,8 +313,8 @@ private void fixStoragePath() {
// find internal storage path that's indexable
boolean set = false;
for (StoragePoint storagePoint : storagePoints) {
- if (storagePoint.getStorageType().equals(StoragePoint.StorageType.INTERNAL) &&
- storagePoint.getPrivacyType().equals(StoragePoint.PrivacyType.PUBLIC)) {
+ if (storagePoint.getStorageType() == StoragePoint.StorageType.INTERNAL &&
+ storagePoint.getPrivacyType() == StoragePoint.PrivacyType.PUBLIC) {
preferences.setStoragePath(storagePoint.getPath());
preferences.removeKeysMigrationPreference();
set = true;
@@ -317,7 +324,7 @@ private void fixStoragePath() {
if (!set) {
for (StoragePoint storagePoint : storagePoints) {
- if (storagePoint.getPrivacyType().equals(StoragePoint.PrivacyType.PUBLIC)) {
+ if (storagePoint.getPrivacyType() == StoragePoint.PrivacyType.PUBLIC) {
preferences.setStoragePath(storagePoint.getPath());
preferences.removeKeysMigrationPreference();
set = true;
@@ -466,28 +473,6 @@ public static String getAccountType(Context context) {
return context.getResources().getString(R.string.account_type);
}
- // Non gradle build systems do not provide BuildConfig.VERSION_CODE
- // so we must fallback to this method :(
- public static int getVersionCode() {
- try {
- String thisPackageName = getAppContext().getPackageName();
- return getAppContext().getPackageManager().getPackageInfo(thisPackageName, 0).versionCode;
- } catch (PackageManager.NameNotFoundException e) {
- return 0;
- }
- }
-
- // Non gradle build systems do not provide BuildConfig.VERSION_CODE
- // so we must fallback to this method :(
- public static String getVersionName() {
- try {
- String thisPackageName = getAppContext().getPackageName();
- return getAppContext().getPackageManager().getPackageInfo(thisPackageName, 0).versionName;
- } catch (PackageManager.NameNotFoundException e) {
- return "";
- }
- }
-
// From AccountAuthenticator
// public static final String AUTHORITY = "org.owncloud";
public static String getAuthority() {
@@ -519,11 +504,6 @@ public static String getDataFolder() {
return getAppContext().getResources().getString(R.string.data_folder);
}
- // log_name
- public static String getLogName() {
- return getAppContext().getResources().getString(R.string.log_name);
- }
-
public static void showOnlyFilesOnDevice(boolean state) {
mOnlyOnDevice = state;
}
diff --git a/src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java b/src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java
index 01373e4ffd09..40adb20f6dea 100644
--- a/src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java
+++ b/src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java
@@ -33,7 +33,7 @@
* then error AccountManager.ERROR_CODE_CANCELED will be called on the response.
*/
-public class AccountAuthenticatorActivity extends AppCompatActivity {
+public abstract class AccountAuthenticatorActivity extends AppCompatActivity {
private AccountAuthenticatorResponse mAccountAuthenticatorResponse;
private Bundle mResultBundle;
diff --git a/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
index b733f9fafca2..1921902dbe73 100644
--- a/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
+++ b/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
@@ -250,7 +250,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
private boolean forceOldLoginMethod;
@Inject
- protected UserAccountManager accountManager;
+ UserAccountManager accountManager;
@Inject
protected AppPreferences preferences;
diff --git a/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java b/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java
index f20efbb5580a..b1e406f0a8e8 100644
--- a/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java
+++ b/src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java
@@ -118,7 +118,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
// else - fall back to UNKNOWN
Log_OC.d(TAG, "Authentication method found: " + authenticationMethodToString(authMethod));
- if (!authMethod.equals(AuthenticationMethod.UNKNOWN)) {
+ if (authMethod != AuthenticationMethod.UNKNOWN) {
result = new RemoteOperationResult(true, result.getHttpCode(), result.getHttpPhrase(), null);
}
ArrayList