Skip to content

Commit

Permalink
DI interface instead of concrete type
Browse files Browse the repository at this point in the history
Inject the interface for shared preferences rather than the concrete
type.
This avoids Mockk trying to grab the abstract class underneath, which
would run the real impl instead. It also brings our DI in this file more
in-line with the commonly used pattern
  • Loading branch information
DavidFair committed Jan 6, 2022
1 parent 13a289d commit d3d0459
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.jellyfin.androidtv.di

import org.jellyfin.androidtv.preference.*
import org.koin.android.ext.koin.androidApplication
import org.koin.dsl.binds
import org.koin.dsl.module

val preferenceModule = module {
Expand All @@ -10,6 +11,9 @@ val preferenceModule = module {
single { LiveTvPreferences(get(userApiClient)) }
single { UserSettingPreferences(get(userApiClient)) }
single { AuthenticationPreferences(androidApplication()) }
single { UserPreferences(androidApplication()) }
single { UserPreferences(androidApplication()) } binds arrayOf(
UserPreferences::class,
IUserPreferences::class
)
single { SystemPreferences(androidApplication()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.jellyfin.androidtv.preference

// Stub interface to allow Koin to resolve between different preference stores
interface IUserPreferences : PreferenceStore {}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.jellyfin.androidtv.util.DeviceUtils
*
* @param context Context to get the SharedPreferences from
*/
class UserPreferences(context: Context) : SharedPreferenceStore(
class UserPreferences(context: Context) : IUserPreferences, SharedPreferenceStore(
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
) {
companion object {
Expand Down Expand Up @@ -127,12 +127,14 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
/**
* Shortcut used for changing the audio track
*/
var shortcutAudioTrack = Preference.int("shortcut_audio_track", KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK)
var shortcutAudioTrack =
Preference.int("shortcut_audio_track", KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK)

/**
* Shortcut used for changing the subtitle track
*/
var shortcutSubtitleTrack = Preference.int("shortcut_subtitle_track", KeyEvent.KEYCODE_CAPTIONS)
var shortcutSubtitleTrack =
Preference.int("shortcut_subtitle_track", KeyEvent.KEYCODE_CAPTIONS)

/* Developer options */
/**
Expand Down Expand Up @@ -174,13 +176,14 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
/**
* Set when watched indicators should show on MyImageCardViews
*/
var watchedIndicatorBehavior = Preference.enum("pref_watched_indicator_behavior", WatchedIndicatorBehavior.ALWAYS)
var watchedIndicatorBehavior =
Preference.enum("pref_watched_indicator_behavior", WatchedIndicatorBehavior.ALWAYS)

/**
* Enable series thumbnails in home screen rows
*/
var seriesThumbnailsEnabled = Preference.boolean("pref_enable_series_thumbnails", true)

/**
* Enable subtitles background
*/
Expand All @@ -206,21 +209,40 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
// Migrate to video player enum
// Note: This is the only time we need to check if the value is not set yet because the version numbers were reset
if (!it.contains("video_player"))
putEnum("video_player", if (it.getBoolean("pref_video_use_external", false)) PreferredVideoPlayer.EXTERNAL else PreferredVideoPlayer.AUTO)
putEnum(
"video_player",
if (it.getBoolean(
"pref_video_use_external",
false
)
) PreferredVideoPlayer.EXTERNAL else PreferredVideoPlayer.AUTO
)
}

// v0.11.x to v0.12.x
migration(toVersion = 5) {
// Migrate to audio behavior enum
putEnum("audio_behavior", if (it.getString("pref_audio_option", "0") == "1") AudioBehavior.DOWNMIX_TO_STEREO else AudioBehavior.DIRECT_STREAM)
putEnum(
"audio_behavior",
if (it.getString(
"pref_audio_option",
"0"
) == "1"
) AudioBehavior.DOWNMIX_TO_STEREO else AudioBehavior.DIRECT_STREAM
)

// Migrate live tv player to use enum
putEnum("live_tv_video_player",
putEnum(
"live_tv_video_player",
when {
it.getBoolean("pref_live_tv_use_external", false) -> PreferredVideoPlayer.EXTERNAL
it.getBoolean(
"pref_live_tv_use_external",
false
) -> PreferredVideoPlayer.EXTERNAL
it.getBoolean("pref_enable_vlc_livetv", false) -> PreferredVideoPlayer.VLC
else -> PreferredVideoPlayer.AUTO
})
}
)

// Change audio delay type from long to int
putInt("libvlc_audio_delay", it.getLong("libvlc_audio_delay", 0).toInt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.jellyfin.androidtv.data.compat.SubtitleStreamInfo;
import org.jellyfin.androidtv.data.compat.VideoOptions;
import org.jellyfin.androidtv.data.model.DataRefreshService;
import org.jellyfin.androidtv.preference.IUserPreferences;
import org.jellyfin.androidtv.preference.SystemPreferences;
import org.jellyfin.androidtv.preference.UserPreferences;
import org.jellyfin.androidtv.preference.UserSettingPreferences;
Expand Down Expand Up @@ -67,7 +68,7 @@ public class PlaybackController {

private Lazy<ApiClient> apiClient = inject(ApiClient.class);
private Lazy<PlaybackManager> playbackManager = inject(PlaybackManager.class);
private Lazy<UserPreferences> userPreferences = inject(UserPreferences.class);
private Lazy<IUserPreferences> userPreferences = inject(IUserPreferences.class);
private Lazy<SystemPreferences> systemPreferences = inject(SystemPreferences.class);
private Lazy<MediaManager> mediaManager = inject(MediaManager.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package org.jellyfin.androidtv.ui.playback

import io.mockk.*
import io.mockk.every
import io.mockk.mockk
import io.mockk.unmockkAll
import io.mockk.verify
import org.jellyfin.androidtv.preference.IUserPreferences
import org.jellyfin.androidtv.preference.Preference
import org.jellyfin.androidtv.preference.UserPreferences
import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer
import org.jellyfin.androidtv.util.Utils
import org.jellyfin.apiclient.interaction.ApiClient
import org.jellyfin.apiclient.model.dto.BaseItemDto
import org.jellyfin.apiclient.model.dto.BaseItemType
import org.jellyfin.apiclient.model.entities.LocationType
import org.jellyfin.apiclient.model.library.PlayAccess
import org.junit.After
import org.junit.Assert.*
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.koin.core.context.startKoin
Expand All @@ -29,7 +28,7 @@ class PlaybackControllerTest : KoinTest {

// Koin managed modules
lateinit var mockApiClient: ApiClient
lateinit var mockUserPreferences: UserPreferences
lateinit var mockUserPreferences: IUserPreferences

private fun prepDiMocks(): Module {
mockApiClient = mockk(relaxed = true)
Expand All @@ -41,8 +40,8 @@ class PlaybackControllerTest : KoinTest {
} returns PreferredVideoPlayer.EXOPLAYER

return module {
single<ApiClient> { mockApiClient }
single<UserPreferences> { mockUserPreferences }
single { mockApiClient }
single { mockUserPreferences }
}
}

Expand Down

0 comments on commit d3d0459

Please sign in to comment.