LoginSignup
2
0

More than 3 years have passed since last update.

VLC for Androidのリポジトリについて

Last updated at Posted at 2021-03-13

はじめに

リポジトリとはなんぞやとや言うことで有名OSSメディアプレイヤーアプリである「VLC for Android」にあるリポジトリの実装を調べる。
当方はAndroidの素人なのでその辺はご了承を。

各種リンク

アプリ
GitHub
公式サイト

アプリ内で定義しているリポジトリ

クラス 概要
BrowserFavRepository お気に入りを保持?
DirectoryRepository ディレクトリを保持?
ExternalSubRepository 外部ストレージ
MediaMetadataRepository メタデータ
MediaPersonRepository ?
MoviepediaApiRepository MoviepediaのApi
OpenSubtitleRepository ?
PersonRepository MoviePediaから取得した人をキャッシュ
SlaveRepository ?

データソース

どこからデータを持ってきているかを調べた結果。データベースとAPI、オンメモリーの3つのパターンがある

クラス データソース
BrowserFavRepository データベース(BrowserFavDao)
DirectoryRepository データベース(CustomDirectoryDao)
ExternalSubRepository データベース(ExternalSubDao)、 オンメモリー
MediaMetadataRepository データベース(MediaMetadataDataFullDao、MediaMetadataDao、MediaImageDao)
MediaPersonRepository データベース(MediaPersonJoinDao)
MoviepediaApiRepository REST API(IMoviepediaApiService)
OpenSubtitleRepository REST API?(IOpenSubtitleService)
PersonRepository データベース(PersonDao)
SlaveRepository データベース(SlaveDao)

ユニットテストを入れているか

クラス  テストクラス
BrowserFavRepository ○(BrowserFavRepositoryTest) 
DirectoryRepository ○(DirectoryRepositoryTest)
ExternalSubRepository ○(ExternalSubRepositoryTest)
MediaMetadataRepository ×
MediaPersonRepository ×
MoviepediaApiRepository ×
OpenSubtitleRepository ○?(SubtitlesModelTest)
PersonRepository ×
SlaveRepository ○(SlaveRepositoryTest)

データ取得元がデータベースの場合のクラス構成

↓はExternalSubRepository周りのクラス構成。ExternalSubクラスはデータベース、SubtitleItemはオンメモリーで管理している。
LiveData、Coroutineが絡んでいるがここでは割愛する。

Class Diagram0.png

ExternalSubRepositoryの責務はなんなのかというと、↓のコードをにある、Roomでは表現できない?制約にそってCRUD操作を実装している。後はテスタビリティの確保。

   fun addDownloadingItem(key: Long, item: SubtitleItem) {
        _downloadingSubtitles.add(key, item.copy(state = State.Downloading))
    }

    fun getDownloadedSubtitles(mediaUri: Uri): LiveData<List<org.videolan.vlc.mediadb.models.ExternalSub>> {
        val externalSubs = externalSubDao.get(mediaUri.path!!)
        return Transformations.map(externalSubs) { list ->
            val existExternalSubs: MutableList<org.videolan.vlc.mediadb.models.ExternalSub> = mutableListOf()
            list.forEach {
                if (File(Uri.decode(it.subtitlePath)).exists())
                    existExternalSubs.add(it)
                else
                    deleteSubtitle(it.mediaPath, it.idSubtitle)
            }
            existExternalSubs
        }
    }

 

データ取得元がREST APIの場合のクラス構成

↓はOpenSubtitleRepository周りのクラス構成。

Class Diagram1.png

OpenSubtitleRepositoryの責務はなんなのかというと、↓のコードにある通りRest APIのクエリーパラメータの組み立てと補正。
クエリーオブジェクト的な責務を行っている状態。後はテスタビリティの確保。

    suspend fun queryWithImdbid(imdbId: Int, tag: String?, episode: Int? , season: Int?, languageId: String? ): List<OpenSubtitle> {
        val actualEpisode = episode ?: 0
        val actualSeason = season ?: 0
        val actualLanguageId = languageId ?: ""
        val actualTag = tag ?: ""
        return openSubtitleService.query(
                imdbId = String.format("%07d", imdbId),
                tag = actualTag,
                episode = actualEpisode,
                season = actualSeason,
                languageId = actualLanguageId)
    }

ExternalSubRepositoryのユニットテスト

案の定、ExternalSubDaoをモック化してテストしている。

OpenSubtitleRepositoryのユニットテスト

SubtitlesModelTestで行っている。SubtitlesModelはViewModel派生のクラスで色々面白い事をしているがここでは触れない。
OpenSubtitleRepositoryそのもの、ExternalSubDaoをモック化してテストしている。 RetroFitのクラスはモック化していなかった。

その他リポジトリの(テスタビリティ担保以外の)責務

クラス (テスタビリティ担保以外の)責務
BrowserFavRepository サーバー保存のお気に入りとローカル保存のお気に入りの整合性をとっている?
DirectoryRepository 実際にフォルダを作成、削除して、DBに同期している?
ExternalSubRepository 説明済
MediaMetadataRepository クエリーの組み立て
MediaPersonRepository なし
MoviepediaApiRepository クエリーの組み立て
OpenSubtitleRepository 説明済
PersonRepository なし
SlaveRepository 様々な保存パターンに対応する。SQL例外の補正

まとめ

  • テスタビリティ担保以外の主な責務はクエリーの組み立て、サーバーとローカルキャッシュの整合性、SQL周りの隠蔽、Retrofit周りの隠蔽
  • Coroutine、LiveDataと密結合している。AndroidのUIでしか使わないから?
  • シングルトンについてSingletonHolderとCompanionオブジェクトを分けているのはなに?
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0