Merge branch 'develop' into remove-mediastore
This commit is contained in:
commit
83b186b9b5
|
@ -33,7 +33,7 @@
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !deleteEnabled && !isOffline(context)</ID>
|
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !deleteEnabled && !isOffline(context)</ID>
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !isOffline(context) && selection.size > pinnedCount</ID>
|
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !isOffline(context) && selection.size > pinnedCount</ID>
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$entry != null && !entry.isDirectory && !entry.isVideo</ID>
|
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$entry != null && !entry.isDirectory && !entry.isVideo</ID>
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment.<no name provided>$Util.getShouldShowAllSongsByArtist(context) && musicDirectory.findChild(allSongsId) == null && musicDirectory.getChildren(true, false).size == musicDirectory.getChildren(true, true).size</ID>
|
<ID>ComplexCondition:SelectAlbumModel.kt$SelectAlbumModel$Util.getShouldShowAllSongsByArtist(context) && musicDirectory.findChild(allSongsId) == null && musicDirectory.getChildren(true, false).size == musicDirectory.getChildren(true, true).size</ID>
|
||||||
<ID>ComplexCondition:ServerSettingsModel.kt$ServerSettingsModel$url.isNullOrEmpty() || userName.isNullOrEmpty() || isMigrated</ID>
|
<ID>ComplexCondition:ServerSettingsModel.kt$ServerSettingsModel$url.isNullOrEmpty() || userName.isNullOrEmpty() || isMigrated</ID>
|
||||||
<ID>ComplexCondition:SongView.kt$SongView$TextUtils.isEmpty(transcodedSuffix) || transcodedSuffix == suffix || song.isVideo && Util.getVideoPlayerType(this.context) !== VideoPlayerType.FLASH</ID>
|
<ID>ComplexCondition:SongView.kt$SongView$TextUtils.isEmpty(transcodedSuffix) || transcodedSuffix == suffix || song.isVideo && Util.getVideoPlayerType(this.context) !== VideoPlayerType.FLASH</ID>
|
||||||
<ID>ComplexCondition:SubsonicImageLoaderProxy.kt$SubsonicImageLoaderProxy$id != null && view != null && view is ImageView</ID>
|
<ID>ComplexCondition:SubsonicImageLoaderProxy.kt$SubsonicImageLoaderProxy$id != null && view != null && view is ImageView</ID>
|
||||||
|
@ -49,10 +49,9 @@
|
||||||
<ID>ComplexMethod:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
<ID>ComplexMethod:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
||||||
<ID>ComplexMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
<ID>ComplexMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$protected override fun done(result: Pair<MusicDirectory, Boolean>)</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateInterfaceWithEntries(musicDirectory: MusicDirectory)</ID>
|
||||||
<ID>ComplexMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
<ID>ComplexMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||||
<ID>ComplexMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
<ID>ComplexMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
||||||
<ID>ComplexMethod:SongView.kt$SongView$fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean)</ID>
|
<ID>ComplexMethod:SongView.kt$SongView$fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean)</ID>
|
||||||
|
@ -85,9 +84,9 @@
|
||||||
<ID>LargeClass:NavigationActivity.kt$NavigationActivity : AppCompatActivity</ID>
|
<ID>LargeClass:NavigationActivity.kt$NavigationActivity : AppCompatActivity</ID>
|
||||||
<ID>LargeClass:RESTMusicService.kt$RESTMusicService : MusicService</ID>
|
<ID>LargeClass:RESTMusicService.kt$RESTMusicService : MusicService</ID>
|
||||||
<ID>LargeClass:SelectAlbumFragment.kt$SelectAlbumFragment : Fragment</ID>
|
<ID>LargeClass:SelectAlbumFragment.kt$SelectAlbumFragment : Fragment</ID>
|
||||||
<ID>LargeClass:SelectAlbumFragment.kt$SelectAlbumFragment$LoadTask : FragmentBackgroundTask</ID>
|
<ID>LargeClass:SelectAlbumModel.kt$SelectAlbumModel : AndroidViewModelKoinComponent</ID>
|
||||||
<ID>LargeClass:SelectArtistFragment.kt$SelectArtistFragment : Fragment</ID>
|
<ID>LargeClass:SelectArtistFragment.kt$SelectArtistFragment : Fragment</ID>
|
||||||
<ID>LargeClass:ServerSettingsModel.kt$ServerSettingsModel : ViewModel</ID>
|
<ID>LargeClass:ServerSettingsModel.kt$ServerSettingsModel : AndroidViewModel</ID>
|
||||||
<ID>LargeClass:SongView.kt$SongView : UpdateViewCheckable</ID>
|
<ID>LargeClass:SongView.kt$SongView : UpdateViewCheckable</ID>
|
||||||
<ID>LongMethod:APIMusicDirectoryConverter.kt$fun MusicDirectoryChild.toDomainEntity(): MusicDirectory.Entry</ID>
|
<ID>LongMethod:APIMusicDirectoryConverter.kt$fun MusicDirectoryChild.toDomainEntity(): MusicDirectory.Entry</ID>
|
||||||
<ID>LongMethod:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
<ID>LongMethod:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
||||||
|
@ -140,14 +139,16 @@
|
||||||
<ID>LongMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
<ID>LongMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||||
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun createHeader( entries: List<MusicDirectory.Entry>, name: CharSequence?, songCount: Int ): View?</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun downloadBackground(save: Boolean, songs: List<MusicDirectory.Entry?>)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun downloadBackground(save: Boolean, songs: List<MusicDirectory.Entry?>)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun playAll(shuffle: Boolean = false, append: Boolean = false)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun playAll(shuffle: Boolean = false, append: Boolean = false)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.<no name provided>$override fun done(result: Pair<MusicDirectory, Boolean>)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateInterfaceWithEntries(musicDirectory: MusicDirectory)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.<no name provided>$override fun load(service: MusicService): MusicDirectory</ID>
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$protected fun createHeader( entries: List<MusicDirectory.Entry>, name: CharSequence?, songCount: Int ): View?</ID>
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getAlbumList(albumListType: String, size: Int, offset: Int)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$protected override fun done(result: Pair<MusicDirectory, Boolean>)</ID>
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getArtist(refresh: Boolean, id: String?, name: String?)</ID>
|
||||||
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getMusicDirectory( refresh: Boolean, id: String?, name: String?, parentId: String? )</ID>
|
||||||
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||||
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$private fun onArtistMenuItemSelected(menuItem: MenuItem, artist: Artist): Boolean</ID>
|
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$private fun onArtistMenuItemSelected(menuItem: MenuItem, artist: Artist): Boolean</ID>
|
||||||
<ID>LongMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
<ID>LongMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
||||||
|
@ -204,7 +205,6 @@
|
||||||
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$206</ID>
|
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$206</ID>
|
||||||
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$5</ID>
|
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$5</ID>
|
||||||
<ID>MagicNumber:SelectAlbumFragment.kt$SelectAlbumFragment$10</ID>
|
<ID>MagicNumber:SelectAlbumFragment.kt$SelectAlbumFragment$10</ID>
|
||||||
<ID>MagicNumber:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$10</ID>
|
|
||||||
<ID>MagicNumber:SelectMusicFolderView.kt$SelectMusicFolderView$10</ID>
|
<ID>MagicNumber:SelectMusicFolderView.kt$SelectMusicFolderView$10</ID>
|
||||||
<ID>MagicNumber:SongView.kt$SongView$3</ID>
|
<ID>MagicNumber:SongView.kt$SongView$3</ID>
|
||||||
<ID>MagicNumber:SongView.kt$SongView$4</ID>
|
<ID>MagicNumber:SongView.kt$SongView$4</ID>
|
||||||
|
@ -212,7 +212,6 @@
|
||||||
<ID>NestedBlockDepth:DownloadFile.kt$DownloadFile.DownloadTask$override fun execute()</ID>
|
<ID>NestedBlockDepth:DownloadFile.kt$DownloadFile.DownloadTask$override fun execute()</ID>
|
||||||
<ID>NestedBlockDepth:DownloadHandler.kt$DownloadHandler$private fun downloadRecursively( fragment: Fragment, id: String, name: String?, isShare: Boolean, isDirectory: Boolean, save: Boolean, append: Boolean, autoPlay: Boolean, shuffle: Boolean, background: Boolean, playNext: Boolean, unpin: Boolean, isArtist: Boolean )</ID>
|
<ID>NestedBlockDepth:DownloadHandler.kt$DownloadHandler$private fun downloadRecursively( fragment: Fragment, id: String, name: String?, isShare: Boolean, isDirectory: Boolean, save: Boolean, append: Boolean, autoPlay: Boolean, shuffle: Boolean, background: Boolean, playNext: Boolean, unpin: Boolean, isArtist: Boolean )</ID>
|
||||||
<ID>NestedBlockDepth:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
<ID>NestedBlockDepth:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
||||||
<ID>NestedBlockDepth:SelectAlbumFragment.kt$SelectAlbumFragment$private fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?)</ID>
|
|
||||||
<ID>ReturnCount:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
<ID>ReturnCount:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
||||||
<ID>ReturnCount:CommunicationErrorHandler.kt$CommunicationErrorHandler.Companion$fun getErrorMessage(error: Throwable, context: Context): String</ID>
|
<ID>ReturnCount:CommunicationErrorHandler.kt$CommunicationErrorHandler.Companion$fun getErrorMessage(error: Throwable, context: Context): String</ID>
|
||||||
<ID>ReturnCount:FileLoggerTree.kt$FileLoggerTree$ private fun getNextLogFile()</ID>
|
<ID>ReturnCount:FileLoggerTree.kt$FileLoggerTree$ private fun getNextLogFile()</ID>
|
||||||
|
@ -241,7 +240,6 @@
|
||||||
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$e: Exception</ID>
|
||||||
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$e: Exception</ID>
|
||||||
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$x: IndexOutOfBoundsException</ID>
|
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$x: IndexOutOfBoundsException</ID>
|
||||||
<ID>TooGenericExceptionCaught:SelectAlbumFragment.kt$SelectAlbumFragment$exception: Exception</ID>
|
|
||||||
<ID>TooGenericExceptionCaught:SongView.kt$SongView$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:SongView.kt$SongView$e: Exception</ID>
|
||||||
<ID>TooGenericExceptionCaught:SubsonicUncaughtExceptionHandler.kt$SubsonicUncaughtExceptionHandler$x: Throwable</ID>
|
<ID>TooGenericExceptionCaught:SubsonicUncaughtExceptionHandler.kt$SubsonicUncaughtExceptionHandler$x: Throwable</ID>
|
||||||
<ID>TooGenericExceptionCaught:VideoPlayer.kt$VideoPlayer$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:VideoPlayer.kt$VideoPlayer$e: Exception</ID>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !deleteEnabled && !isOffline(context)</ID>
|
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !deleteEnabled && !isOffline(context)</ID>
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !isOffline(context) && selection.size > pinnedCount</ID>
|
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$enabled && !isOffline(context) && selection.size > pinnedCount</ID>
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$entry != null && !entry.isDirectory && !entry.isVideo</ID>
|
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment$entry != null && !entry.isDirectory && !entry.isVideo</ID>
|
||||||
<ID>ComplexCondition:SelectAlbumFragment.kt$SelectAlbumFragment.<no name provided>$Util.getShouldShowAllSongsByArtist(context) && musicDirectory.findChild(allSongsId) == null && musicDirectory.getChildren(true, false).size == musicDirectory.getChildren(true, true).size</ID>
|
<ID>ComplexCondition:SelectAlbumModel.kt$SelectAlbumModel$Util.getShouldShowAllSongsByArtist(context) && musicDirectory.findChild(allSongsId) == null && musicDirectory.getChildren(true, false).size == musicDirectory.getChildren(true, true).size</ID>
|
||||||
<ID>ComplexCondition:ServerSettingsModel.kt$ServerSettingsModel$url.isNullOrEmpty() || userName.isNullOrEmpty() || isMigrated</ID>
|
<ID>ComplexCondition:ServerSettingsModel.kt$ServerSettingsModel$url.isNullOrEmpty() || userName.isNullOrEmpty() || isMigrated</ID>
|
||||||
<ID>ComplexCondition:SongView.kt$SongView$TextUtils.isEmpty(transcodedSuffix) || transcodedSuffix == suffix || song.isVideo && Util.getVideoPlayerType(this.context) !== VideoPlayerType.FLASH</ID>
|
<ID>ComplexCondition:SongView.kt$SongView$TextUtils.isEmpty(transcodedSuffix) || transcodedSuffix == suffix || song.isVideo && Util.getVideoPlayerType(this.context) !== VideoPlayerType.FLASH</ID>
|
||||||
<ID>ComplexCondition:SubsonicImageLoaderProxy.kt$SubsonicImageLoaderProxy$id != null && view != null && view is ImageView</ID>
|
<ID>ComplexCondition:SubsonicImageLoaderProxy.kt$SubsonicImageLoaderProxy$id != null && view != null && view is ImageView</ID>
|
||||||
|
@ -49,10 +49,11 @@
|
||||||
<ID>ComplexMethod:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
<ID>ComplexMethod:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
||||||
<ID>ComplexMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
<ID>ComplexMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
||||||
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$protected override fun done(result: Pair<MusicDirectory, Boolean>)</ID>
|
<ID>ComplexMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateInterfaceWithEntries(musicDirectory: MusicDirectory)</ID>
|
||||||
|
<ID>ComplexMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getAlbumList(albumListType: String, size: Int, offset: Int)</ID>
|
||||||
|
<ID>ComplexMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getMusicDirectory( refresh: Boolean, id: String?, name: String?, parentId: String? )</ID>
|
||||||
<ID>ComplexMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
<ID>ComplexMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||||
<ID>ComplexMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
<ID>ComplexMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
||||||
<ID>ComplexMethod:SongView.kt$SongView$fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean)</ID>
|
<ID>ComplexMethod:SongView.kt$SongView$fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean)</ID>
|
||||||
|
@ -85,9 +86,9 @@
|
||||||
<ID>LargeClass:NavigationActivity.kt$NavigationActivity : AppCompatActivity</ID>
|
<ID>LargeClass:NavigationActivity.kt$NavigationActivity : AppCompatActivity</ID>
|
||||||
<ID>LargeClass:RESTMusicService.kt$RESTMusicService : MusicService</ID>
|
<ID>LargeClass:RESTMusicService.kt$RESTMusicService : MusicService</ID>
|
||||||
<ID>LargeClass:SelectAlbumFragment.kt$SelectAlbumFragment : Fragment</ID>
|
<ID>LargeClass:SelectAlbumFragment.kt$SelectAlbumFragment : Fragment</ID>
|
||||||
<ID>LargeClass:SelectAlbumFragment.kt$SelectAlbumFragment$LoadTask : FragmentBackgroundTask</ID>
|
<ID>LargeClass:SelectAlbumModel.kt$SelectAlbumModel : AndroidViewModelKoinComponent</ID>
|
||||||
<ID>LargeClass:SelectArtistFragment.kt$SelectArtistFragment : Fragment</ID>
|
<ID>LargeClass:SelectArtistFragment.kt$SelectArtistFragment : Fragment</ID>
|
||||||
<ID>LargeClass:ServerSettingsModel.kt$ServerSettingsModel : ViewModel</ID>
|
<ID>LargeClass:ServerSettingsModel.kt$ServerSettingsModel : AndroidViewModel</ID>
|
||||||
<ID>LargeClass:SongView.kt$SongView : UpdateViewCheckable</ID>
|
<ID>LargeClass:SongView.kt$SongView : UpdateViewCheckable</ID>
|
||||||
<ID>LongMethod:APIMusicDirectoryConverter.kt$fun MusicDirectoryChild.toDomainEntity(): MusicDirectory.Entry</ID>
|
<ID>LongMethod:APIMusicDirectoryConverter.kt$fun MusicDirectoryChild.toDomainEntity(): MusicDirectory.Entry</ID>
|
||||||
<ID>LongMethod:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
<ID>LongMethod:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
||||||
|
@ -140,14 +141,16 @@
|
||||||
<ID>LongMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
<ID>LongMethod:RestErrorMapper.kt$ fun SubsonicRESTException.getLocalizedErrorMessage(context: Context): String</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onContextItemSelected(menuItem: MenuItem): Boolean</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||||
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun createHeader( entries: List<MusicDirectory.Entry>, name: CharSequence?, songCount: Int ): View?</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun downloadBackground(save: Boolean, songs: List<MusicDirectory.Entry?>)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun downloadBackground(save: Boolean, songs: List<MusicDirectory.Entry?>)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun enableButtons()</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun playAll(shuffle: Boolean = false, append: Boolean = false)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun playAll(shuffle: Boolean = false, append: Boolean = false)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateDisplay(refresh: Boolean)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.<no name provided>$override fun done(result: Pair<MusicDirectory, Boolean>)</ID>
|
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment$private fun updateInterfaceWithEntries(musicDirectory: MusicDirectory)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.<no name provided>$override fun load(service: MusicService): MusicDirectory</ID>
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$protected fun createHeader( entries: List<MusicDirectory.Entry>, name: CharSequence?, songCount: Int ): View?</ID>
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getAlbumList(albumListType: String, size: Int, offset: Int)</ID>
|
||||||
<ID>LongMethod:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$protected override fun done(result: Pair<MusicDirectory, Boolean>)</ID>
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getArtist(refresh: Boolean, id: String?, name: String?)</ID>
|
||||||
|
<ID>LongMethod:SelectAlbumModel.kt$SelectAlbumModel$suspend fun getMusicDirectory( refresh: Boolean, id: String?, name: String?, parentId: String? )</ID>
|
||||||
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||||
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$private fun onArtistMenuItemSelected(menuItem: MenuItem, artist: Artist): Boolean</ID>
|
<ID>LongMethod:SelectArtistFragment.kt$SelectArtistFragment$private fun onArtistMenuItemSelected(menuItem: MenuItem, artist: Artist): Boolean</ID>
|
||||||
<ID>LongMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
<ID>LongMethod:ServerRowAdapter.kt$ServerRowAdapter$ override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View?</ID>
|
||||||
|
@ -204,7 +207,6 @@
|
||||||
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$206</ID>
|
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$206</ID>
|
||||||
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$5</ID>
|
<ID>MagicNumber:RESTMusicService.kt$RESTMusicService$5</ID>
|
||||||
<ID>MagicNumber:SelectAlbumFragment.kt$SelectAlbumFragment$10</ID>
|
<ID>MagicNumber:SelectAlbumFragment.kt$SelectAlbumFragment$10</ID>
|
||||||
<ID>MagicNumber:SelectAlbumFragment.kt$SelectAlbumFragment.LoadTask$10</ID>
|
|
||||||
<ID>MagicNumber:SelectMusicFolderView.kt$SelectMusicFolderView$10</ID>
|
<ID>MagicNumber:SelectMusicFolderView.kt$SelectMusicFolderView$10</ID>
|
||||||
<ID>MagicNumber:SongView.kt$SongView$3</ID>
|
<ID>MagicNumber:SongView.kt$SongView$3</ID>
|
||||||
<ID>MagicNumber:SongView.kt$SongView$4</ID>
|
<ID>MagicNumber:SongView.kt$SongView$4</ID>
|
||||||
|
@ -212,7 +214,6 @@
|
||||||
<ID>NestedBlockDepth:DownloadFile.kt$DownloadFile.DownloadTask$override fun execute()</ID>
|
<ID>NestedBlockDepth:DownloadFile.kt$DownloadFile.DownloadTask$override fun execute()</ID>
|
||||||
<ID>NestedBlockDepth:DownloadHandler.kt$DownloadHandler$private fun downloadRecursively( fragment: Fragment, id: String, name: String?, isShare: Boolean, isDirectory: Boolean, save: Boolean, append: Boolean, autoPlay: Boolean, shuffle: Boolean, background: Boolean, playNext: Boolean, unpin: Boolean, isArtist: Boolean )</ID>
|
<ID>NestedBlockDepth:DownloadHandler.kt$DownloadHandler$private fun downloadRecursively( fragment: Fragment, id: String, name: String?, isShare: Boolean, isDirectory: Boolean, save: Boolean, append: Boolean, autoPlay: Boolean, shuffle: Boolean, background: Boolean, playNext: Boolean, unpin: Boolean, isArtist: Boolean )</ID>
|
||||||
<ID>NestedBlockDepth:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
<ID>NestedBlockDepth:MediaPlayerService.kt$MediaPlayerService$private fun setupOnSongCompletedHandler()</ID>
|
||||||
<ID>NestedBlockDepth:SelectAlbumFragment.kt$SelectAlbumFragment$private fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?)</ID>
|
|
||||||
<ID>ReturnCount:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
<ID>ReturnCount:ActiveServerProvider.kt$ActiveServerProvider$ fun getActiveServer(): ServerSetting</ID>
|
||||||
<ID>ReturnCount:CommunicationErrorHandler.kt$CommunicationErrorHandler.Companion$fun getErrorMessage(error: Throwable, context: Context): String</ID>
|
<ID>ReturnCount:CommunicationErrorHandler.kt$CommunicationErrorHandler.Companion$fun getErrorMessage(error: Throwable, context: Context): String</ID>
|
||||||
<ID>ReturnCount:FileLoggerTree.kt$FileLoggerTree$ private fun getNextLogFile()</ID>
|
<ID>ReturnCount:FileLoggerTree.kt$FileLoggerTree$ private fun getNextLogFile()</ID>
|
||||||
|
@ -241,7 +242,6 @@
|
||||||
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$e: Exception</ID>
|
||||||
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$e: Exception</ID>
|
||||||
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$x: IndexOutOfBoundsException</ID>
|
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$x: IndexOutOfBoundsException</ID>
|
||||||
<ID>TooGenericExceptionCaught:SelectAlbumFragment.kt$SelectAlbumFragment$exception: Exception</ID>
|
|
||||||
<ID>TooGenericExceptionCaught:SongView.kt$SongView$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:SongView.kt$SongView$e: Exception</ID>
|
||||||
<ID>TooGenericExceptionCaught:SubsonicUncaughtExceptionHandler.kt$SubsonicUncaughtExceptionHandler$x: Throwable</ID>
|
<ID>TooGenericExceptionCaught:SubsonicUncaughtExceptionHandler.kt$SubsonicUncaughtExceptionHandler$x: Throwable</ID>
|
||||||
<ID>TooGenericExceptionCaught:VideoPlayer.kt$VideoPlayer$e: Exception</ID>
|
<ID>TooGenericExceptionCaught:VideoPlayer.kt$VideoPlayer$e: Exception</ID>
|
||||||
|
|
|
@ -49,8 +49,6 @@ complexity:
|
||||||
thresholdInFiles: 20
|
thresholdInFiles: 20
|
||||||
thresholdInClasses: 20
|
thresholdInClasses: 20
|
||||||
thresholdInInterfaces: 20
|
thresholdInInterfaces: 20
|
||||||
ComplexCondition:
|
|
||||||
threshold: 3
|
|
||||||
LabeledExpression:
|
LabeledExpression:
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
|
|
|
@ -492,13 +492,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMediaButtonsEnabled(boolean enabled) {
|
private void setMediaButtonsEnabled(boolean enabled) {
|
||||||
if (enabled) {
|
lockScreenEnabled.setEnabled(enabled);
|
||||||
lockScreenEnabled.setEnabled(true);
|
Util.updateMediaButtonEventReceiver();
|
||||||
Util.registerMediaButtonEventReceiver(getActivity(), false);
|
|
||||||
} else {
|
|
||||||
lockScreenEnabled.setEnabled(false);
|
|
||||||
Util.unregisterMediaButtonEventReceiver(getActivity(), false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBluetoothPreferences(boolean enabled) {
|
private void setBluetoothPreferences(boolean enabled) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.moire.ultrasonic.util.Constants;
|
||||||
import org.moire.ultrasonic.util.Util;
|
import org.moire.ultrasonic.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request media button focus when connected to Bluetooth A2DP.
|
* Resume or pause playback on Bluetooth A2DP connect/disconnect.
|
||||||
*
|
*
|
||||||
* @author Sindre Mehus
|
* @author Sindre Mehus
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,6 @@ public class BluetoothIntentReceiver extends BroadcastReceiver
|
||||||
if (state == android.bluetooth.BluetoothA2dp.STATE_CONNECTED) actionA2dpConnected = true;
|
if (state == android.bluetooth.BluetoothA2dp.STATE_CONNECTED) actionA2dpConnected = true;
|
||||||
else if (state == android.bluetooth.BluetoothA2dp.STATE_DISCONNECTED) actionA2dpDisconnected = true;
|
else if (state == android.bluetooth.BluetoothA2dp.STATE_DISCONNECTED) actionA2dpDisconnected = true;
|
||||||
|
|
||||||
boolean connected = actionA2dpConnected || actionBluetoothDeviceConnected;
|
|
||||||
boolean resume = false;
|
boolean resume = false;
|
||||||
boolean pause = false;
|
boolean pause = false;
|
||||||
|
|
||||||
|
@ -83,12 +82,6 @@ public class BluetoothIntentReceiver extends BroadcastReceiver
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connected)
|
|
||||||
{
|
|
||||||
Timber.i("Connected to Bluetooth device %s address %s, requesting media button focus.", name, address);
|
|
||||||
Util.registerMediaButtonEventReceiver(context, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resume)
|
if (resume)
|
||||||
{
|
{
|
||||||
Timber.i("Connected to Bluetooth device %s address %s, resuming playback.", name, address);
|
Timber.i("Connected to Bluetooth device %s address %s, resuming playback.", name, address);
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class MediaButtonIntentReceiver extends BroadcastReceiver
|
||||||
String intentAction = intent.getAction();
|
String intentAction = intent.getAction();
|
||||||
|
|
||||||
// If media button are turned off and we received a media button, exit
|
// If media button are turned off and we received a media button, exit
|
||||||
if (!Util.getMediaButtonsPreference(context) &&
|
if (!Util.getMediaButtonsEnabled(context) &&
|
||||||
Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) return;
|
Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) return;
|
||||||
|
|
||||||
// Only process media buttons and CMD_PROCESS_KEYCODE, which is received from the widgets
|
// Only process media buttons and CMD_PROCESS_KEYCODE, which is received from the widgets
|
||||||
|
|
|
@ -85,12 +85,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||||
public void onCreate()
|
public void onCreate()
|
||||||
{
|
{
|
||||||
if (created) return;
|
if (created) return;
|
||||||
this.externalStorageMonitor.onCreate(new Runnable() {
|
this.externalStorageMonitor.onCreate(this::reset);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setJukeboxEnabled(activeServerProvider.getValue().getActiveServer().getJukeboxByDefault());
|
setJukeboxEnabled(activeServerProvider.getValue().getActiveServer().getJukeboxByDefault());
|
||||||
created = true;
|
created = true;
|
||||||
|
@ -116,9 +111,8 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||||
|
|
||||||
if (currentPlayingIndex != -1)
|
if (currentPlayingIndex != -1)
|
||||||
{
|
{
|
||||||
MediaPlayerService.executeOnStartedMediaPlayerService(context, new Consumer<MediaPlayerService>() {
|
MediaPlayerService.executeOnStartedMediaPlayerService(context, (mediaPlayerService) ->
|
||||||
@Override
|
{
|
||||||
public void accept(MediaPlayerService mediaPlayerService) {
|
|
||||||
mediaPlayerService.play(currentPlayingIndex, autoPlayStart);
|
mediaPlayerService.play(currentPlayingIndex, autoPlayStart);
|
||||||
|
|
||||||
if (localMediaPlayer.currentPlaying != null)
|
if (localMediaPlayer.currentPlaying != null)
|
||||||
|
@ -136,8 +130,9 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
autoPlayStart = false;
|
autoPlayStart = false;
|
||||||
}
|
return null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,55 +144,53 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||||
@Override
|
@Override
|
||||||
public synchronized void play(final int index)
|
public synchronized void play(final int index)
|
||||||
{
|
{
|
||||||
MediaPlayerService.executeOnStartedMediaPlayerService(context,new Consumer<MediaPlayerService>() {
|
MediaPlayerService.executeOnStartedMediaPlayerService(context, (mediaPlayerService) -> {
|
||||||
@Override
|
|
||||||
public void accept(MediaPlayerService mediaPlayerService) {
|
|
||||||
mediaPlayerService.play(index, true);
|
mediaPlayerService.play(index, true);
|
||||||
}
|
return null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void play()
|
public synchronized void play()
|
||||||
{
|
{
|
||||||
MediaPlayerService.executeOnStartedMediaPlayerService(context, new Consumer<MediaPlayerService>() {
|
MediaPlayerService.executeOnStartedMediaPlayerService(context, (mediaPlayerService) -> {
|
||||||
@Override
|
|
||||||
public void accept(MediaPlayerService mediaPlayerService) {
|
|
||||||
mediaPlayerService.play();
|
mediaPlayerService.play();
|
||||||
}
|
return null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void resumeOrPlay()
|
public synchronized void resumeOrPlay()
|
||||||
{
|
{
|
||||||
MediaPlayerService.executeOnStartedMediaPlayerService(context, new Consumer<MediaPlayerService>() {
|
MediaPlayerService.executeOnStartedMediaPlayerService(context, (mediaPlayerService) -> {
|
||||||
@Override
|
|
||||||
public void accept(MediaPlayerService mediaPlayerService) {
|
|
||||||
mediaPlayerService.resumeOrPlay();
|
mediaPlayerService.resumeOrPlay();
|
||||||
}
|
return null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void togglePlayPause()
|
public synchronized void togglePlayPause()
|
||||||
{
|
{
|
||||||
if (localMediaPlayer.playerState == PlayerState.IDLE) autoPlayStart = true;
|
if (localMediaPlayer.playerState == PlayerState.IDLE) autoPlayStart = true;
|
||||||
MediaPlayerService.executeOnStartedMediaPlayerService(context,new Consumer<MediaPlayerService>() {
|
MediaPlayerService.executeOnStartedMediaPlayerService(context, (mediaPlayerService) -> {
|
||||||
@Override
|
|
||||||
public void accept(MediaPlayerService mediaPlayerService) {
|
|
||||||
mediaPlayerService.togglePlayPause();
|
mediaPlayerService.togglePlayPause();
|
||||||
}
|
return null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void start()
|
public synchronized void start()
|
||||||
{
|
{
|
||||||
MediaPlayerService.executeOnStartedMediaPlayerService(context, new Consumer<MediaPlayerService>() {
|
MediaPlayerService.executeOnStartedMediaPlayerService(context, (mediaPlayerService) -> {
|
||||||
@Override
|
|
||||||
public void accept(MediaPlayerService mediaPlayerService) {
|
|
||||||
mediaPlayerService.start();
|
mediaPlayerService.start();
|
||||||
}
|
return null;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -612,19 +605,14 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||||
final Entry song = localMediaPlayer.currentPlaying.getSong();
|
final Entry song = localMediaPlayer.currentPlaying.getSong();
|
||||||
song.setUserRating(rating);
|
song.setUserRating(rating);
|
||||||
|
|
||||||
new Thread(new Runnable()
|
new Thread(() -> {
|
||||||
{
|
try
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
{
|
||||||
try
|
MusicServiceFactory.getMusicService(context).setRating(song.getId(), rating, context);
|
||||||
{
|
}
|
||||||
MusicServiceFactory.getMusicService(context).setRating(song.getId(), rating, context);
|
catch (Exception e)
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
Timber.e(e);
|
||||||
{
|
|
||||||
Timber.e(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,6 @@ public class MediaPlayerLifecycleSupport
|
||||||
|
|
||||||
registerHeadsetReceiver();
|
registerHeadsetReceiver();
|
||||||
|
|
||||||
// React to media buttons.
|
|
||||||
Util.registerMediaButtonEventReceiver(context, true);
|
|
||||||
|
|
||||||
mediaPlayerController.onCreate();
|
mediaPlayerController.onCreate();
|
||||||
if (autoPlay) mediaPlayerController.preload();
|
if (autoPlay) mediaPlayerController.preload();
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
@ -54,8 +53,8 @@ import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||||
import org.moire.ultrasonic.domain.*;
|
import org.moire.ultrasonic.domain.*;
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||||
import org.moire.ultrasonic.receiver.MediaButtonIntentReceiver;
|
|
||||||
import org.moire.ultrasonic.service.DownloadFile;
|
import org.moire.ultrasonic.service.DownloadFile;
|
||||||
|
import org.moire.ultrasonic.service.MediaPlayerService;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
@ -679,31 +678,16 @@ public class Util
|
||||||
return Bitmap.createScaledBitmap(bitmap, size, getScaledHeight(bitmap, size), true);
|
return Bitmap.createScaledBitmap(bitmap, size, getScaledHeight(bitmap, size), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerMediaButtonEventReceiver(Context context, boolean isService)
|
// Trigger an update on the MediaSession. Depending on the preference it will register
|
||||||
|
// or deregister the MediaButtonReceiver.
|
||||||
|
public static void updateMediaButtonEventReceiver()
|
||||||
{
|
{
|
||||||
if (getMediaButtonsPreference(context))
|
MediaPlayerService mediaPlayerService = MediaPlayerService.getRunningInstance();
|
||||||
{
|
if (mediaPlayerService != null) {
|
||||||
if (isService) mediaButtonsRegisteredForService = true;
|
mediaPlayerService.updateMediaButtonReceiver();
|
||||||
else mediaButtonsRegisteredForUI = true;
|
|
||||||
|
|
||||||
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
audioManager.registerMediaButtonEventReceiver(new ComponentName(context.getPackageName(), MediaButtonIntentReceiver.class.getName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void unregisterMediaButtonEventReceiver(Context context, boolean isService)
|
|
||||||
{
|
|
||||||
if (isService) mediaButtonsRegisteredForService = false;
|
|
||||||
else mediaButtonsRegisteredForUI = false;
|
|
||||||
|
|
||||||
// Do not unregister while there is an active part of the app which needs the control
|
|
||||||
if (mediaButtonsRegisteredForService || mediaButtonsRegisteredForUI) return;
|
|
||||||
|
|
||||||
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
audioManager.unregisterMediaButtonEventReceiver(new ComponentName(context.getPackageName(), MediaButtonIntentReceiver.class.getName()));
|
|
||||||
Timber.i("MediaButtonEventReceiver unregistered.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MusicDirectory getSongsFromSearchResult(SearchResult searchResult)
|
public static MusicDirectory getSongsFromSearchResult(SearchResult searchResult)
|
||||||
{
|
{
|
||||||
MusicDirectory musicDirectory = new MusicDirectory();
|
MusicDirectory musicDirectory = new MusicDirectory();
|
||||||
|
@ -1056,7 +1040,7 @@ public class Util
|
||||||
return Integer.parseInt(preferences.getString(Constants.PREFERENCES_KEY_INCREMENT_TIME, "5"));
|
return Integer.parseInt(preferences.getString(Constants.PREFERENCES_KEY_INCREMENT_TIME, "5"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getMediaButtonsPreference(Context context)
|
public static boolean getMediaButtonsEnabled(Context context)
|
||||||
{
|
{
|
||||||
SharedPreferences preferences = getPreferences(context);
|
SharedPreferences preferences = getPreferences(context);
|
||||||
return preferences.getBoolean(Constants.PREFERENCES_KEY_MEDIA_BUTTONS, true);
|
return preferences.getBoolean(Constants.PREFERENCES_KEY_MEDIA_BUTTONS, true);
|
||||||
|
|
|
@ -33,6 +33,8 @@ import org.moire.ultrasonic.util.ImageLoader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This is the adapter for the display of a single list item (song, album, etc)
|
||||||
|
*
|
||||||
* @author Sindre Mehus
|
* @author Sindre Mehus
|
||||||
*/
|
*/
|
||||||
public class EntryAdapter extends ArrayAdapter<Entry>
|
public class EntryAdapter extends ArrayAdapter<Entry>
|
||||||
|
|
|
@ -14,6 +14,11 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A View that is periodically refreshed
|
||||||
|
* @deprecated
|
||||||
|
* Use LiveData to ensure that the content is up-to-date
|
||||||
|
**/
|
||||||
public class UpdateView extends LinearLayout
|
public class UpdateView extends LinearLayout
|
||||||
{
|
{
|
||||||
private static final WeakHashMap<UpdateView, ?> INSTANCES = new WeakHashMap<UpdateView, Object>();
|
private static final WeakHashMap<UpdateView, ?> INSTANCES = new WeakHashMap<UpdateView, Object>();
|
||||||
|
|
|
@ -178,7 +178,7 @@ class NavigationActivity : AppCompatActivity() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
setMenuForServerSetting()
|
setMenuForServerSetting()
|
||||||
Util.registerMediaButtonEventReceiver(this, false)
|
|
||||||
// Lifecycle support's constructor registers some event receivers so it should be created early
|
// Lifecycle support's constructor registers some event receivers so it should be created early
|
||||||
lifecycleSupport.onCreate()
|
lifecycleSupport.onCreate()
|
||||||
|
|
||||||
|
@ -188,7 +188,6 @@ class NavigationActivity : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
Util.unregisterMediaButtonEventReceiver(this, false)
|
|
||||||
nowPlayingEventDistributor.unsubscribe(nowPlayingEventListener)
|
nowPlayingEventDistributor.unsubscribe(nowPlayingEventListener)
|
||||||
themeChangedEventDistributor.unsubscribe(themeChangedEventListener)
|
themeChangedEventDistributor.unsubscribe(themeChangedEventListener)
|
||||||
imageLoaderProvider.clearImageLoader()
|
imageLoaderProvider.clearImageLoader()
|
||||||
|
@ -310,7 +309,6 @@ class NavigationActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private fun exit() {
|
private fun exit() {
|
||||||
lifecycleSupport.onDestroy()
|
lifecycleSupport.onDestroy()
|
||||||
Util.unregisterMediaButtonEventReceiver(this, false)
|
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,5 +31,5 @@ val appPermanentStorage = module {
|
||||||
|
|
||||||
single { get<AppDatabase>().serverSettingDao() }
|
single { get<AppDatabase>().serverSettingDao() }
|
||||||
|
|
||||||
viewModel { ServerSettingsModel(get(), get(), androidContext()) }
|
viewModel { ServerSettingsModel(get(), get(), get()) }
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,351 @@
|
||||||
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import java.util.LinkedList
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.koin.core.component.KoinApiExtension
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
import org.moire.ultrasonic.R
|
||||||
|
import org.moire.ultrasonic.api.subsonic.models.AlbumListType
|
||||||
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
|
import org.moire.ultrasonic.domain.MusicDirectory
|
||||||
|
import org.moire.ultrasonic.domain.MusicFolder
|
||||||
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
|
import org.moire.ultrasonic.util.Util
|
||||||
|
|
||||||
|
// TODO: Break up this class into smaller more specific classes, extending a base class if necessary
|
||||||
|
@KoinApiExtension
|
||||||
|
class SelectAlbumModel(application: Application) : AndroidViewModel(application), KoinComponent {
|
||||||
|
|
||||||
|
private val context: Context
|
||||||
|
get() = getApplication<Application>().applicationContext
|
||||||
|
|
||||||
|
private val activeServerProvider: ActiveServerProvider by inject()
|
||||||
|
|
||||||
|
private val allSongsId = "-1"
|
||||||
|
|
||||||
|
val musicFolders: MutableLiveData<List<MusicFolder>> = MutableLiveData()
|
||||||
|
val albumList: MutableLiveData<MusicDirectory> = MutableLiveData()
|
||||||
|
val currentDirectory: MutableLiveData<MusicDirectory> = MutableLiveData()
|
||||||
|
val songsForGenre: MutableLiveData<MusicDirectory> = MutableLiveData()
|
||||||
|
|
||||||
|
var currentDirectoryIsSortable = true
|
||||||
|
var showHeader = true
|
||||||
|
var showSelectFolderHeader = false
|
||||||
|
|
||||||
|
suspend fun getMusicFolders(refresh: Boolean) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val musicService = MusicServiceFactory.getMusicService(context)
|
||||||
|
musicFolders.postValue(musicService.getMusicFolders(refresh, context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getMusicDirectory(
|
||||||
|
refresh: Boolean,
|
||||||
|
id: String?,
|
||||||
|
name: String?,
|
||||||
|
parentId: String?
|
||||||
|
) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
|
||||||
|
var root = MusicDirectory()
|
||||||
|
|
||||||
|
if (allSongsId == id) {
|
||||||
|
val musicDirectory = service.getMusicDirectory(
|
||||||
|
parentId, name, refresh, context
|
||||||
|
)
|
||||||
|
|
||||||
|
val songs: MutableList<MusicDirectory.Entry> = LinkedList()
|
||||||
|
getSongsRecursively(musicDirectory, songs)
|
||||||
|
|
||||||
|
for (song in songs) {
|
||||||
|
if (!song.isDirectory) {
|
||||||
|
root.addChild(song)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val musicDirectory = service.getMusicDirectory(id, name, refresh, context)
|
||||||
|
|
||||||
|
if (Util.getShouldShowAllSongsByArtist(context) &&
|
||||||
|
musicDirectory.findChild(allSongsId) == null &&
|
||||||
|
hasOnlyFolders(musicDirectory)
|
||||||
|
) {
|
||||||
|
val allSongs = MusicDirectory.Entry()
|
||||||
|
|
||||||
|
allSongs.isDirectory = true
|
||||||
|
allSongs.artist = name
|
||||||
|
allSongs.parent = id
|
||||||
|
allSongs.id = allSongsId
|
||||||
|
allSongs.title = String.format(
|
||||||
|
context.resources.getString(R.string.select_album_all_songs), name
|
||||||
|
)
|
||||||
|
|
||||||
|
root.addChild(allSongs)
|
||||||
|
root.addAll(musicDirectory.getChildren())
|
||||||
|
} else {
|
||||||
|
root = musicDirectory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDirectory.postValue(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a Music directory "songs" it recursively adds all children to "songs"
|
||||||
|
private fun getSongsRecursively(
|
||||||
|
parent: MusicDirectory,
|
||||||
|
songs: MutableList<MusicDirectory.Entry>
|
||||||
|
) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
|
||||||
|
for (song in parent.getChildren(includeDirs = false, includeFiles = true)) {
|
||||||
|
if (!song.isVideo && !song.isDirectory) {
|
||||||
|
songs.add(song)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((id1, _, _, title) in parent.getChildren(true, includeFiles = false)) {
|
||||||
|
var root: MusicDirectory
|
||||||
|
|
||||||
|
if (allSongsId != id1) {
|
||||||
|
root = service.getMusicDirectory(id1, title, false, context)
|
||||||
|
|
||||||
|
getSongsRecursively(root, songs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getArtist(refresh: Boolean, id: String?, name: String?) {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
|
||||||
|
var root = MusicDirectory()
|
||||||
|
|
||||||
|
val musicDirectory = service.getArtist(id, name, refresh, context)
|
||||||
|
|
||||||
|
if (Util.getShouldShowAllSongsByArtist(context) &&
|
||||||
|
musicDirectory.findChild(allSongsId) == null &&
|
||||||
|
hasOnlyFolders(musicDirectory)
|
||||||
|
) {
|
||||||
|
val allSongs = MusicDirectory.Entry()
|
||||||
|
|
||||||
|
allSongs.isDirectory = true
|
||||||
|
allSongs.artist = name
|
||||||
|
allSongs.parent = id
|
||||||
|
allSongs.id = allSongsId
|
||||||
|
allSongs.title = String.format(
|
||||||
|
context.resources.getString(R.string.select_album_all_songs), name
|
||||||
|
)
|
||||||
|
|
||||||
|
root.addFirst(allSongs)
|
||||||
|
root.addAll(musicDirectory.getChildren())
|
||||||
|
} else {
|
||||||
|
root = musicDirectory
|
||||||
|
}
|
||||||
|
currentDirectory.postValue(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?) {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
|
||||||
|
val musicDirectory: MusicDirectory
|
||||||
|
|
||||||
|
musicDirectory = if (allSongsId == id) {
|
||||||
|
val root = MusicDirectory()
|
||||||
|
|
||||||
|
val songs: MutableCollection<MusicDirectory.Entry> = LinkedList()
|
||||||
|
val artist = service.getArtist(parentId, "", false, context)
|
||||||
|
|
||||||
|
for ((id1) in artist.getChildren()) {
|
||||||
|
if (allSongsId != id1) {
|
||||||
|
val albumDirectory = service.getAlbum(
|
||||||
|
id1, "", false, context
|
||||||
|
)
|
||||||
|
|
||||||
|
for (song in albumDirectory.getChildren()) {
|
||||||
|
if (!song.isVideo) {
|
||||||
|
songs.add(song)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (song in songs) {
|
||||||
|
if (!song.isDirectory) {
|
||||||
|
root.addChild(song)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root
|
||||||
|
} else {
|
||||||
|
service.getAlbum(id, name, refresh, context)
|
||||||
|
}
|
||||||
|
currentDirectory.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getSongsForGenre(genre: String, count: Int, offset: Int) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory = service.getSongsByGenre(genre, count, offset, context)
|
||||||
|
songsForGenre.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getStarred() {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory: MusicDirectory
|
||||||
|
val context = context
|
||||||
|
|
||||||
|
if (Util.getShouldUseId3Tags(context)) {
|
||||||
|
musicDirectory = Util.getSongsFromSearchResult(service.getStarred2(context))
|
||||||
|
} else {
|
||||||
|
musicDirectory = Util.getSongsFromSearchResult(service.getStarred(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDirectory.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getVideos(refresh: Boolean) {
|
||||||
|
showHeader = false
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
currentDirectory.postValue(service.getVideos(refresh, context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getRandom(size: Int) {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory = service.getRandomSongs(size, context)
|
||||||
|
|
||||||
|
currentDirectoryIsSortable = false
|
||||||
|
currentDirectory.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getPlaylist(playlistId: String, playlistName: String?) {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory = service.getPlaylist(playlistId, playlistName, context)
|
||||||
|
|
||||||
|
currentDirectory.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getPodcastEpisodes(podcastChannelId: String) {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory = service.getPodcastEpisodes(podcastChannelId, context)
|
||||||
|
currentDirectory.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getShare(shareId: String) {
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory = MusicDirectory()
|
||||||
|
|
||||||
|
val shares = service.getShares(true, context)
|
||||||
|
|
||||||
|
for (share in shares) {
|
||||||
|
if (share.id == shareId) {
|
||||||
|
for (entry in share.getEntries()) {
|
||||||
|
musicDirectory.addChild(entry)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentDirectory.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getAlbumList(albumListType: String, size: Int, offset: Int) {
|
||||||
|
|
||||||
|
showHeader = false
|
||||||
|
showSelectFolderHeader = !ActiveServerProvider.isOffline(context) &&
|
||||||
|
!Util.getShouldUseId3Tags(context) && (
|
||||||
|
(albumListType == AlbumListType.SORTED_BY_NAME.toString()) ||
|
||||||
|
(albumListType == AlbumListType.SORTED_BY_ARTIST.toString())
|
||||||
|
)
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (!ActiveServerProvider.isOffline(context)) {
|
||||||
|
val service = MusicServiceFactory.getMusicService(context)
|
||||||
|
val musicDirectory: MusicDirectory
|
||||||
|
val musicFolderId = if (showSelectFolderHeader) {
|
||||||
|
activeServerProvider.getActiveServer().musicFolderId
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Util.getShouldUseId3Tags(context)) {
|
||||||
|
musicDirectory = service.getAlbumList2(
|
||||||
|
albumListType, size,
|
||||||
|
offset, musicFolderId, context
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
musicDirectory = service.getAlbumList(
|
||||||
|
albumListType, size,
|
||||||
|
offset, musicFolderId, context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDirectoryIsSortable = sortableCollection(albumListType)
|
||||||
|
albumList.postValue(musicDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sortableCollection(albumListType: String): Boolean {
|
||||||
|
return albumListType != "newest" && albumListType != "random" &&
|
||||||
|
albumListType != "highest" && albumListType != "recent" &&
|
||||||
|
albumListType != "frequent"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the directory contains only folders
|
||||||
|
private fun hasOnlyFolders(musicDirectory: MusicDirectory) =
|
||||||
|
musicDirectory.getChildren(includeDirs = true, includeFiles = false).size ==
|
||||||
|
musicDirectory.getChildren(includeDirs = true, includeFiles = true).size
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
package org.moire.ultrasonic.fragment
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.content.Context
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -22,8 +22,8 @@ import timber.log.Timber
|
||||||
class ServerSettingsModel(
|
class ServerSettingsModel(
|
||||||
private val repository: ServerSettingDao,
|
private val repository: ServerSettingDao,
|
||||||
private val activeServerProvider: ActiveServerProvider,
|
private val activeServerProvider: ActiveServerProvider,
|
||||||
private val context: Context
|
application: Application
|
||||||
) : ViewModel() {
|
) : AndroidViewModel(application) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val PREFERENCES_KEY_SERVER_MIGRATED = "serverMigrated"
|
private const val PREFERENCES_KEY_SERVER_MIGRATED = "serverMigrated"
|
||||||
|
@ -54,6 +54,7 @@ class ServerSettingsModel(
|
||||||
if (rowCount == null || rowCount == 0) {
|
if (rowCount == null || rowCount == 0) {
|
||||||
// First time load up the server settings from the Preferences
|
// First time load up the server settings from the Preferences
|
||||||
val dbServerList = mutableListOf<ServerSetting>()
|
val dbServerList = mutableListOf<ServerSetting>()
|
||||||
|
val context = getApplication<Application>().applicationContext
|
||||||
val settings = PreferenceManager.getDefaultSharedPreferences(context)
|
val settings = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
val serverNum = settings.getInt(PREFERENCES_KEY_ACTIVE_SERVERS, 0)
|
val serverNum = settings.getInt(PREFERENCES_KEY_ACTIVE_SERVERS, 0)
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,6 @@ class LocalMediaPlayer(
|
||||||
}.start()
|
}.start()
|
||||||
|
|
||||||
wakeLock.setReferenceCounted(false)
|
wakeLock.setReferenceCounted(false)
|
||||||
Util.registerMediaButtonEventReceiver(context, true)
|
|
||||||
Timber.i("LocalMediaPlayer created")
|
Timber.i("LocalMediaPlayer created")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +145,7 @@ class LocalMediaPlayer(
|
||||||
if (nextPlayingTask != null) {
|
if (nextPlayingTask != null) {
|
||||||
nextPlayingTask!!.cancel()
|
nextPlayingTask!!.cancel()
|
||||||
}
|
}
|
||||||
Util.unregisterMediaButtonEventReceiver(context, true)
|
|
||||||
wakeLock.release()
|
wakeLock.release()
|
||||||
} catch (exception: Throwable) {
|
} catch (exception: Throwable) {
|
||||||
Timber.w(exception, "LocalMediaPlayer onDestroy exception: ")
|
Timber.w(exception, "LocalMediaPlayer onDestroy exception: ")
|
||||||
|
|
|
@ -12,6 +12,7 @@ import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -22,7 +23,6 @@ import android.support.v4.media.session.PlaybackStateCompat
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import java.util.ArrayList
|
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.activity.NavigationActivity
|
import org.moire.ultrasonic.activity.NavigationActivity
|
||||||
|
@ -33,6 +33,7 @@ import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X1
|
||||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X2
|
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X2
|
||||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X3
|
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X3
|
||||||
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X4
|
import org.moire.ultrasonic.provider.UltrasonicAppWidgetProvider4X4
|
||||||
|
import org.moire.ultrasonic.receiver.MediaButtonIntentReceiver
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
import org.moire.ultrasonic.util.FileUtil
|
import org.moire.ultrasonic.util.FileUtil
|
||||||
|
@ -792,7 +793,8 @@ class MediaPlayerService : Service() {
|
||||||
|
|
||||||
mediaSession = MediaSessionCompat(applicationContext, "UltrasonicService")
|
mediaSession = MediaSessionCompat(applicationContext, "UltrasonicService")
|
||||||
mediaSessionToken = mediaSession!!.sessionToken
|
mediaSessionToken = mediaSession!!.sessionToken
|
||||||
// mediaController = new MediaControllerCompat(getApplicationContext(), mediaSessionToken);
|
|
||||||
|
updateMediaButtonReceiver()
|
||||||
|
|
||||||
mediaSession!!.setCallback(object : MediaSessionCompat.Callback() {
|
mediaSession!!.setCallback(object : MediaSessionCompat.Callback() {
|
||||||
override fun onPlay() {
|
override fun onPlay() {
|
||||||
|
@ -838,10 +840,39 @@ class MediaPlayerService : Service() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateMediaButtonReceiver() {
|
||||||
|
if (Util.getMediaButtonsEnabled(applicationContext)) {
|
||||||
|
registerMediaButtonEventReceiver()
|
||||||
|
} else {
|
||||||
|
unregisterMediaButtonEventReceiver()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerMediaButtonEventReceiver() {
|
||||||
|
val component = ComponentName(packageName, MediaButtonIntentReceiver::class.java.name)
|
||||||
|
val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON)
|
||||||
|
mediaButtonIntent.component = component
|
||||||
|
|
||||||
|
val pendingIntent = PendingIntent.getBroadcast(
|
||||||
|
this,
|
||||||
|
INTENT_CODE_MEDIA_BUTTON,
|
||||||
|
mediaButtonIntent,
|
||||||
|
PendingIntent.FLAG_CANCEL_CURRENT
|
||||||
|
)
|
||||||
|
|
||||||
|
mediaSession?.setMediaButtonReceiver(pendingIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterMediaButtonEventReceiver() {
|
||||||
|
mediaSession?.setMediaButtonReceiver(null)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val NOTIFICATION_CHANNEL_ID = "org.moire.ultrasonic"
|
private const val NOTIFICATION_CHANNEL_ID = "org.moire.ultrasonic"
|
||||||
private const val NOTIFICATION_CHANNEL_NAME = "Ultrasonic background service"
|
private const val NOTIFICATION_CHANNEL_NAME = "Ultrasonic background service"
|
||||||
private const val NOTIFICATION_ID = 3033
|
private const val NOTIFICATION_ID = 3033
|
||||||
|
private const val INTENT_CODE_MEDIA_BUTTON = 161
|
||||||
|
|
||||||
private var instance: MediaPlayerService? = null
|
private var instance: MediaPlayerService? = null
|
||||||
private val instanceLock = Any()
|
private val instanceLock = Any()
|
||||||
|
|
||||||
|
@ -872,7 +903,7 @@ class MediaPlayerService : Service() {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun executeOnStartedMediaPlayerService(
|
fun executeOnStartedMediaPlayerService(
|
||||||
context: Context,
|
context: Context,
|
||||||
taskToExecute: Consumer<MediaPlayerService?>
|
taskToExecute: (MediaPlayerService?) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val t: Thread = object : Thread() {
|
val t: Thread = object : Thread() {
|
||||||
|
@ -882,7 +913,7 @@ class MediaPlayerService : Service() {
|
||||||
Timber.e("ExecuteOnStarted.. failed to get a MediaPlayerService instance!")
|
Timber.e("ExecuteOnStarted.. failed to get a MediaPlayerService instance!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
taskToExecute.accept(instance)
|
taskToExecute(instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.start()
|
t.start()
|
||||||
|
|
Loading…
Reference in New Issue