Browse Source

Add AppInfo and WhatsNewService

Signed-off-by: Chris Narkiewicz <hello@ezaquarii.com>
Chris Narkiewicz 5 years ago
parent
commit
f0554ab59b
22 changed files with 292 additions and 96 deletions
  1. 1 1
      src/main/AndroidManifest.xml
  2. 37 0
      src/main/java/com/nextcloud/client/appinfo/AppInfo.java
  3. 30 0
      src/main/java/com/nextcloud/client/appinfo/AppInfoImpl.java
  4. 31 0
      src/main/java/com/nextcloud/client/appinfo/AppInfoModule.java
  5. 8 1
      src/main/java/com/nextcloud/client/di/AppComponent.java
  6. 6 0
      src/main/java/com/nextcloud/client/di/AppModule.java
  7. 1 1
      src/main/java/com/nextcloud/client/di/ComponentsModule.java
  8. 12 40
      src/main/java/com/nextcloud/client/whatsnew/WhatsNewActivity.java
  9. 41 0
      src/main/java/com/nextcloud/client/whatsnew/WhatsNewModule.java
  10. 75 0
      src/main/java/com/nextcloud/client/whatsnew/WhatsNewService.java
  11. 12 32
      src/main/java/com/owncloud/android/MainApp.java
  12. 1 1
      src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java
  13. 1 1
      src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java
  14. 1 1
      src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java
  15. 5 5
      src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java
  16. 14 4
      src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java
  17. 8 4
      src/main/java/com/owncloud/android/ui/activity/FirstRunActivity.java
  18. 1 1
      src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java
  19. 3 1
      src/main/java/com/owncloud/android/ui/asynctasks/LoadingVersionNumberTask.java
  20. 2 1
      src/main/java/com/owncloud/android/utils/BitmapUtils.java
  21. 2 1
      src/main/java/com/owncloud/android/utils/DisplayUtils.java
  22. 0 1
      src/main/res/values/setup.xml

+ 1 - 1
src/main/AndroidManifest.xml

@@ -314,7 +314,7 @@
         <activity
             android:name=".ui.trashbin.TrashbinActivity"
             android:configChanges="orientation|screenSize|keyboardHidden"/>
-        <activity android:name=".ui.activity.WhatsNewActivity"
+        <activity android:name="com.nextcloud.client.whatsnew.WhatsNewActivity"
                   android:theme="@style/Theme.ownCloud.noActionBar.Login" />
         <activity
             android:name=".ui.activity.FirstRunActivity"

+ 37 - 0
src/main/java/com/nextcloud/client/appinfo/AppInfo.java

@@ -0,0 +1,37 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+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();
+
+}

+ 30 - 0
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 <hello@ezaquarii.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package com.nextcloud.client.appinfo;
+
+import com.owncloud.android.BuildConfig;
+
+class AppInfoImpl implements AppInfo {
+
+    @Override
+    public String getFormattedVersionCode() {
+        return Integer.toString(BuildConfig.VERSION_CODE);
+    }
+}

+ 31 - 0
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 <hello@ezaquarii.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package com.nextcloud.client.appinfo;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class AppInfoModule {
+    @Provides
+    AppInfo appInfo() {
+        return new AppInfoImpl();
+    }
+}

+ 8 - 1
src/main/java/com/nextcloud/client/di/AppComponent.java

@@ -22,16 +22,23 @@ package com.nextcloud.client.di;
 
 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);
 

+ 6 - 0
src/main/java/com/nextcloud/client/di/AppModule.java

@@ -24,6 +24,7 @@ import android.accounts.AccountManager;
 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 @@ class AppModule {
         return application;
     }
 
+    @Provides
+    Resources resources(Application application) {
+        return application.getResources();
+    }
+
     @Provides
     AppPreferences preferences(Application application) {
         return AppPreferencesImpl.fromContext(application);

+ 1 - 1
src/main/java/com/nextcloud/client/di/ComponentsModule.java

@@ -56,7 +56,7 @@ import com.owncloud.android.ui.activity.UploadFilesActivity;
 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;

+ 12 - 40
src/main/java/com/owncloud/android/ui/activity/WhatsNewActivity.java → 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 <hello@ezaquarii.com>
  *
  * 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 <http://www.gnu.org/licenses/>.
  */
+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.Button;
 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 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
 
         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 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
         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 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
     }
 
     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 class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
     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];
-        }
-    }
 }
+

+ 41 - 0
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 <hello@ezaquarii.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+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);
+    }
+}

+ 75 - 0
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 <hello@ezaquarii.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+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;
+    }
+}

+ 12 - 32
src/main/java/com/owncloud/android/MainApp.java

@@ -45,10 +45,12 @@ import android.view.WindowManager;
 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.common.utils.Log_OC;
 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 class MainApp extends MultiDexApplication implements
             @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 @@ public class MainApp extends MultiDexApplication implements
                         // 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 @@ public class MainApp extends MultiDexApplication implements
 
                         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 class MainApp extends MultiDexApplication implements
         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 class MainApp extends MultiDexApplication implements
         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;
     }

+ 1 - 1
src/main/java/com/owncloud/android/authentication/AccountAuthenticatorActivity.java

@@ -33,7 +33,7 @@ import androidx.appcompat.app.AppCompatActivity;
  * 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;

+ 1 - 1
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;

+ 1 - 1
src/main/java/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java

@@ -118,7 +118,7 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation {
         // 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<Object> data = new ArrayList<>();

+ 5 - 5
src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java

@@ -591,17 +591,17 @@ public class DocumentsStorageProvider extends DocumentsProvider {
     @SuppressLint("UseSparseArrays")
     private void initiateStorageMap() throws FileNotFoundException {
 
-        rootIdToStorageManager = new HashMap<>();
-
         Context context = getContext();
 
+        final Account[] allAccounts = accountManager.getAccounts();
+        rootIdToStorageManager = new HashMap<>(allAccounts.length);
+
         if (context == null) {
             throw new FileNotFoundException("Context may not be null!");
         }
 
-        ContentResolver contentResolver = context.getContentResolver();
-
-        for (Account account : accountManager.getAccounts()) {
+        final ContentResolver contentResolver = context.getContentResolver();
+        for (Account account : allAccounts) {
             final FileDataStorageManager storageManager = new FileDataStorageManager(account, contentResolver);
             final OCFile rootDir = storageManager.getFileByPath(ROOT_PATH);
             rootIdToStorageManager.put(rootDir.getFileId(), storageManager);

+ 14 - 4
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -59,9 +59,11 @@ import android.widget.ImageView;
 
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 import com.google.android.material.snackbar.Snackbar;
+import com.nextcloud.client.appinfo.AppInfo;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
+import com.owncloud.android.BuildConfig;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
@@ -216,7 +218,12 @@ public class FileDisplayActivity extends FileActivity
     private boolean searchOpen;
 
     private SearchView searchView;
-    @Inject AppPreferences preferences;
+
+    @Inject
+    protected AppPreferences preferences;
+
+    @Inject
+    protected AppInfo appInfo;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -364,7 +371,7 @@ public class FileDisplayActivity extends FileActivity
             int lastSeenVersion = arbitraryDataProvider.getIntegerValue(account,
                                                                         AppPreferencesImpl.AUTO_PREF__LAST_SEEN_VERSION_CODE);
 
-            if (MainApp.getVersionCode() > lastSeenVersion) {
+            if (BuildConfig.VERSION_CODE > lastSeenVersion) {
                 OwnCloudVersion serverVersion = AccountUtils.getServerVersionForAccount(account, this);
 
                 if (serverVersion == null) {
@@ -375,8 +382,11 @@ public class FileDisplayActivity extends FileActivity
                     DisplayUtils.showServerOutdatedSnackbar(this);
                 }
 
-                arbitraryDataProvider.storeOrUpdateKeyValue(account.name, AppPreferencesImpl.AUTO_PREF__LAST_SEEN_VERSION_CODE,
-                                                            String.valueOf(MainApp.getVersionCode()));
+                arbitraryDataProvider.storeOrUpdateKeyValue(
+                    account.name,
+                    AppPreferencesImpl.AUTO_PREF__LAST_SEEN_VERSION_CODE,
+                    appInfo.getFormattedVersionCode()
+                );
             }
         }
     }

+ 8 - 4
src/main/java/com/owncloud/android/ui/activity/FirstRunActivity.java

@@ -40,8 +40,11 @@ import android.widget.TextView;
 import androidx.viewpager.widget.ViewPager;
 
 import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.appinfo.AppInfo;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
+import com.nextcloud.client.whatsnew.WhatsNewService;
+import com.owncloud.android.BuildConfig;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
@@ -66,6 +69,8 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
 
     @Inject UserAccountManager userAccountManager;
     @Inject AppPreferences preferences;
+    @Inject AppInfo appInfo;
+    @Inject WhatsNewService whatsNew;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -114,7 +119,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
         ViewPager viewPager = findViewById(R.id.contentPanel);
 
         // Sometimes, accounts are not deleted when you uninstall the application so we'll do it now
-        if (isFirstRun(this)) {
+        if (whatsNew.isFirstRun()) {
             AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
             if (am != null) {
                 for (Account account : userAccountManager.getAccounts()) {
@@ -123,8 +128,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
             }
         }
 
-        FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(),
-                getFirstRun());
+        FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(), getFirstRun());
         progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount());
         viewPager.setAdapter(featuresViewAdapter);
 
@@ -176,7 +180,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
     }
 
     private void onFinish() {
-        preferences.setLastSeenVersionCode(MainApp.getVersionCode());
+        preferences.setLastSeenVersionCode(BuildConfig.VERSION_CODE);
     }
 
     @Override

+ 1 - 1
src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java

@@ -579,7 +579,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA
 
         // custom folders newly created aren't in the list already,
         // so triggering a refresh
-        if (MediaFolderType.CUSTOM.equals(syncedFolder.getType()) && syncedFolder.getId() == UNPERSISTED_ID) {
+        if (MediaFolderType.CUSTOM == syncedFolder.getType() && syncedFolder.getId() == UNPERSISTED_ID) {
             SyncedFolderDisplayItem newCustomFolder = new SyncedFolderDisplayItem(
                     SyncedFolder.UNPERSISTED_ID, syncedFolder.getLocalPath(), syncedFolder.getRemotePath(),
                     syncedFolder.getWifiOnly(), syncedFolder.getChargingOnly(), syncedFolder.getSubfolderByDate(),

+ 3 - 1
src/main/java/com/owncloud/android/ui/asynctasks/LoadingVersionNumberTask.java

@@ -30,6 +30,7 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.charset.Charset;
 
 /**
  * Class for loading the version number
@@ -46,7 +47,8 @@ public class LoadingVersionNumberTask extends AsyncTask<String, Void, Integer> {
     protected Integer doInBackground(String... args) {
         try {
             URL url = new URL(args[0]);
-            try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))){
+            final Charset charset = Charset.defaultCharset();
+            try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), charset))) {
                 return Integer.parseInt(in.readLine());
 
             } catch (IOException e) {

+ 2 - 1
src/main/java/com/owncloud/android/utils/BitmapUtils.java

@@ -31,6 +31,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 
 import org.apache.commons.codec.binary.Hex;
 
+import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Locale;
@@ -362,7 +363,7 @@ public final class BitmapUtils {
 
     public static String md5(String string) throws NoSuchAlgorithmException {
         MessageDigest md5 = MessageDigest.getInstance("MD5");
-        md5.update(string.getBytes());
+        md5.update(string.getBytes(Charset.defaultCharset()));
 
         return new String(Hex.encodeHex(md5.digest()));
     }

+ 2 - 1
src/main/java/com/owncloud/android/utils/DisplayUtils.java

@@ -85,6 +85,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.net.IDN;
+import java.nio.charset.Charset;
 import java.text.DateFormat;
 import java.util.Collection;
 import java.util.Date;
@@ -649,7 +650,7 @@ public final class DisplayUtils {
      */
     public static String getData(InputStream inputStream) {
 
-        BufferedReader buffreader = new BufferedReader(new InputStreamReader(inputStream));
+        BufferedReader buffreader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));
         String line;
         StringBuilder text = new StringBuilder();
         try {

+ 0 - 1
src/main/res/values/setup.xml

@@ -16,7 +16,6 @@
     <string name="db_file">nextcloud.db</string>
     <string name="db_name">nextcloud</string>
     <string name="data_folder">nextcloud</string>
-    <string name="log_name">nextcloud</string>
     <string name="default_display_name_for_root_folder">Nextcloud</string>
     <string name="user_agent">Mozilla/5.0 (Android) ownCloud-android/%1$s</string>
     <string name="nextcloud_user_agent">Mozilla/5.0 (Android) Nextcloud-android/%1$s</string>