From 2536574f5d8217b098035a7bf689985b8a17c2b3 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Thu, 28 Nov 2024 22:14:29 -0600 Subject: [PATCH] Convert CommonsApplicationModule to kotlin --- .../commons/di/CommonsApplicationModule.java | 314 ------------------ .../commons/di/CommonsApplicationModule.kt | 239 +++++++++++++ .../nrw/commons/TestCommonsApplication.kt | 16 +- 3 files changed, 245 insertions(+), 324 deletions(-) delete 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/CommonsApplicationModule.kt 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 deleted file mode 100644 index 3f9344184..000000000 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java +++ /dev/null @@ -1,314 +0,0 @@ -package fr.free.nrw.commons.di; - -import android.app.Activity; -import android.content.ContentProviderClient; -import android.content.ContentResolver; -import android.content.Context; -import android.view.inputmethod.InputMethodManager; -import androidx.collection.LruCache; -import androidx.room.Room; -import androidx.room.migration.Migration; -import androidx.sqlite.db.SupportSQLiteDatabase; -import com.google.gson.Gson; -import dagger.Module; -import dagger.Provides; -import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.R; -import fr.free.nrw.commons.auth.SessionManager; -import fr.free.nrw.commons.contributions.ContributionDao; -import fr.free.nrw.commons.customselector.database.NotForUploadStatusDao; -import fr.free.nrw.commons.customselector.database.UploadedStatusDao; -import fr.free.nrw.commons.customselector.ui.selector.ImageFileLoader; -import fr.free.nrw.commons.data.DBOpenHelper; -import fr.free.nrw.commons.db.AppDatabase; -import fr.free.nrw.commons.kvstore.JsonKvStore; -import fr.free.nrw.commons.location.LocationServiceManager; -import fr.free.nrw.commons.nearby.PlaceDao; -import fr.free.nrw.commons.review.ReviewDao; -import fr.free.nrw.commons.settings.Prefs; -import fr.free.nrw.commons.upload.UploadController; -import fr.free.nrw.commons.upload.depicts.DepictsDao; -import fr.free.nrw.commons.utils.ConfigUtils; -import fr.free.nrw.commons.wikidata.WikidataEditListener; -import fr.free.nrw.commons.wikidata.WikidataEditListenerImpl; -import io.reactivex.Scheduler; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import javax.inject.Named; -import javax.inject.Singleton; - -/** - * The Dependency Provider class for Commons Android. - * - * Provides all sorts of ContentProviderClients used by the app - * along with the Liscences, AccountUtility, UploadController, Logged User, - * Location manager etc - */ -@Module -@SuppressWarnings({"WeakerAccess", "unused"}) -public class CommonsApplicationModule { - private Context applicationContext; - public static final String IO_THREAD="io_thread"; - public static final String MAIN_THREAD="main_thread"; - private AppDatabase appDatabase; - - static final Migration MIGRATION_1_2 = new Migration(1, 2) { - @Override - public void migrate(SupportSQLiteDatabase database) { - database.execSQL("ALTER TABLE contribution " - + " ADD COLUMN hasInvalidLocation INTEGER NOT NULL DEFAULT 0"); - } - }; - - public CommonsApplicationModule(Context applicationContext) { - this.applicationContext = applicationContext; - } - - /** - * Provides ImageFileLoader used to fetch device images. - * @param context - * @return - */ - @Provides - public ImageFileLoader providesImageFileLoader(Context context) { - return new ImageFileLoader(context); - } - - @Provides - public Context providesApplicationContext() { - return this.applicationContext; - } - - @Provides - public InputMethodManager provideInputMethodManager() { - return (InputMethodManager) applicationContext.getSystemService(Activity.INPUT_METHOD_SERVICE); - } - - @Provides - @Named("licenses") - public List provideLicenses(Context context) { - List licenseItems = new ArrayList<>(); - licenseItems.add(context.getString(R.string.license_name_cc0)); - licenseItems.add(context.getString(R.string.license_name_cc_by)); - licenseItems.add(context.getString(R.string.license_name_cc_by_sa)); - licenseItems.add(context.getString(R.string.license_name_cc_by_four)); - licenseItems.add(context.getString(R.string.license_name_cc_by_sa_four)); - return licenseItems; - } - - @Provides - @Named("licenses_by_name") - public Map provideLicensesByName(Context context) { - Map byName = new HashMap<>(); - byName.put(context.getString(R.string.license_name_cc0), Prefs.Licenses.CC0); - byName.put(context.getString(R.string.license_name_cc_by), Prefs.Licenses.CC_BY_3); - byName.put(context.getString(R.string.license_name_cc_by_sa), Prefs.Licenses.CC_BY_SA_3); - byName.put(context.getString(R.string.license_name_cc_by_four), Prefs.Licenses.CC_BY_4); - byName.put(context.getString(R.string.license_name_cc_by_sa_four), Prefs.Licenses.CC_BY_SA_4); - return byName; - } - - /** - * Provides an instance of CategoryContentProviderClient i.e. the categories - * that are there in local storage - */ - @Provides - @Named("category") - public ContentProviderClient provideCategoryContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.CATEGORY_AUTHORITY); - } - - /** - * This method is used to provide instance of RecentSearchContentProviderClient - * which provides content of Recent Searches from database - * @param context - * @return returns RecentSearchContentProviderClient - */ - @Provides - @Named("recentsearch") - public ContentProviderClient provideRecentSearchContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.RECENT_SEARCH_AUTHORITY); - } - - @Provides - @Named("contribution") - public ContentProviderClient provideContributionContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.CONTRIBUTION_AUTHORITY); - } - - @Provides - @Named("modification") - public ContentProviderClient provideModificationContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.MODIFICATION_AUTHORITY); - } - - @Provides - @Named("bookmarks") - public ContentProviderClient provideBookmarkContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.BOOKMARK_AUTHORITY); - } - - @Provides - @Named("bookmarksLocation") - public ContentProviderClient provideBookmarkLocationContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.BOOKMARK_LOCATIONS_AUTHORITY); - } - - @Provides - @Named("bookmarksItem") - public ContentProviderClient provideBookmarkItemContentProviderClient(Context context) { - return context.getContentResolver().acquireContentProviderClient(BuildConfig.BOOKMARK_ITEMS_AUTHORITY); - } - - /** - * This method is used to provide instance of RecentLanguagesContentProvider - * which provides content of recent used languages from database - * @param context Context - * @return returns RecentLanguagesContentProvider - */ - @Provides - @Named("recent_languages") - public ContentProviderClient provideRecentLanguagesContentProviderClient(final Context context) { - return context.getContentResolver() - .acquireContentProviderClient(BuildConfig.RECENT_LANGUAGE_AUTHORITY); - } - - /** - * Provides a Json store instance(JsonKvStore) which keeps - * the provided Gson in it's instance - * @param gson stored inside the store instance - */ - @Provides - @Named("default_preferences") - public JsonKvStore providesDefaultKvStore(Context context, Gson gson) { - String storeName = context.getPackageName() + "_preferences"; - return new JsonKvStore(context, storeName, gson); - } - - @Provides - public UploadController providesUploadController(SessionManager sessionManager, - @Named("default_preferences") JsonKvStore kvStore, - Context context, ContributionDao contributionDao) { - return new UploadController(sessionManager, context, kvStore); - } - - @Provides - @Singleton - public LocationServiceManager provideLocationServiceManager(Context context) { - return new LocationServiceManager(context); - } - - @Provides - @Singleton - public DBOpenHelper provideDBOpenHelper(Context context) { - return new DBOpenHelper(context); - } - - @Provides - @Singleton - @Named("thumbnail-cache") - public LruCache provideLruCache() { - return new LruCache<>(1024); - } - - @Provides - @Singleton - public WikidataEditListener provideWikidataEditListener() { - return new WikidataEditListenerImpl(); - } - - /** - * Provides app flavour. Can be used to alter flows in the app - * @return - */ - @Named("isBeta") - @Provides - @Singleton - public boolean provideIsBetaVariant() { - return ConfigUtils.isBetaFlavour(); - } - - /** - * Provide JavaRx IO scheduler which manages IO operations - * across various Threads - */ - @Named(IO_THREAD) - @Provides - public Scheduler providesIoThread(){ - return Schedulers.io(); - } - - @Named(MAIN_THREAD) - @Provides - public Scheduler providesMainThread() { - return AndroidSchedulers.mainThread(); - } - - @Named("username") - @Provides - public String provideLoggedInUsername(SessionManager sessionManager) { - return Objects.toString(sessionManager.getUserName(), ""); - } - - @Provides - @Singleton - public AppDatabase provideAppDataBase() { - appDatabase = Room.databaseBuilder(applicationContext, AppDatabase.class, "commons_room.db") - .addMigrations(MIGRATION_1_2) - .fallbackToDestructiveMigration() - .build(); - return appDatabase; - } - - @Provides - public ContributionDao providesContributionsDao(AppDatabase appDatabase) { - return appDatabase.contributionDao(); - } - - @Provides - public PlaceDao providesPlaceDao(AppDatabase appDatabase) { - return appDatabase.PlaceDao(); - } - - /** - * Get the reference of DepictsDao class. - */ - @Provides - public DepictsDao providesDepictDao(AppDatabase appDatabase) { - return appDatabase.DepictsDao(); - } - - /** - * Get the reference of UploadedStatus class. - */ - @Provides - public UploadedStatusDao providesUploadedStatusDao(AppDatabase appDatabase) { - return appDatabase.UploadedStatusDao(); - } - - /** - * Get the reference of NotForUploadStatus class. - */ - @Provides - public NotForUploadStatusDao providesNotForUploadStatusDao(AppDatabase appDatabase) { - return appDatabase.NotForUploadStatusDao(); - } - - /** - * Get the reference of ReviewDao class - */ - @Provides - public ReviewDao providesReviewDao(AppDatabase appDatabase){ - return appDatabase.ReviewDao(); - } - - @Provides - public ContentResolver providesContentResolver(Context context){ - return context.getContentResolver(); - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.kt b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.kt new file mode 100644 index 000000000..6f883769f --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.kt @@ -0,0 +1,239 @@ +package fr.free.nrw.commons.di + +import android.app.Activity +import android.content.ContentProviderClient +import android.content.ContentResolver +import android.content.Context +import android.view.inputmethod.InputMethodManager +import androidx.collection.LruCache +import androidx.room.Room.databaseBuilder +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import com.google.gson.Gson +import dagger.Module +import dagger.Provides +import fr.free.nrw.commons.BuildConfig +import fr.free.nrw.commons.R +import fr.free.nrw.commons.auth.SessionManager +import fr.free.nrw.commons.contributions.ContributionDao +import fr.free.nrw.commons.customselector.database.NotForUploadStatusDao +import fr.free.nrw.commons.customselector.database.UploadedStatusDao +import fr.free.nrw.commons.customselector.ui.selector.ImageFileLoader +import fr.free.nrw.commons.data.DBOpenHelper +import fr.free.nrw.commons.db.AppDatabase +import fr.free.nrw.commons.kvstore.JsonKvStore +import fr.free.nrw.commons.location.LocationServiceManager +import fr.free.nrw.commons.nearby.PlaceDao +import fr.free.nrw.commons.review.ReviewDao +import fr.free.nrw.commons.settings.Prefs +import fr.free.nrw.commons.upload.UploadController +import fr.free.nrw.commons.upload.depicts.DepictsDao +import fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour +import fr.free.nrw.commons.wikidata.WikidataEditListener +import fr.free.nrw.commons.wikidata.WikidataEditListenerImpl +import io.reactivex.Scheduler +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import java.util.Objects +import javax.inject.Named +import javax.inject.Singleton + +/** + * The Dependency Provider class for Commons Android. + * Provides all sorts of ContentProviderClients used by the app + * along with the Liscences, AccountUtility, UploadController, Logged User, + * Location manager etc + */ +@Module +@Suppress("unused") +open class CommonsApplicationModule(private val applicationContext: Context) { + @Provides + fun providesImageFileLoader(context: Context): ImageFileLoader = + ImageFileLoader(context) + + @Provides + fun providesApplicationContext(): Context = + applicationContext + + @Provides + fun provideInputMethodManager(): InputMethodManager = + applicationContext.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + + @Provides + @Named("licenses") + fun provideLicenses(context: Context): List = listOf( + context.getString(R.string.license_name_cc0), + context.getString(R.string.license_name_cc_by), + context.getString(R.string.license_name_cc_by_sa), + context.getString(R.string.license_name_cc_by_four), + context.getString(R.string.license_name_cc_by_sa_four) + ) + + @Provides + @Named("licenses_by_name") + fun provideLicensesByName(context: Context): Map = mapOf( + context.getString(R.string.license_name_cc0) to Prefs.Licenses.CC0, + context.getString(R.string.license_name_cc_by) to Prefs.Licenses.CC_BY_3, + context.getString(R.string.license_name_cc_by_sa) to Prefs.Licenses.CC_BY_SA_3, + context.getString(R.string.license_name_cc_by_four) to Prefs.Licenses.CC_BY_4, + context.getString(R.string.license_name_cc_by_sa_four) to Prefs.Licenses.CC_BY_SA_4 + ) + + /** + * Provides an instance of CategoryContentProviderClient i.e. the categories + * that are there in local storage + */ + @Provides + @Named("category") + open fun provideCategoryContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.CATEGORY_AUTHORITY) + + @Provides + @Named("recentsearch") + fun provideRecentSearchContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.RECENT_SEARCH_AUTHORITY) + + @Provides + @Named("contribution") + open fun provideContributionContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.CONTRIBUTION_AUTHORITY) + + @Provides + @Named("modification") + open fun provideModificationContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.MODIFICATION_AUTHORITY) + + @Provides + @Named("bookmarks") + fun provideBookmarkContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.BOOKMARK_AUTHORITY) + + @Provides + @Named("bookmarksLocation") + fun provideBookmarkLocationContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.BOOKMARK_LOCATIONS_AUTHORITY) + + @Provides + @Named("bookmarksItem") + fun provideBookmarkItemContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.BOOKMARK_ITEMS_AUTHORITY) + + /** + * This method is used to provide instance of RecentLanguagesContentProvider + * which provides content of recent used languages from database + * @param context Context + * @return returns RecentLanguagesContentProvider + */ + @Provides + @Named("recent_languages") + fun provideRecentLanguagesContentProviderClient(context: Context): ContentProviderClient? = + context.contentResolver.acquireContentProviderClient(BuildConfig.RECENT_LANGUAGE_AUTHORITY) + + /** + * Provides a Json store instance(JsonKvStore) which keeps + * the provided Gson in it's instance + * @param gson stored inside the store instance + */ + @Provides + @Named("default_preferences") + open fun providesDefaultKvStore(context: Context, gson: Gson): JsonKvStore = + JsonKvStore(context, "${context.packageName}_preferences", gson) + + @Provides + fun providesUploadController( + sessionManager: SessionManager, + @Named("default_preferences") kvStore: JsonKvStore, + context: Context + ): UploadController = UploadController(sessionManager, context, kvStore) + + @Provides + @Singleton + open fun provideLocationServiceManager(context: Context): LocationServiceManager = + LocationServiceManager(context) + + @Provides + @Singleton + open fun provideDBOpenHelper(context: Context): DBOpenHelper = + DBOpenHelper(context) + + @Provides + @Singleton + @Named("thumbnail-cache") + open fun provideLruCache(): LruCache = + LruCache(1024) + + @Provides + @Singleton + fun provideWikidataEditListener(): WikidataEditListener = + WikidataEditListenerImpl() + + @Named("isBeta") + @Provides + @Singleton + fun provideIsBetaVariant(): Boolean = + isBetaFlavour + + @Named(IO_THREAD) + @Provides + fun providesIoThread(): Scheduler = + Schedulers.io() + + @Named(MAIN_THREAD) + @Provides + fun providesMainThread(): Scheduler = + AndroidSchedulers.mainThread() + + @Named("username") + @Provides + fun provideLoggedInUsername(sessionManager: SessionManager): String = + Objects.toString(sessionManager.userName, "") + + @Provides + @Singleton + fun provideAppDataBase(): AppDatabase = databaseBuilder( + applicationContext, + AppDatabase::class.java, + "commons_room.db" + ).addMigrations(MIGRATION_1_2).fallbackToDestructiveMigration().build() + + @Provides + fun providesContributionsDao(appDatabase: AppDatabase): ContributionDao = + appDatabase.contributionDao() + + @Provides + fun providesPlaceDao(appDatabase: AppDatabase): PlaceDao = + appDatabase.PlaceDao() + + @Provides + fun providesDepictDao(appDatabase: AppDatabase): DepictsDao = + appDatabase.DepictsDao() + + @Provides + fun providesUploadedStatusDao(appDatabase: AppDatabase): UploadedStatusDao = + appDatabase.UploadedStatusDao() + + @Provides + fun providesNotForUploadStatusDao(appDatabase: AppDatabase): NotForUploadStatusDao = + appDatabase.NotForUploadStatusDao() + + @Provides + fun providesReviewDao(appDatabase: AppDatabase): ReviewDao = + appDatabase.ReviewDao() + + @Provides + fun providesContentResolver(context: Context): ContentResolver = + context.contentResolver + + companion object { + const val IO_THREAD: String = "io_thread" + const val MAIN_THREAD: String = "main_thread" + + val MIGRATION_1_2: Migration = object : Migration(1, 2) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( + "ALTER TABLE contribution " + " ADD COLUMN hasInvalidLocation INTEGER NOT NULL DEFAULT 0" + ) + } + } + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt b/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt index 4c38a30ff..c0e3bda08 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt @@ -37,9 +37,8 @@ class TestCommonsApplication : Application() { } @Suppress("MemberVisibilityCanBePrivate") -class MockCommonsApplicationModule( - appContext: Context, -) : CommonsApplicationModule(appContext) { +class MockCommonsApplicationModule(appContext: Context) : CommonsApplicationModule(appContext) { + val defaultSharedPreferences: JsonKvStore = mock() val locationServiceManager: LocationServiceManager = mock() val mockDbOpenHelper: DBOpenHelper = mock() @@ -50,16 +49,13 @@ class MockCommonsApplicationModule( val modificationClient: ContentProviderClient = mock() val uploadPrefs: JsonKvStore = mock() - override fun provideCategoryContentProviderClient(context: Context?): ContentProviderClient = categoryClient + override fun provideCategoryContentProviderClient(context: Context): ContentProviderClient = categoryClient - override fun provideContributionContentProviderClient(context: Context?): ContentProviderClient = contributionClient + override fun provideContributionContentProviderClient(context: Context): ContentProviderClient = contributionClient - override fun provideModificationContentProviderClient(context: Context?): ContentProviderClient = modificationClient + override fun provideModificationContentProviderClient(context: Context): ContentProviderClient = modificationClient - override fun providesDefaultKvStore( - context: Context, - gson: Gson, - ): JsonKvStore = defaultSharedPreferences + override fun providesDefaultKvStore(context: Context, gson: Gson): JsonKvStore = defaultSharedPreferences override fun provideLocationServiceManager(context: Context): LocationServiceManager = locationServiceManager