diff --git a/app/build.gradle b/app/build.gradle index b46867999..7028b3636 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -133,6 +133,7 @@ android { } } sourceSets { + androidTest.java.srcDirs += "src/androidTest/kotlin" main.java.srcDirs += 'src/main/kotlin' debug.java.srcDirs += 'src/debug/kotlin' play.java.srcDirs += 'src/play/kotlin' @@ -154,12 +155,13 @@ ext { jackson_version = "2.8.5" butterknife_version = "8.4.0" material_dialogs_version = "0.9.1.0" + runner_version = "0.5" + espresso_version = "2.2.2" + junit_version = "4.12" + mockito_version = "2.3.0" } dependencies { - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) compile "com.android.support:appcompat-v7:${support_library_version}" compile "com.android.support:support-v4:${support_library_version}" @@ -215,15 +217,29 @@ dependencies { compile 'com.jakewharton.timber:timber:4.3.1' compile 'com.jakewharton.rxrelay:rxrelay:1.2.0' compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' - testCompile 'org.robolectric:robolectric:3.1.4' - testCompile 'org.mockito:mockito-core:2.2.22' - testCompile 'com.google.truth:truth:0.30' - testCompile 'junit:junit:4.12' + testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' previewCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' + testCompile 'org.robolectric:robolectric:3.1.4' + testCompile "org.mockito:mockito-core:${mockito_version}" + testCompile 'com.google.truth:truth:0.30' + testCompile "junit:junit:${junit_version}" + testCompile "com.github.stephanenicolas.toothpick:toothpick-testing:${toothpick_version}" + + androidTestCompile "com.github.stephanenicolas.toothpick:toothpick-testing:${toothpick_version}" + androidTestCompile "org.mockito:mockito-core:${mockito_version}" + androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0' + androidTestCompile "junit:junit:${junit_version}" + androidTestCompile "com.android.support:support-annotations:${support_library_version}" + androidTestCompile "com.android.support.test:runner:${runner_version}" + androidTestCompile "com.android.support.test:rules:${runner_version}" + androidTestCompile("com.android.support.test.espresso:espresso-core:${espresso_version}", { + exclude group: 'com.android.support', module: 'support-annotations' + }) + playCompile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') { transitive = true } diff --git a/app/src/androidTest/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivityTest.kt b/app/src/androidTest/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivityTest.kt new file mode 100644 index 000000000..0c0940428 --- /dev/null +++ b/app/src/androidTest/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivityTest.kt @@ -0,0 +1,106 @@ +package com.kelsos.mbrc.ui.navigation.main + +import android.app.Application +import android.content.Intent +import android.support.test.InstrumentationRegistry +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.assertion.ViewAssertions.doesNotExist +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.* +import android.support.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE +import android.support.test.filters.LargeTest +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import com.kelsos.mbrc.R +import com.kelsos.mbrc.constants.Protocol +import com.kelsos.mbrc.domain.TrackInfo +import com.kelsos.mbrc.events.bus.RxBus +import com.kelsos.mbrc.model.MainDataModel +import com.kelsos.mbrc.repository.ModelCache +import com.kelsos.mbrc.utilities.SettingsManager +import org.hamcrest.Matchers.allOf +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import org.junit.rules.TestRule +import org.junit.runner.RunWith +import org.mockito.Mockito.* +import rx.Completable +import rx.Scheduler +import rx.Single +import rx.schedulers.TestScheduler +import toothpick.Toothpick +import toothpick.config.Module +import toothpick.testing.ToothPickRule + + +@RunWith(AndroidJUnit4::class) +@LargeTest +class MainActivityTest { + + var toothPickRule = ToothPickRule(this) + val activityRule = ActivityTestRule(MainActivity::class.java, true, false) + + @Rule fun chain(): TestRule = RuleChain.outerRule(toothPickRule).around(activityRule) + + + private lateinit var model: MainDataModel + private lateinit var mockBus: RxBus + private lateinit var mockSettingsManager: SettingsManager + private lateinit var mockCache: ModelCache + + @Before + fun setUp() { + mockSettingsManager = mock(SettingsManager::class.java) + mockCache = mock(ModelCache::class.java) + `when`(mockCache.restoreCover()).thenReturn(Single.just("")) + `when`(mockCache.persistCover(anyString())).thenReturn(Completable.complete()) + `when`(mockCache.restoreInfo()).thenReturn(Single.just(TrackInfo())) + `when`(mockSettingsManager.shouldShowPluginUpdate()).thenReturn(Single.just(false)) + mockBus = mock(RxBus::class.java) + + model = MainDataModel(mockBus, mockCache) + + val application = InstrumentationRegistry.getTargetContext().applicationContext as Application + val scope = Toothpick.openScope(application) + scope.installModules(TestModule()) + } + + @After + fun tearDown() { + Toothpick.reset() + } + + @Test + fun testShowOutdatedPluginSnackBar() { + activityRule.launchActivity(Intent()) + onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(R.string.plugin_protocol_out_of_date))) + .check(doesNotExist()) + model.pluginProtocol = 1 + onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(R.string.plugin_protocol_out_of_date))) + .check(matches(withEffectiveVisibility(VISIBLE))) + } + + @Test + fun testShouldNotShowOutdatedPluginSnackBar() { + activityRule.launchActivity(Intent()) + onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(R.string.plugin_protocol_out_of_date))) + .check(doesNotExist()) + model.pluginProtocol = Protocol.ProtocolVersionNumber + onView(allOf(withId(android.support.design.R.id.snackbar_text), withText(R.string.plugin_protocol_out_of_date))) + .check(doesNotExist()) + } + + inner class TestModule : Module() { + init { + bind(MainDataModel::class.java).toProviderInstance { model }.providesSingletonInScope() + bind(RxBus::class.java).toProviderInstance { mockBus }.providesSingletonInScope() + bind(SettingsManager::class.java) + .toProviderInstance { mockSettingsManager } + .providesSingletonInScope() + bind(Scheduler::class.java).withName("main").toProviderInstance { TestScheduler() } + } + } +} diff --git a/app/src/main/kotlin/com/kelsos/mbrc/commands/VersionCheckCommand.kt b/app/src/main/kotlin/com/kelsos/mbrc/commands/VersionCheckCommand.kt index 423a97ba7..cc482eaaf 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/commands/VersionCheckCommand.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/commands/VersionCheckCommand.kt @@ -29,12 +29,12 @@ internal constructor(private val model: MainDataModel, override fun execute(e: IEvent) { - if (!manager.isPluginUpdateCheckEnabled) { + if (!manager.isPluginUpdateCheckEnabled()) { return } val calendar = Calendar.getInstance() - calendar.timeInMillis = manager.lastUpdated.time + calendar.timeInMillis = manager.getLastUpdated().time calendar.add(Calendar.DATE, 2) val nextCheck = Date(calendar.timeInMillis) val now = Date() @@ -84,7 +84,7 @@ internal constructor(private val model: MainDataModel, } } - manager.lastUpdated = now + manager.setLastUpdated(now) Timber.d("last check on: %s", java.lang.Long.toString(now.time)) Timber.d("plugin reported version: %s", model.pluginVersion) Timber.d("plugin suggested version: %s", suggestedVersion) diff --git a/app/src/main/kotlin/com/kelsos/mbrc/di/modules/RemoteModule.kt b/app/src/main/kotlin/com/kelsos/mbrc/di/modules/RemoteModule.kt index e1a5e52f9..3c9c3be0e 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/di/modules/RemoteModule.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/di/modules/RemoteModule.kt @@ -6,8 +6,34 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.kelsos.mbrc.di.providers.NotificationManagerCompatProvider import com.kelsos.mbrc.events.bus.RxBus import com.kelsos.mbrc.events.bus.RxBusImpl -import com.kelsos.mbrc.repository.* -import com.kelsos.mbrc.services.* +import com.kelsos.mbrc.repository.AlbumRepository +import com.kelsos.mbrc.repository.AlbumRepositoryImpl +import com.kelsos.mbrc.repository.ArtistRepository +import com.kelsos.mbrc.repository.ArtistRepositoryImpl +import com.kelsos.mbrc.repository.ConnectionRepository +import com.kelsos.mbrc.repository.ConnectionRepositoryImpl +import com.kelsos.mbrc.repository.GenreRepository +import com.kelsos.mbrc.repository.GenreRepositoryImpl +import com.kelsos.mbrc.repository.ModelCache +import com.kelsos.mbrc.repository.ModelCacheImpl +import com.kelsos.mbrc.repository.NowPlayingRepository +import com.kelsos.mbrc.repository.NowPlayingRepositoryImpl +import com.kelsos.mbrc.repository.PlaylistRepository +import com.kelsos.mbrc.repository.PlaylistRepositoryImpl +import com.kelsos.mbrc.repository.TrackRepository +import com.kelsos.mbrc.repository.TrackRepositoryImpl +import com.kelsos.mbrc.services.CoverService +import com.kelsos.mbrc.services.CoverServiceImpl +import com.kelsos.mbrc.services.LibraryService +import com.kelsos.mbrc.services.LibraryServiceImpl +import com.kelsos.mbrc.services.NowPlayingService +import com.kelsos.mbrc.services.NowPlayingServiceImpl +import com.kelsos.mbrc.services.PlaylistService +import com.kelsos.mbrc.services.PlaylistServiceImpl +import com.kelsos.mbrc.services.QueueService +import com.kelsos.mbrc.services.QueueServiceImpl +import com.kelsos.mbrc.utilities.SettingsManager +import com.kelsos.mbrc.utilities.SettingsManagerImpl import rx.Scheduler import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers @@ -38,5 +64,8 @@ class RemoteModule : Module() { bind(NowPlayingRepository::class.java).to(NowPlayingRepositoryImpl::class.java) bind(PlaylistRepository::class.java).to(PlaylistRepositoryImpl::class.java) + + bind(SettingsManager::class.java).to(SettingsManagerImpl::class.java).singletonInScope() + bind(ModelCache::class.java).to(ModelCacheImpl::class.java).singletonInScope() } } diff --git a/app/src/main/kotlin/com/kelsos/mbrc/messaging/NotificationService.kt b/app/src/main/kotlin/com/kelsos/mbrc/messaging/NotificationService.kt index 7029fc821..5239e5c5a 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/messaging/NotificationService.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/messaging/NotificationService.kt @@ -87,7 +87,7 @@ constructor(bus: RxBus, } private fun connectionChanged(event: ConnectionStatusChangeEvent) { - if (!settings.isNotificationControlEnabled) { + if (!settings.isNotificationControlEnabled()) { Timber.v("Notification is off doing nothing") return } diff --git a/app/src/main/kotlin/com/kelsos/mbrc/model/MainDataModel.kt b/app/src/main/kotlin/com/kelsos/mbrc/model/MainDataModel.kt index 47adca5c5..008ec7bee 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/model/MainDataModel.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/model/MainDataModel.kt @@ -12,14 +12,8 @@ import com.kelsos.mbrc.domain.TrackInfo import com.kelsos.mbrc.enums.LfmStatus import com.kelsos.mbrc.events.MessageEvent import com.kelsos.mbrc.events.bus.RxBus -import com.kelsos.mbrc.events.ui.LfmRatingChanged -import com.kelsos.mbrc.events.ui.PlayStateChange -import com.kelsos.mbrc.events.ui.RatingChanged -import com.kelsos.mbrc.events.ui.RepeatChange -import com.kelsos.mbrc.events.ui.ScrobbleChange -import com.kelsos.mbrc.events.ui.ShuffleChange +import com.kelsos.mbrc.events.ui.* import com.kelsos.mbrc.events.ui.ShuffleChange.ShuffleState -import com.kelsos.mbrc.events.ui.VolumeChange import com.kelsos.mbrc.repository.ModelCache import rx.Completable import rx.Subscription @@ -38,8 +32,13 @@ constructor(private val bus: RxBus, private var subscription: Subscription? = null private var _trackInfo: TrackInfo = TrackInfo() private var _coverPath: String = "" + private var onPluginOutOfDate: (() -> Unit)? = null init { + restoreStated() + } + + private fun restoreStated() { cache.restoreInfo().subscribe({ trackInfo = it }, { onLoadError(it) }) cache.restoreCover().subscribe({ coverPath = it }, { onLoadError(it) }) } @@ -52,6 +51,10 @@ constructor(private val bus: RxBus, } } + fun setOnPluginOutOfDate(method: (() -> Unit)?) { + this.onPluginOutOfDate = method + } + var rating: Float = 0f set(value) { field = value @@ -99,6 +102,13 @@ constructor(private val bus: RxBus, } var pluginProtocol: Int = 2 + set(value) { + field = value + if (value < Protocol.ProtocolVersionNumber) { + apiOutOfDate = true + onPluginOutOfDate?.invoke() + } + } @State var playState: String = PlayerState.UNDEFINED @@ -111,7 +121,7 @@ constructor(private val bus: RxBus, Const.STOPPED.equals(value, ignoreCase = true) -> PlayerState.STOPPED Const.PAUSED.equals(value, ignoreCase = true) -> PlayerState.PAUSED else -> PlayerState.UNDEFINED - } + } field = newState @@ -181,5 +191,10 @@ constructor(private val bus: RxBus, } } + + var apiOutOfDate: Boolean = false + get + private set + } diff --git a/app/src/main/kotlin/com/kelsos/mbrc/repository/ModelCache.kt b/app/src/main/kotlin/com/kelsos/mbrc/repository/ModelCache.kt index 84588010b..b20070a87 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/repository/ModelCache.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/repository/ModelCache.kt @@ -8,11 +8,11 @@ import rx.Single import java.io.* import javax.inject.Inject -class ModelCache +class ModelCacheImpl @Inject constructor(private val mapper: ObjectMapper, - private val context: Application) { + private val context: Application) : ModelCache { - fun persistInfo(trackInfo: TrackInfo): Completable { + override fun persistInfo(trackInfo: TrackInfo): Completable { return Completable.fromCallable { val infoFile = File(context.filesDir, TRACK_INFO) if (infoFile.exists()) { @@ -22,7 +22,7 @@ class ModelCache } } - fun restoreInfo(): Single { + override fun restoreInfo(): Single { return Single.fromCallable { val infoFile = File(context.filesDir, TRACK_INFO) if (infoFile.exists()) { @@ -32,7 +32,7 @@ class ModelCache } } - fun persistCover(cover: String): Completable { + override fun persistCover(cover: String): Completable { return Completable.fromCallable { val coverFile = File(context.filesDir, COVER_INFO) if (coverFile.exists()) { @@ -48,7 +48,7 @@ class ModelCache } } - fun restoreCover(): Single { + override fun restoreCover(): Single { return Single.fromCallable { val coverFile = File(context.filesDir, COVER_INFO) if (coverFile.exists()) { @@ -68,3 +68,10 @@ class ModelCache const val COVER_INFO = "cover.txt" } } + +interface ModelCache { + fun persistInfo(trackInfo: TrackInfo): Completable + fun restoreInfo(): Single + fun persistCover(cover: String): Completable + fun restoreCover(): Single +} diff --git a/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivity.kt b/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivity.kt index 27420dabc..a5084fc77 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivity.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainActivity.kt @@ -5,6 +5,7 @@ import android.graphics.Bitmap import android.os.Bundle import android.support.annotation.ColorRes import android.support.annotation.DrawableRes +import android.support.design.widget.Snackbar import android.support.v4.content.ContextCompat import android.support.v4.view.MenuItemCompat import android.support.v7.widget.ShareActionProvider @@ -68,9 +69,11 @@ class MainActivity : BaseActivity(), MainView, ProgressUpdate { @BindView(R.id.main_album_cover_image_view) lateinit var albumCover: ImageView private var mShareActionProvider: ShareActionProvider? = null - private var menu: Menu? = null + private var snackbar: Snackbar? =null + private var menu: Menu? = null private var volumeChangeListener: SeekBarThrottler? = null + private var positionChangeListener: SeekBarThrottler? = null @OnClick(R.id.main_button_play_pause) @@ -139,6 +142,12 @@ class MainActivity : BaseActivity(), MainView, ProgressUpdate { .show() } + override fun notifyPluginOutOfDate() { + snackbar = Snackbar.make(albumCover, R.string.plugin_protocol_out_of_date, Snackbar.LENGTH_INDEFINITE) + snackbar!!.setAction(android.R.string.ok, { snackbar?.dismiss() }) + snackbar!!.show() + } + override fun onStart() { super.onStart() presenter.attach(this) diff --git a/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainContract.kt b/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainContract.kt index a5590c24f..1102e8bd0 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainContract.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainContract.kt @@ -32,6 +32,8 @@ interface MainView : BaseView { fun updateProgress(position: UpdatePosition) fun showPluginUpdateDialog() + + fun notifyPluginOutOfDate() } diff --git a/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainViewPresenterImpl.kt b/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainViewPresenterImpl.kt index d3ce3d2f6..64bfd5440 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainViewPresenterImpl.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/ui/navigation/main/MainViewPresenterImpl.kt @@ -5,16 +5,7 @@ import com.kelsos.mbrc.constants.Protocol import com.kelsos.mbrc.data.UserAction import com.kelsos.mbrc.events.MessageEvent import com.kelsos.mbrc.events.bus.RxBus -import com.kelsos.mbrc.events.ui.ConnectionStatusChangeEvent -import com.kelsos.mbrc.events.ui.CoverChangedEvent -import com.kelsos.mbrc.events.ui.LfmRatingChanged -import com.kelsos.mbrc.events.ui.PlayStateChange -import com.kelsos.mbrc.events.ui.RepeatChange -import com.kelsos.mbrc.events.ui.ScrobbleChange -import com.kelsos.mbrc.events.ui.ShuffleChange -import com.kelsos.mbrc.events.ui.TrackInfoChangeEvent -import com.kelsos.mbrc.events.ui.UpdatePosition -import com.kelsos.mbrc.events.ui.VolumeChange +import com.kelsos.mbrc.events.ui.* import com.kelsos.mbrc.model.ConnectionModel import com.kelsos.mbrc.model.MainDataModel import com.kelsos.mbrc.mvp.BasePresenter @@ -107,11 +98,13 @@ class MainViewPresenterImpl this.bus.register(this, UpdatePosition::class.java, { this.view?.updateProgress(it) }, true) this.bus.register(this, ScrobbleChange::class.java, { this.view?.updateScrobbleStatus(it.isActive) }, true) this.bus.register(this, LfmRatingChanged::class.java, { this.view?.updateLfmStatus(it.status) }, true) + model.setOnPluginOutOfDate { this.view?.notifyPluginOutOfDate() } } override fun detach() { super.detach() this.bus.unregister(this) + model.setOnPluginOutOfDate(null) } override fun play() { diff --git a/app/src/main/kotlin/com/kelsos/mbrc/utilities/RemoteBroadcastReceiver.kt b/app/src/main/kotlin/com/kelsos/mbrc/utilities/RemoteBroadcastReceiver.kt index 6cbded478..43a6dd166 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/utilities/RemoteBroadcastReceiver.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/utilities/RemoteBroadcastReceiver.kt @@ -42,7 +42,7 @@ class RemoteBroadcastReceiver val state = bundle.getString(TelephonyManager.EXTRA_STATE) if (TelephonyManager.EXTRA_STATE_RINGING.equals(state!!, ignoreCase = true)) { - when (settingsManager.callAction) { + when (settingsManager.getCallAction()) { SettingsManager.PAUSE -> postAction(UserAction(Protocol.PlayerPause, true)) SettingsManager.STOP -> postAction(UserAction(Protocol.PlayerStop, true)) SettingsManager.NONE -> { diff --git a/app/src/main/kotlin/com/kelsos/mbrc/utilities/SettingsManager.kt b/app/src/main/kotlin/com/kelsos/mbrc/utilities/SettingsManagerImpl.kt similarity index 50% rename from app/src/main/kotlin/com/kelsos/mbrc/utilities/SettingsManager.kt rename to app/src/main/kotlin/com/kelsos/mbrc/utilities/SettingsManagerImpl.kt index cd864d2d5..9263bed27 100644 --- a/app/src/main/kotlin/com/kelsos/mbrc/utilities/SettingsManager.kt +++ b/app/src/main/kotlin/com/kelsos/mbrc/utilities/SettingsManagerImpl.kt @@ -5,6 +5,9 @@ import android.content.SharedPreferences import android.support.annotation.StringDef import com.kelsos.mbrc.R import com.kelsos.mbrc.logging.FileLoggingTree +import com.kelsos.mbrc.utilities.SettingsManager.CallAction +import com.kelsos.mbrc.utilities.SettingsManager.Companion.NONE +import com.kelsos.mbrc.utilities.SettingsManager.Companion.REDUCE import rx.Single import timber.log.Timber import java.util.* @@ -12,11 +15,15 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class SettingsManager +class SettingsManagerImpl @Inject constructor(private val context: Application, - private val preferences: SharedPreferences) { + private val preferences: SharedPreferences) : SettingsManager { init { + setupManager() + } + + private fun setupManager() { updatePreferences() val loggingEnabled = loggingEnabled() if (loggingEnabled) { @@ -38,36 +45,36 @@ constructor(private val context: Application, } } - val isNotificationControlEnabled: Boolean - get() = preferences.getBoolean(context.getString(R.string.settings_key_notification_control), true) + override fun isNotificationControlEnabled(): Boolean { + return preferences.getBoolean(context.getString(R.string.settings_key_notification_control), true) + } - internal val callAction: String - @SuppressWarnings("WrongConstant") - @SettingsManager.CallAction - get() = preferences.getString(context.getString(R.string.settings_key_incoming_call_action), NONE) + @CallAction override fun getCallAction(): String = preferences.getString( + context.getString(R.string.settings_key_incoming_call_action), NONE) - val isPluginUpdateCheckEnabled: Boolean - get() = preferences.getBoolean(context.getString(R.string.settings_key_plugin_check), false) + override fun isPluginUpdateCheckEnabled(): Boolean { + return preferences.getBoolean(context.getString(R.string.settings_key_plugin_check), false) + } - var lastUpdated: Date - get() = Date(preferences.getLong(context.getString(R.string.settings_key_last_update_check), 0)) - set(lastChecked) { - val editor = preferences.edit() - editor.putLong(context.getString(R.string.settings_key_last_update_check), lastChecked.time) - editor.apply() - } + override fun getLastUpdated(): Date { + return Date(preferences.getLong(context.getString(R.string.settings_key_last_update_check), 0)) + } + override fun setLastUpdated(lastChecked: Date) { + preferences.edit() + .putLong(context.getString(R.string.settings_key_last_update_check), lastChecked.time) + .apply() + } - fun shouldShowPluginUpdate(): Single { + override fun shouldShowPluginUpdate(): Single { return Single.fromCallable { val lastVersionCode = preferences.getLong(context.getString(R.string.settings_key_last_version_run), 0) val currentVersion = RemoteUtils.getVersionCode(context) if (lastVersionCode < currentVersion) { - - val editor = preferences.edit() - editor.putLong(context.getString(R.string.settings_key_last_version_run), currentVersion) - editor.apply() + preferences.edit() + .putLong(context.getString(R.string.settings_key_last_version_run), currentVersion) + .apply() Timber.d("Update or fresh install") return@fromCallable true @@ -76,15 +83,29 @@ constructor(private val context: Application, } } - @StringDef(NONE, PAUSE, STOP) +} + +interface SettingsManager { + + fun shouldShowPluginUpdate(): Single + fun isNotificationControlEnabled(): Boolean + fun isPluginUpdateCheckEnabled(): Boolean + @CallAction fun getCallAction(): String + + @StringDef(NONE, + PAUSE, + STOP, + REDUCE) @Retention(AnnotationRetention.SOURCE) - internal annotation class CallAction + annotation class CallAction companion object { - const val NONE = "none" const val PAUSE = "pause" const val STOP = "stop" const val REDUCE = "reduce" } + + fun getLastUpdated(): Date + fun setLastUpdated(lastChecked: Date) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0941c92ea..ab4274ed2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -169,4 +169,5 @@ Refreshing library data Include Logs Change Log + Some features may not work properly due to mbrc plugin running an older protocol version, please update. diff --git a/build.gradle b/build.gradle index ff2078fae..9fcaa5ff3 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0-alpha2' + classpath 'com.android.tools.build:gradle:2.3.0-alpha3' classpath 'com.github.ben-manes:gradle-versions-plugin:0.13.0' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"