diff --git a/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt b/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt index 33a731d55..0298d4a5e 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/language/viewmodel/SaveLanguagesAndFinish.kt @@ -17,6 +17,7 @@ */ package org.kiwix.kiwixmobile.language.viewmodel +import android.annotation.SuppressLint import androidx.appcompat.app.AppCompatActivity import io.reactivex.Flowable import io.reactivex.schedulers.Schedulers @@ -24,6 +25,7 @@ import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao import org.kiwix.kiwixmobile.core.zim_manager.Language +@SuppressLint("CheckResult") data class SaveLanguagesAndFinish( val languages: List, val languageDao: NewLanguagesDao diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt index 9243b46f0..9a680d048 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt @@ -245,6 +245,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { override fun onDestroyView() { super.onDestroyView() + availableSpaceCalculator.dispose() fragmentDestinationDownloadBinding?.libraryList?.adapter = null fragmentDestinationDownloadBinding = null } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/webserver/WebServerHelper.kt b/app/src/main/java/org/kiwix/kiwixmobile/webserver/WebServerHelper.kt index 7ced19e69..09920833f 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/webserver/WebServerHelper.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/webserver/WebServerHelper.kt @@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.webserver import android.util.Log import io.reactivex.Flowable import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.Disposable import org.kiwix.kiwixmobile.core.utils.DEFAULT_PORT import org.kiwix.kiwixmobile.core.utils.ServerUtils import org.kiwix.kiwixmobile.core.utils.ServerUtils.INVALID_IP @@ -40,6 +41,7 @@ class WebServerHelper @Inject constructor( ) { private var kiwixServer: KiwixServer? = null private var isServerStarted = false + private var validIpAddressDisposable: Disposable? = null fun startServerHelper(selectedBooksPath: ArrayList): Boolean { val ip = getIpAddress() @@ -79,7 +81,7 @@ class WebServerHelper @Inject constructor( // If no ip is found after 15 seconds, dismisses the progress dialog @Suppress("MagicNumber") fun pollForValidIpAddress() { - Flowable.interval(1, TimeUnit.SECONDS) + validIpAddressDisposable = Flowable.interval(1, TimeUnit.SECONDS) .map { getIp() } .filter { s: String? -> s != INVALID_IP } .timeout(15, TimeUnit.SECONDS) @@ -96,6 +98,10 @@ class WebServerHelper @Inject constructor( } } + fun dispose() { + validIpAddressDisposable?.dispose() + } + companion object { private const val TAG = "WebServerHelper" } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/webserver/wifi_hotspot/HotspotService.kt b/app/src/main/java/org/kiwix/kiwixmobile/webserver/wifi_hotspot/HotspotService.kt index fca38f16e..50daf9961 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/webserver/wifi_hotspot/HotspotService.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/webserver/wifi_hotspot/HotspotService.kt @@ -64,6 +64,7 @@ class HotspotService : } override fun onDestroy() { + webServerHelper?.dispose() hotspotStateReceiver?.let(this@HotspotService::unregisterReceiver) super.onDestroy() } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/Fat32Checker.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/Fat32Checker.kt index 740081e7c..1ced19f79 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/Fat32Checker.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/Fat32Checker.kt @@ -17,6 +17,7 @@ */ package org.kiwix.kiwixmobile.zimManager +import android.annotation.SuppressLint import android.os.FileObserver import io.reactivex.Flowable import io.reactivex.functions.BiFunction @@ -32,6 +33,7 @@ import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CAN_WRITE_4GB import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.INCONCLUSIVE import java.io.File +@SuppressLint("CheckResult") class Fat32Checker constructor( sharedPreferenceUtil: SharedPreferenceUtil, private val fileSystemCheckers: List diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt index a614c6c1c..b447ee661 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/ZimManageViewModel.kt @@ -246,12 +246,14 @@ class ZimManageViewModel @Inject constructor( .observeOn(Schedulers.io()) .subscribe( { - kiwixService.library - .retry(5) - .subscribe(library::onNext) { - it.printStackTrace() - library.onNext(LibraryNetworkEntity().apply { book = LinkedList() }) - } + compositeDisposable?.add( + kiwixService.library + .retry(5) + .subscribe(library::onNext) { + it.printStackTrace() + library.onNext(LibraryNetworkEntity().apply { book = LinkedList() }) + } + ) }, Throwable::printStackTrace ) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/libraryView/AvailableSpaceCalculator.kt b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/libraryView/AvailableSpaceCalculator.kt index 1c466ef14..66647a037 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zimManager/libraryView/AvailableSpaceCalculator.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zimManager/libraryView/AvailableSpaceCalculator.kt @@ -21,6 +21,7 @@ package org.kiwix.kiwixmobile.zimManager.libraryView import eu.mhutti1.utils.storage.Bytes import eu.mhutti1.utils.storage.Kb import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel @@ -32,12 +33,13 @@ class AvailableSpaceCalculator @Inject constructor( private val downloadDao: FetchDownloadDao, private val storageCalculator: StorageCalculator ) { + private var availableSpaceCalculatorDisposable: Disposable? = null fun hasAvailableSpaceFor( bookItem: LibraryListItem.BookItem, successAction: (LibraryListItem.BookItem) -> Unit, failureAction: (String) -> Unit ) { - downloadDao.allDownloads() + availableSpaceCalculatorDisposable = downloadDao.allDownloads() .map { it.map(DownloadModel::bytesRemaining).sum() } .map { bytesToBeDownloaded -> storageCalculator.availableBytes() - bytesToBeDownloaded } .subscribeOn(Schedulers.io()) @@ -50,4 +52,8 @@ class AvailableSpaceCalculator @Inject constructor( } } } + + fun dispose() { + availableSpaceCalculatorDisposable?.dispose() + } } diff --git a/buildSrc/src/main/kotlin/plugin/AllProjectConfigurer.kt b/buildSrc/src/main/kotlin/plugin/AllProjectConfigurer.kt index cb44bff58..09dfb8a0a 100644 --- a/buildSrc/src/main/kotlin/plugin/AllProjectConfigurer.kt +++ b/buildSrc/src/main/kotlin/plugin/AllProjectConfigurer.kt @@ -100,7 +100,6 @@ class AllProjectConfigurer { "GoogleAppIndexingApiWarning", "LockedOrientationActivity", //TODO stop ignoring below this - "CheckResult", "LabelFor", "LogConditional", "ConvertToWebp", diff --git a/core/src/main/java/eu/mhutti1/utils/storage/StorageSelectDialog.kt b/core/src/main/java/eu/mhutti1/utils/storage/StorageSelectDialog.kt index 5345199b2..368ae1463 100644 --- a/core/src/main/java/eu/mhutti1/utils/storage/StorageSelectDialog.kt +++ b/core/src/main/java/eu/mhutti1/utils/storage/StorageSelectDialog.kt @@ -30,6 +30,7 @@ import eu.mhutti1.utils.storage.adapter.StorageAdapter import eu.mhutti1.utils.storage.adapter.StorageDelegate import io.reactivex.Flowable import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import org.kiwix.kiwixmobile.core.CoreApp import org.kiwix.kiwixmobile.core.databinding.StorageSelectDialogBinding @@ -44,6 +45,7 @@ class StorageSelectDialog : DialogFragment() { @Inject lateinit var sharedPreferenceUtil: SharedPreferenceUtil private var aTitle: String? = null private var storageSelectDialogViewBinding: StorageSelectDialogBinding? = null + private var storageDisposable: Disposable? = null private val storageAdapter: StorageAdapter by lazy { StorageAdapter( @@ -73,13 +75,14 @@ class StorageSelectDialog : DialogFragment() { setHasFixedSize(true) } - Flowable.fromCallable { StorageDeviceUtils.getWritableStorage(requireActivity()) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - { storageAdapter.items = it }, - Throwable::printStackTrace - ) + storageDisposable = + Flowable.fromCallable { StorageDeviceUtils.getWritableStorage(requireActivity()) } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { storageAdapter.items = it }, + Throwable::printStackTrace + ) } override fun show(fm: FragmentManager, text: String?) { @@ -89,6 +92,7 @@ class StorageSelectDialog : DialogFragment() { override fun onDestroyView() { super.onDestroyView() + storageDisposable?.dispose() storageSelectDialogViewBinding = null } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/NightModeConfig.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/NightModeConfig.kt index 669efaa11..c98c36c48 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/NightModeConfig.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/NightModeConfig.kt @@ -17,6 +17,7 @@ */ package org.kiwix.kiwixmobile.core +import android.annotation.SuppressLint import android.content.Context import android.content.res.Configuration import androidx.appcompat.app.AppCompatDelegate @@ -24,6 +25,7 @@ import org.kiwix.kiwixmobile.core.NightModeConfig.Mode.SYSTEM import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import javax.inject.Inject +@SuppressLint("CheckResult") class NightModeConfig @Inject constructor( val sharedPreferenceUtil: SharedPreferenceUtil, val context: Context diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/DownloaderImpl.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/DownloaderImpl.kt index 908b91817..e272ca6d9 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/DownloaderImpl.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/DownloaderImpl.kt @@ -18,6 +18,7 @@ package org.kiwix.kiwixmobile.core.downloader +import android.annotation.SuppressLint import io.reactivex.Observable import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao import org.kiwix.kiwixmobile.core.data.remote.KiwixService @@ -31,6 +32,7 @@ class DownloaderImpl @Inject constructor( private val kiwixService: KiwixService ) : Downloader { + @SuppressLint("CheckResult") override fun download(book: LibraryNetworkEntity.Book) { urlProvider(book) .take(1) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/fetch/FetchDownloadMonitor.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/fetch/FetchDownloadMonitor.kt index 1bf34b1fa..eef4bf97d 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/fetch/FetchDownloadMonitor.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/fetch/FetchDownloadMonitor.kt @@ -17,6 +17,7 @@ */ package org.kiwix.kiwixmobile.core.downloader.fetch +import android.annotation.SuppressLint import com.tonyodev.fetch2.Download import com.tonyodev.fetch2.Error import com.tonyodev.fetch2.Fetch @@ -28,6 +29,7 @@ import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao import org.kiwix.kiwixmobile.core.downloader.DownloadMonitor import javax.inject.Inject +@SuppressLint("CheckResult") class FetchDownloadMonitor @Inject constructor(fetch: Fetch, fetchDownloadDao: FetchDownloadDao) : DownloadMonitor { private val updater = PublishSubject.create<() -> Unit>() diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt index 0ffa0dab3..08bf576f0 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/AddNoteDialog.kt @@ -439,6 +439,7 @@ class AddNoteDialog : DialogFragment() { override fun onDestroyView() { super.onDestroyView() + mainRepositoryActions.dispose() dialogNoteAddNoteBinding = null } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt index 0a484441c..bcd81eed4 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt @@ -802,6 +802,7 @@ abstract class CoreReaderFragment : val activity = requireActivity() as AppCompatActivity? activity?.setSupportActionBar(null) } + repositoryActions?.dispose() safeDispose() tabCallback = null hideBackToTopTimer?.cancel() diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt index 9c417d846..4f6a440cc 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainRepositoryActions.kt @@ -18,6 +18,7 @@ package org.kiwix.kiwixmobile.core.main import android.util.Log +import io.reactivex.disposables.Disposable import org.kiwix.kiwixmobile.core.data.DataSource import org.kiwix.kiwixmobile.core.di.ActivityScope import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem @@ -29,14 +30,18 @@ private const val TAG = "MainPresenter" @ActivityScope class MainRepositoryActions @Inject constructor(private val dataSource: DataSource) { + private var saveHistoryDisposable: Disposable? = null + private var saveBookmarkDisposable: Disposable? = null + private var saveNoteDisposable: Disposable? = null + private var deleteNoteDisposable: Disposable? = null fun saveHistory(history: HistoryItem) { - dataSource.saveHistory(history) + saveHistoryDisposable = dataSource.saveHistory(history) .subscribe({}, { e -> Log.e(TAG, "Unable to save history", e) }) } fun saveBookmark(bookmark: BookmarkItem) { - dataSource.saveBookmark(bookmark) + saveBookmarkDisposable = dataSource.saveBookmark(bookmark) .subscribe({}, { e -> Log.e(TAG, "Unable to save bookmark", e) }) } @@ -47,12 +52,19 @@ class MainRepositoryActions @Inject constructor(private val dataSource: DataSour } fun saveNote(note: NoteListItem) { - dataSource.saveNote(note) + saveNoteDisposable = dataSource.saveNote(note) .subscribe({}, { e -> Log.e(TAG, "Unable to save note", e) }) } fun deleteNote(noteUniqueKey: String) { - dataSource.deleteNote(noteUniqueKey) + deleteNoteDisposable = dataSource.deleteNote(noteUniqueKey) .subscribe({}, { e -> Log.e(TAG, "Unable to delete note", e) }) } + + fun dispose() { + saveHistoryDisposable?.dispose() + saveBookmarkDisposable?.dispose() + saveNoteDisposable?.dispose() + deleteNoteDisposable?.dispose() + } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt index 60ebe0a61..1b811614d 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimFileReader.kt @@ -17,6 +17,7 @@ */ package org.kiwix.kiwixmobile.core.reader +import android.annotation.SuppressLint import android.content.res.AssetFileDescriptor import android.net.Uri import android.os.ParcelFileDescriptor @@ -173,6 +174,7 @@ class ZimFileReader constructor( private fun getContent(url: String) = getContentAndMimeType(url).let { (content, _) -> content } + @SuppressLint("CheckResult") private fun streamZimContentToPipe(uri: String, outputStream: OutputStream) { Completable.fromAction { try { diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.kt index 13a11e522..07ad1ec09 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.kt @@ -127,6 +127,11 @@ abstract class CorePrefsFragment : .unregisterOnSharedPreferenceChangeListener(this) } + override fun onDestroyView() { + presenter?.dispose() + super.onDestroyView() + } + private fun setUpSettings() { setAppVersionNumber() } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/SettingsPresenter.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/SettingsPresenter.kt index 3f4653e6b..d4b26446c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/SettingsPresenter.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/SettingsPresenter.kt @@ -18,6 +18,7 @@ package org.kiwix.kiwixmobile.core.settings import android.util.Log +import io.reactivex.disposables.Disposable import org.kiwix.kiwixmobile.core.base.BasePresenter import org.kiwix.kiwixmobile.core.data.DataSource import org.kiwix.kiwixmobile.core.settings.SettingsContract.Presenter @@ -26,12 +27,17 @@ import javax.inject.Inject internal class SettingsPresenter @Inject constructor(private val dataSource: DataSource) : BasePresenter(), Presenter { + private var dataSourceDisposable: Disposable? = null override fun clearHistory() { - dataSource.clearHistory() + dataSourceDisposable = dataSource.clearHistory() .subscribe({ // TODO }, { e -> Log.e("SettingsPresenter", e.message, e) }) } + + fun dispose() { + dataSourceDisposable?.dispose() + } } diff --git a/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt b/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt index dc55beced..e952bdcee 100644 --- a/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt +++ b/core/src/test/java/org/kiwix/kiwixmobile/core/dao/NewBookDaoTest.kt @@ -18,6 +18,7 @@ package org.kiwix.kiwixmobile.core.dao +import android.annotation.SuppressLint import io.mockk.CapturingSlot import io.mockk.clearAllMocks import io.mockk.every @@ -63,6 +64,7 @@ internal class NewBookDaoTest { newBookDao.books().test().assertValues(listOf(BookOnDisk(expectedEntity))) } + @SuppressLint("CheckResult") @Test fun `books deletes entities whose file does not exist`() { val (_, deletedEntity) = expectEmissionOfExistingAndNotExistingBook()