mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Improve Kotlin converted from java in various places
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -37,7 +37,6 @@ import org.schabi.newpipe.player.notification.NotificationPlayerUi | |||||||
| import org.schabi.newpipe.util.Localization | import org.schabi.newpipe.util.Localization | ||||||
| import org.schabi.newpipe.util.ThemeHelper | import org.schabi.newpipe.util.ThemeHelper | ||||||
| import java.lang.ref.WeakReference | import java.lang.ref.WeakReference | ||||||
| import java.util.function.BiConsumer |  | ||||||
| import java.util.function.Consumer | import java.util.function.Consumer | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -47,13 +46,13 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|     // These objects are used to cleanly separate the Service implementation (in this file) and the |     // These objects are used to cleanly separate the Service implementation (in this file) and the | ||||||
|     // media browser and playback preparer implementations. At the moment the playback preparer is |     // media browser and playback preparer implementations. At the moment the playback preparer is | ||||||
|     // only used in conjunction with the media browser. |     // only used in conjunction with the media browser. | ||||||
|     private var mediaBrowserImpl: MediaBrowserImpl? = null |     private lateinit var mediaBrowserImpl: MediaBrowserImpl | ||||||
|     private var mediaBrowserPlaybackPreparer: MediaBrowserPlaybackPreparer? = null |     private lateinit var mediaBrowserPlaybackPreparer: MediaBrowserPlaybackPreparer | ||||||
|  |  | ||||||
|     // these are instantiated in onCreate() as per |     // these are instantiated in onCreate() as per | ||||||
|     // https://developer.android.com/training/cars/media#browser_workflow |     // https://developer.android.com/training/cars/media#browser_workflow | ||||||
|     private var mediaSession: MediaSessionCompat? = null |     private lateinit var mediaSession: MediaSessionCompat | ||||||
|     private var sessionConnector: MediaSessionConnector? = null |     private lateinit var sessionConnector: MediaSessionConnector | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @return the current active player instance. May be null, since the player service can outlive |      * @return the current active player instance. May be null, since the player service can outlive | ||||||
| @@ -68,7 +67,7 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|      * The parameter taken by this [Consumer] can be null to indicate the player is being |      * The parameter taken by this [Consumer] can be null to indicate the player is being | ||||||
|      * stopped. |      * stopped. | ||||||
|      */ |      */ | ||||||
|     private var onPlayerStartedOrStopped: Consumer<Player?>? = null |     private var onPlayerStartedOrStopped: ((player: Player?) -> Unit)? = null | ||||||
|  |  | ||||||
|     //region Service lifecycle |     //region Service lifecycle | ||||||
|     override fun onCreate() { |     override fun onCreate() { | ||||||
| @@ -80,14 +79,7 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|         Localization.assureCorrectAppLanguage(this) |         Localization.assureCorrectAppLanguage(this) | ||||||
|         ThemeHelper.setTheme(this) |         ThemeHelper.setTheme(this) | ||||||
|  |  | ||||||
|         mediaBrowserImpl = MediaBrowserImpl( |         mediaBrowserImpl = MediaBrowserImpl(this, this::notifyChildrenChanged) | ||||||
|             this, |  | ||||||
|             Consumer { parentId: String -> |  | ||||||
|                 this.notifyChildrenChanged( |  | ||||||
|                     parentId |  | ||||||
|                 ) |  | ||||||
|             } |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         // see https://developer.android.com/training/cars/media#browser_workflow |         // see https://developer.android.com/training/cars/media#browser_workflow | ||||||
|         val session = MediaSessionCompat(this, "MediaSessionPlayerServ") |         val session = MediaSessionCompat(this, "MediaSessionPlayerServ") | ||||||
| @@ -98,17 +90,10 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|         connector.setMetadataDeduplicationEnabled(true) |         connector.setMetadataDeduplicationEnabled(true) | ||||||
|  |  | ||||||
|         mediaBrowserPlaybackPreparer = MediaBrowserPlaybackPreparer( |         mediaBrowserPlaybackPreparer = MediaBrowserPlaybackPreparer( | ||||||
|             this, |             context = this, | ||||||
|             BiConsumer { message: String, code: Int -> |             setMediaSessionError = connector::setCustomErrorMessage, | ||||||
|                 connector.setCustomErrorMessage( |             clearMediaSessionError = { connector.setCustomErrorMessage(null) }, | ||||||
|                     message, |             onPrepare = { player?.onPrepare() } | ||||||
|                     code |  | ||||||
|                 ) |  | ||||||
|             }, |  | ||||||
|             Runnable { connector.setCustomErrorMessage(null) }, |  | ||||||
|             Consumer { playWhenReady: Boolean? -> |  | ||||||
|                 player?.onPrepare() |  | ||||||
|             } |  | ||||||
|         ) |         ) | ||||||
|         connector.setPlaybackPreparer(mediaBrowserPlaybackPreparer) |         connector.setPlaybackPreparer(mediaBrowserPlaybackPreparer) | ||||||
|  |  | ||||||
| @@ -125,11 +110,8 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|         if (DEBUG) { |         if (DEBUG) { | ||||||
|             Log.d( |             Log.d( | ||||||
|                 TAG, |                 TAG, | ||||||
|                 ( |                 "onStartCommand() called with: intent = [$intent], extras = [${ | ||||||
|                     "onStartCommand() called with: intent = [" + intent + |                 intent.extras.toDebugString()}], flags = [$flags], startId = [$startId]" | ||||||
|                         "], extras = [" + intent.extras.toDebugString() + |  | ||||||
|                         "], flags = [" + flags + "], startId = [" + startId + "]" |  | ||||||
|                     ) |  | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -140,7 +122,7 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|             val playerWasNull = (player == null) |             val playerWasNull = (player == null) | ||||||
|             if (playerWasNull) { |             if (playerWasNull) { | ||||||
|                 // make sure the player exists, in case the service was resumed |                 // make sure the player exists, in case the service was resumed | ||||||
|                 player = Player(this, mediaSession!!, sessionConnector!!) |                 player = Player(this, mediaSession, sessionConnector) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // Be sure that the player notification is set and the service is started in foreground, |             // Be sure that the player notification is set and the service is started in foreground, | ||||||
| @@ -150,35 +132,29 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|             // no one already and starting the service in foreground should not create any issues. |             // no one already and starting the service in foreground should not create any issues. | ||||||
|             // If the service is already started in foreground, requesting it to be started |             // If the service is already started in foreground, requesting it to be started | ||||||
|             // shouldn't do anything. |             // shouldn't do anything. | ||||||
|             player!!.UIs().get(NotificationPlayerUi::class.java) |             player?.UIs()?.get(NotificationPlayerUi::class)?.createNotificationAndStartForeground() | ||||||
|                 ?.createNotificationAndStartForeground() |  | ||||||
|  |  | ||||||
|             val startedOrStopped = onPlayerStartedOrStopped |             if (playerWasNull) { | ||||||
|             if (playerWasNull && startedOrStopped != null) { |  | ||||||
|                 // notify that a new player was created (but do it after creating the foreground |                 // notify that a new player was created (but do it after creating the foreground | ||||||
|                 // notification just to make sure we don't incur, due to slowness, in |                 // notification just to make sure we don't incur, due to slowness, in | ||||||
|                 // "Context.startForegroundService() did not then call Service.startForeground()") |                 // "Context.startForegroundService() did not then call Service.startForeground()") | ||||||
|                 startedOrStopped.accept(player) |                 onPlayerStartedOrStopped?.invoke(player) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         val p = player |         val p = player | ||||||
|         if (Intent.ACTION_MEDIA_BUTTON == intent.action && |         if (Intent.ACTION_MEDIA_BUTTON == intent.action && p?.playQueue == null) { | ||||||
|             (p == null || p.playQueue == null) |             // No need to process media button's actions if the player is not working, otherwise | ||||||
|         ) { |             // the player service would strangely start with nothing to play | ||||||
|             /* |             // Stop the service in this case, which will be removed from the foreground and its | ||||||
|             No need to process media button's actions if the player is not working, otherwise |             // notification cancelled in its destruction | ||||||
|             the player service would strangely start with nothing to play |  | ||||||
|             Stop the service in this case, which will be removed from the foreground and its |  | ||||||
|             notification cancelled in its destruction |  | ||||||
|              */ |  | ||||||
|             destroyPlayerAndStopService() |             destroyPlayerAndStopService() | ||||||
|             return START_NOT_STICKY |             return START_NOT_STICKY | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (p != null) { |         if (p != null) { | ||||||
|             p.handleIntent(intent) |             p.handleIntent(intent) | ||||||
|             p.UIs().get(MediaSessionPlayerUi::class.java) |             p.UIs().get(MediaSessionPlayerUi::class) | ||||||
|                 ?.handleMediaButtonIntent(intent) |                 ?.handleMediaButtonIntent(intent) | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -218,22 +194,22 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|  |  | ||||||
|         cleanup() |         cleanup() | ||||||
|  |  | ||||||
|         mediaBrowserPlaybackPreparer?.dispose() |         mediaBrowserPlaybackPreparer.dispose() | ||||||
|         mediaSession?.release() |         mediaSession.release() | ||||||
|         mediaBrowserImpl?.dispose() |         mediaBrowserImpl.dispose() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun cleanup() { |     private fun cleanup() { | ||||||
|         val p = player |         val p = player | ||||||
|         if (p != null) { |         if (p != null) { | ||||||
|             // notify that the player is being destroyed |             // notify that the player is being destroyed | ||||||
|             onPlayerStartedOrStopped?.accept(null) |             onPlayerStartedOrStopped?.invoke(null) | ||||||
|             p.saveAndShutdown() |             p.saveAndShutdown() | ||||||
|             player = null |             player = null | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Should already be handled by MediaSessionPlayerUi, but just to be sure. |         // Should already be handled by MediaSessionPlayerUi, but just to be sure. | ||||||
|         mediaSession?.setActive(false) |         mediaSession.setActive(false) | ||||||
|  |  | ||||||
|         // Should already be handled by NotificationUtil.cancelNotificationAndStopForeground() in |         // Should already be handled by NotificationUtil.cancelNotificationAndStopForeground() in | ||||||
|         // NotificationPlayerUi, but let's make sure that the foreground service is stopped. |         // NotificationPlayerUi, but let's make sure that the foreground service is stopped. | ||||||
| @@ -273,24 +249,22 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|         if (DEBUG) { |         if (DEBUG) { | ||||||
|             Log.d( |             Log.d( | ||||||
|                 TAG, |                 TAG, | ||||||
|                 ( |                 "onBind() called with: intent = [$intent], extras = [${ | ||||||
|                     "onBind() called with: intent = [" + intent + |                 intent.extras.toDebugString()}]" | ||||||
|                         "], extras = [" + intent.extras.toDebugString() + "]" |  | ||||||
|                     ) |  | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (BIND_PLAYER_HOLDER_ACTION == intent.action) { |         return if (BIND_PLAYER_HOLDER_ACTION == intent.action) { | ||||||
|             // Note that this binder might be reused multiple times while the service is alive, even |             // Note that this binder might be reused multiple times while the service is alive, even | ||||||
|             // after unbind() has been called: https://stackoverflow.com/a/8794930 . |             // after unbind() has been called: https://stackoverflow.com/a/8794930 . | ||||||
|             return mBinder |             mBinder | ||||||
|         } else if (SERVICE_INTERFACE == intent.action) { |         } else if (SERVICE_INTERFACE == intent.action) { | ||||||
|             // MediaBrowserService also uses its own binder, so for actions related to the media |             // MediaBrowserService also uses its own binder, so for actions related to the media | ||||||
|             // browser service, pass the onBind to the superclass. |             // browser service, pass the onBind to the superclass. | ||||||
|             return super.onBind(intent) |             super.onBind(intent) | ||||||
|         } else { |         } else { | ||||||
|             // This is an unknown request, avoid returning any binder to not leak objects. |             // This is an unknown request, avoid returning any binder to not leak objects. | ||||||
|             return null |             null | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -307,9 +281,9 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|      * by the [Consumer] can be null to indicate that the player is stopping. |      * by the [Consumer] can be null to indicate that the player is stopping. | ||||||
|      * @param listener the listener to set or unset |      * @param listener the listener to set or unset | ||||||
|      */ |      */ | ||||||
|     fun setPlayerListener(listener: Consumer<Player?>?) { |     fun setPlayerListener(listener: ((player: Player?) -> Unit)?) { | ||||||
|         this.onPlayerStartedOrStopped = listener |         this.onPlayerStartedOrStopped = listener | ||||||
|         listener?.accept(player) |         listener?.invoke(player) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //endregion |     //endregion | ||||||
| @@ -320,14 +294,14 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|         rootHints: Bundle? |         rootHints: Bundle? | ||||||
|     ): BrowserRoot? { |     ): BrowserRoot? { | ||||||
|         // TODO check if the accessing package has permission to view data |         // TODO check if the accessing package has permission to view data | ||||||
|         return mediaBrowserImpl?.onGetRoot(clientPackageName, clientUid, rootHints) |         return mediaBrowserImpl.onGetRoot(clientPackageName, clientUid, rootHints) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onLoadChildren( |     override fun onLoadChildren( | ||||||
|         parentId: String, |         parentId: String, | ||||||
|         result: Result<List<MediaBrowserCompat.MediaItem>> |         result: Result<List<MediaBrowserCompat.MediaItem>> | ||||||
|     ) { |     ) { | ||||||
|         mediaBrowserImpl?.onLoadChildren(parentId, result) |         mediaBrowserImpl.onLoadChildren(parentId, result) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun onSearch( |     override fun onSearch( | ||||||
| @@ -335,7 +309,7 @@ class PlayerService : MediaBrowserServiceCompat() { | |||||||
|         extras: Bundle?, |         extras: Bundle?, | ||||||
|         result: Result<List<MediaBrowserCompat.MediaItem>> |         result: Result<List<MediaBrowserCompat.MediaItem>> | ||||||
|     ) { |     ) { | ||||||
|         mediaBrowserImpl?.onSearch(query, result) |         mediaBrowserImpl.onSearch(query, result) | ||||||
|     } //endregion |     } //endregion | ||||||
|  |  | ||||||
|     companion object { |     companion object { | ||||||
|   | |||||||
| @@ -20,7 +20,6 @@ import org.schabi.newpipe.player.event.PlayerServiceEventListener | |||||||
| import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener | import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener | ||||||
| import org.schabi.newpipe.player.playqueue.PlayQueue | import org.schabi.newpipe.player.playqueue.PlayQueue | ||||||
| import org.schabi.newpipe.util.NavigationHelper | import org.schabi.newpipe.util.NavigationHelper | ||||||
| import java.util.function.Consumer |  | ||||||
|  |  | ||||||
| private val DEBUG = MainActivity.DEBUG | private val DEBUG = MainActivity.DEBUG | ||||||
| private val TAG: String = PlayerHolder::class.java.getSimpleName() | private val TAG: String = PlayerHolder::class.java.getSimpleName() | ||||||
| @@ -40,9 +39,9 @@ object PlayerHolder { | |||||||
|     private val player: Player? |     private val player: Player? | ||||||
|         get() = playerService?.player |         get() = playerService?.player | ||||||
|  |  | ||||||
|  |     // player play queue might be null e.g. while player is starting | ||||||
|     private val playQueue: PlayQueue? |     private val playQueue: PlayQueue? | ||||||
|         get() = // player play queue might be null e.g. while player is starting |         get() = this.player?.playQueue | ||||||
|             this.player?.playQueue |  | ||||||
|  |  | ||||||
|     val type: PlayerType? |     val type: PlayerType? | ||||||
|         /** |         /** | ||||||
| @@ -78,8 +77,8 @@ object PlayerHolder { | |||||||
|  |  | ||||||
|         // Force reload data from service |         // Force reload data from service | ||||||
|         newListener?.let { listener -> |         newListener?.let { listener -> | ||||||
|             playerService?.let { |             playerService?.let { service -> | ||||||
|                 listener.onServiceConnected(it) |                 listener.onServiceConnected(service) | ||||||
|                 startPlayerListener() |                 startPlayerListener() | ||||||
|                 // ^ will call listener.onPlayerConnected() down the line if there is an active player |                 // ^ will call listener.onPlayerConnected() down the line if there is an active player | ||||||
|             } |             } | ||||||
| @@ -103,7 +102,7 @@ object PlayerHolder { | |||||||
|         newListener: PlayerServiceExtendedEventListener? |         newListener: PlayerServiceExtendedEventListener? | ||||||
|     ) { |     ) { | ||||||
|         if (DEBUG) { |         if (DEBUG) { | ||||||
|             Log.d(TAG, "startService() called with playAfterConnect=" + playAfterConnect) |             Log.d(TAG, "startService() called with playAfterConnect=$playAfterConnect") | ||||||
|         } |         } | ||||||
|         val context = this.commonContext |         val context = this.commonContext | ||||||
|         setListener(newListener) |         setListener(newListener) | ||||||
| @@ -162,21 +161,15 @@ object PlayerHolder { | |||||||
|  |  | ||||||
|             val s = localBinder.service |             val s = localBinder.service | ||||||
|             requireNotNull(s) { |             requireNotNull(s) { | ||||||
|                 ( |  | ||||||
|                 "PlayerService.LocalBinder.getService() must never be" + |                 "PlayerService.LocalBinder.getService() must never be" + | ||||||
|                     "null after the service connects" |                     "null after the service connects" | ||||||
|                     ) |  | ||||||
|             } |             } | ||||||
|             playerService = s |             playerService = s | ||||||
|             val l = listener |             listener?.let { l -> | ||||||
|             if (l != null) { |  | ||||||
|                 l.onServiceConnected(s) |                 l.onServiceConnected(s) | ||||||
|                 player?.let { |                 player?.let { l.onPlayerConnected(it, playAfterConnect) } | ||||||
|                     l.onPlayerConnected(it, playAfterConnect) |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             startPlayerListener() |             startPlayerListener() | ||||||
|  |  | ||||||
|             // ^ will call listener.onPlayerConnected() down the line if there is an active player |             // ^ will call listener.onPlayerConnected() down the line if there is an active player | ||||||
|  |  | ||||||
|             // notify the main activity that binding the service has completed, so that it can |             // notify the main activity that binding the service has completed, so that it can | ||||||
| @@ -305,9 +298,8 @@ object PlayerHolder { | |||||||
|      * or stopping. This is necessary since the service outlives the player e.g. to answer Android |      * or stopping. This is necessary since the service outlives the player e.g. to answer Android | ||||||
|      * Auto media browser queries. |      * Auto media browser queries. | ||||||
|      */ |      */ | ||||||
|     private val playerStateListener = Consumer { player: Player? -> |     private val playerStateListener: (Player?) -> Unit = { player: Player? -> | ||||||
|         val l = listener |         listener?.let { l -> | ||||||
|         if (l != null) { |  | ||||||
|             if (player == null) { |             if (player == null) { | ||||||
|                 // player.fragmentListener=null is already done by player.stopActivityBinding(), |                 // player.fragmentListener=null is already done by player.stopActivityBinding(), | ||||||
|                 // which is called by player.destroy(), which is in turn called by PlayerService |                 // which is called by player.destroy(), which is in turn called by PlayerService | ||||||
|   | |||||||
| @@ -36,7 +36,6 @@ import org.schabi.newpipe.local.playlist.RemotePlaylistManager | |||||||
| import org.schabi.newpipe.util.ExtractorHelper | import org.schabi.newpipe.util.ExtractorHelper | ||||||
| import org.schabi.newpipe.util.ServiceHelper | import org.schabi.newpipe.util.ServiceHelper | ||||||
| import org.schabi.newpipe.util.image.ImageStrategy | import org.schabi.newpipe.util.image.ImageStrategy | ||||||
| import java.util.function.Consumer |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * This class is used to cleanly separate the Service implementation (in |  * This class is used to cleanly separate the Service implementation (in | ||||||
| @@ -46,16 +45,14 @@ import java.util.function.Consumer | |||||||
|  */ |  */ | ||||||
| class MediaBrowserImpl( | class MediaBrowserImpl( | ||||||
|     private val context: Context, |     private val context: Context, | ||||||
|     notifyChildrenChanged: Consumer<String>, // parentId |     notifyChildrenChanged: (parentId: String) -> Unit, | ||||||
| ) { | ) { | ||||||
|     private val database = NewPipeDatabase.getInstance(context) |     private val database = NewPipeDatabase.getInstance(context) | ||||||
|     private var disposables = CompositeDisposable() |     private var disposables = CompositeDisposable() | ||||||
|  |  | ||||||
|     init { |     init { | ||||||
|         // this will listen to changes in the bookmarks until this MediaBrowserImpl is dispose()d |         // this will listen to changes in the bookmarks until this MediaBrowserImpl is dispose()d | ||||||
|         disposables.add( |         disposables.add(getMergedPlaylists().subscribe { notifyChildrenChanged(ID_BOOKMARKS) }) | ||||||
|             getMergedPlaylists().subscribe { notifyChildrenChanged.accept(ID_BOOKMARKS) } |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //region Cleanup |     //region Cleanup | ||||||
| @@ -204,6 +201,7 @@ class MediaBrowserImpl( | |||||||
|         val builder = MediaDescriptionCompat.Builder() |         val builder = MediaDescriptionCompat.Builder() | ||||||
|         builder.setMediaId(createMediaIdForInfoItem(item)) |         builder.setMediaId(createMediaIdForInfoItem(item)) | ||||||
|             .setTitle(item.name) |             .setTitle(item.name) | ||||||
|  |             .setIconUri(ImageStrategy.choosePreferredImage(item.thumbnails)?.toUri()) | ||||||
|  |  | ||||||
|         when (item.infoType) { |         when (item.infoType) { | ||||||
|             InfoType.STREAM -> builder.setSubtitle((item as StreamInfoItem).uploaderName) |             InfoType.STREAM -> builder.setSubtitle((item as StreamInfoItem).uploaderName) | ||||||
| @@ -212,10 +210,6 @@ class MediaBrowserImpl( | |||||||
|             else -> return null |             else -> return null | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         ImageStrategy.choosePreferredImage(item.thumbnails)?.let { |  | ||||||
|             builder.setIconUri(imageUriOrNullIfDisabled(it)) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return MediaBrowserCompat.MediaItem( |         return MediaBrowserCompat.MediaItem( | ||||||
|             builder.build(), |             builder.build(), | ||||||
|             MediaBrowserCompat.MediaItem.FLAG_PLAYABLE |             MediaBrowserCompat.MediaItem.FLAG_PLAYABLE | ||||||
| @@ -276,10 +270,7 @@ class MediaBrowserImpl( | |||||||
|         builder.setMediaId(createMediaIdForPlaylistIndex(true, playlistId, index)) |         builder.setMediaId(createMediaIdForPlaylistIndex(true, playlistId, index)) | ||||||
|             .setTitle(item.name) |             .setTitle(item.name) | ||||||
|             .setSubtitle(item.uploaderName) |             .setSubtitle(item.uploaderName) | ||||||
|  |             .setIconUri(ImageStrategy.choosePreferredImage(item.thumbnails)?.toUri()) | ||||||
|         ImageStrategy.choosePreferredImage(item.thumbnails)?.let { |  | ||||||
|             builder.setIconUri(imageUriOrNullIfDisabled(it)) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return MediaBrowserCompat.MediaItem( |         return MediaBrowserCompat.MediaItem( | ||||||
|             builder.build(), |             builder.build(), | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| package org.schabi.newpipe.player.ui | package org.schabi.newpipe.player.ui | ||||||
|  |  | ||||||
| import org.schabi.newpipe.util.GuardedByMutex | import org.schabi.newpipe.util.GuardedByMutex | ||||||
|  | import kotlin.reflect.KClass | ||||||
|  | import kotlin.reflect.safeCast | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Creates a [PlayerUiList] starting with the provided player uis. The provided player uis |  * Creates a [PlayerUiList] starting with the provided player uis. The provided player uis | ||||||
| @@ -84,20 +86,20 @@ class PlayerUiList(vararg initialPlayerUis: PlayerUi) { | |||||||
|      * @param T the class type parameter |      * @param T the class type parameter | ||||||
|      * @return the first player UI of the required type found in the list, or null |      * @return the first player UI of the required type found in the list, or null | ||||||
|      </T> */ |      </T> */ | ||||||
|     fun <T : PlayerUi> get(playerUiType: Class<T>): T? = |     fun <T : PlayerUi> get(playerUiType: KClass<T>): T? = | ||||||
|         playerUis.runWithLockSync { |         playerUis.runWithLockSync { | ||||||
|             for (ui in lockData) { |             for (ui in lockData) { | ||||||
|                 if (playerUiType.isInstance(ui)) { |                 if (playerUiType.isInstance(ui)) { | ||||||
|                     when (val r = playerUiType.cast(ui)) { |  | ||||||
|                     // try all UIs before returning null |                     // try all UIs before returning null | ||||||
|                         null -> continue |                     playerUiType.safeCast(ui)?.let { return@runWithLockSync it } | ||||||
|                         else -> return@runWithLockSync r |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return@runWithLockSync null |             return@runWithLockSync null | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     fun <T : PlayerUi> get(playerUiType: Class<T>): T? = | ||||||
|  |         get(playerUiType.kotlin) | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Calls the provided consumer on all player UIs in the list, in order of addition. |      * Calls the provided consumer on all player UIs in the list, in order of addition. | ||||||
|      * @param consumer the consumer to call with player UIs |      * @param consumer the consumer to call with player UIs | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox