Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix or suppress detekt warnings and code style issues #412

Merged
merged 2 commits into from
Jun 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/src/main/java/org/jellyfin/mobile/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ class MainActivity : AppCompatActivity() {
serviceBinder = binder as? RemotePlayerService.ServiceBinder
}

override fun onServiceDisconnected(componentName: ComponentName) {}
override fun onServiceDisconnected(componentName: ComponentName) {
serviceBinder = null
}
}

private val orientationListener: OrientationEventListener by lazy { SmartOrientationListener(this) }
Expand Down
35 changes: 18 additions & 17 deletions app/src/main/java/org/jellyfin/mobile/api/DeviceProfileBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -107,30 +107,31 @@ class DeviceProfileBuilder {
ignoreTranscodeByteRangeRequests = false,
)

@Suppress("NestedBlockDepth")
private fun getAndroidCodecs(): Pair<Map<String, DeviceCodec.Video>, Map<String, DeviceCodec.Audio>> {
val videoCodecs: MutableMap<String, DeviceCodec.Video> = HashMap()
val audioCodecs: MutableMap<String, DeviceCodec.Audio> = HashMap()

val androidCodecs = MediaCodecList(MediaCodecList.REGULAR_CODECS)
for (codecInfo in androidCodecs.codecInfos) {
if (!codecInfo.isEncoder) {
for (mimeType in codecInfo.supportedTypes) {
val codec = DeviceCodec.from(codecInfo.getCapabilitiesForType(mimeType)) ?: continue
val name = codec.name
when (codec) {
is DeviceCodec.Video -> {
if (videoCodecs.containsKey(name)) {
videoCodecs[name] = videoCodecs[name]!!.mergeCodec(codec)
} else {
videoCodecs[name] = codec
}
if (codecInfo.isEncoder) continue

for (mimeType in codecInfo.supportedTypes) {
val codec = DeviceCodec.from(codecInfo.getCapabilitiesForType(mimeType)) ?: continue
val name = codec.name
when (codec) {
is DeviceCodec.Video -> {
if (videoCodecs.containsKey(name)) {
videoCodecs[name] = videoCodecs[name]!!.mergeCodec(codec)
} else {
videoCodecs[name] = codec
}
is DeviceCodec.Audio -> {
if (audioCodecs.containsKey(mimeType)) {
audioCodecs[name] = audioCodecs[name]!!.mergeCodec(codec)
} else {
audioCodecs[name] = codec
}
}
is DeviceCodec.Audio -> {
if (audioCodecs.containsKey(mimeType)) {
audioCodecs[name] = audioCodecs[name]!!.mergeCodec(codec)
} else {
audioCodecs[name] = codec
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jellyfin.mobile.bridge

import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
Expand Down Expand Up @@ -102,7 +103,7 @@ class NativeInterface(private val fragment: WebViewFragment) : KoinComponent {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri))
context.startActivity(intent)
true
} catch (e: Exception) {
} catch (e: ActivityNotFoundException) {
Timber.e("openIntent: %s", e.message)
false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class ConnectFragment : Fragment() {

// Show keyboard
serverSetupLayout.doOnNextLayout {
@Suppress("MagicNumber")
hostInput.postDelayed(25) {
hostInput.requestFocus()

Expand Down
111 changes: 66 additions & 45 deletions app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.*
import android.webkit.ConsoleMessage
import android.webkit.WebChromeClient
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.widget.Toast
import androidx.activity.addCallback
import androidx.appcompat.app.AlertDialog
Expand All @@ -37,8 +41,20 @@ import org.jellyfin.mobile.controller.ApiController
import org.jellyfin.mobile.databinding.FragmentWebviewBinding
import org.jellyfin.mobile.model.sql.entity.ServerEntity
import org.jellyfin.mobile.player.PlayerFragment
import org.jellyfin.mobile.utils.*
import org.jellyfin.mobile.utils.Constants
import org.jellyfin.mobile.utils.Constants.FRAGMENT_WEB_VIEW_EXTRA_SERVER
import org.jellyfin.mobile.utils.JS_INJECTION_CODE
import org.jellyfin.mobile.utils.addFragment
import org.jellyfin.mobile.utils.applyDefault
import org.jellyfin.mobile.utils.applyWindowInsetsAsMargins
import org.jellyfin.mobile.utils.dip
import org.jellyfin.mobile.utils.initLocale
import org.jellyfin.mobile.utils.isOutdated
import org.jellyfin.mobile.utils.loadAsset
import org.jellyfin.mobile.utils.replaceFragment
import org.jellyfin.mobile.utils.requestNoBatteryOptimizations
import org.jellyfin.mobile.utils.runOnUiThread
import org.jellyfin.mobile.utils.unescapeJson
import org.jellyfin.mobile.webapp.WebappFunctionChannel
import org.json.JSONException
import org.json.JSONObject
Expand Down Expand Up @@ -92,6 +108,7 @@ class WebViewFragment : Fragment(), NativePlayerHost {

// Setup exclusion rects for gestures
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@Suppress("MagicNumber")
webView.doOnNextLayout { webView ->
// Maximum allowed exclusion rect height is 200dp,
// offsetting 100dp from the center in both directions
Expand Down Expand Up @@ -131,49 +148,7 @@ class WebViewFragment : Fragment(), NativePlayerHost {

private fun WebView.initialize() {
if (!appPreferences.ignoreWebViewChecks && isOutdated()) { // Check WebView version
AlertDialog.Builder(requireContext()).apply {
setTitle(R.string.dialog_web_view_outdated)
setMessage(R.string.dialog_web_view_outdated_message)
setCancelable(false)

val webViewPackage = WebViewCompat.getCurrentWebViewPackage(context)
if (webViewPackage != null) {
val marketUri = Uri.Builder().apply {
scheme("market")
authority("details")
appendQueryParameter("id", webViewPackage.packageName)
}.build()
val referrerUri = Uri.Builder().apply {
scheme("android-app")
authority(context.packageName)
}.build()

val marketIntent = Intent(Intent.ACTION_VIEW).apply {
data = marketUri
putExtra(Intent.EXTRA_REFERRER, referrerUri)
}

// Only show button if the intent can be resolved
if (marketIntent.resolveActivity(context.packageManager) != null) {
setNegativeButton(R.string.dialog_button_check_for_updates) { _, _ ->
startActivity(marketIntent)
requireActivity().finishAfterTransition()
}
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setPositiveButton(R.string.dialog_button_open_settings) { _, _ ->
startActivity(Intent(Settings.ACTION_WEBVIEW_SETTINGS))
Toast.makeText(context, R.string.toast_reopen_after_change, Toast.LENGTH_LONG).show()
requireActivity().finishAfterTransition()
}
}
setNeutralButton(R.string.dialog_button_ignore) { _, _ ->
appPreferences.ignoreWebViewChecks = true
// Re-initialize
initialize()
}
}.show()
showOutdatedWebViewDialog()
return
}

Expand Down Expand Up @@ -263,6 +238,52 @@ class WebViewFragment : Fragment(), NativePlayerHost {
loadUrl(server.hostname)
}

private fun showOutdatedWebViewDialog() {
AlertDialog.Builder(requireContext()).apply {
setTitle(R.string.dialog_web_view_outdated)
setMessage(R.string.dialog_web_view_outdated_message)
setCancelable(false)

val webViewPackage = WebViewCompat.getCurrentWebViewPackage(context)
if (webViewPackage != null) {
val marketUri = Uri.Builder().apply {
scheme("market")
authority("details")
appendQueryParameter("id", webViewPackage.packageName)
}.build()
val referrerUri = Uri.Builder().apply {
scheme("android-app")
authority(context.packageName)
}.build()

val marketIntent = Intent(Intent.ACTION_VIEW).apply {
data = marketUri
putExtra(Intent.EXTRA_REFERRER, referrerUri)
}

// Only show button if the intent can be resolved
if (marketIntent.resolveActivity(context.packageManager) != null) {
setNegativeButton(R.string.dialog_button_check_for_updates) { _, _ ->
startActivity(marketIntent)
requireActivity().finishAfterTransition()
}
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setPositiveButton(R.string.dialog_button_open_settings) { _, _ ->
startActivity(Intent(Settings.ACTION_WEBVIEW_SETTINGS))
Toast.makeText(context, R.string.toast_reopen_after_change, Toast.LENGTH_LONG).show()
requireActivity().finishAfterTransition()
}
}
setNeutralButton(R.string.dialog_button_ignore) { _, _ ->
appPreferences.ignoreWebViewChecks = true
// Re-initialize
webView.initialize()
nielsvanvelzen marked this conversation as resolved.
Show resolved Hide resolved
}
}.show()
}

fun onConnectedToWebapp() {
connected = true
(activity as? MainActivity)?.requestNoBatteryOptimizations()
Expand Down
25 changes: 17 additions & 8 deletions app/src/main/java/org/jellyfin/mobile/media/MediaService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,28 @@ import androidx.mediarouter.media.MediaControlIntent
import androidx.mediarouter.media.MediaRouteSelector
import androidx.mediarouter.media.MediaRouter
import androidx.mediarouter.media.MediaRouterParams
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.ControlDispatcher
import com.google.android.exoplayer2.ExoPlaybackException
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.audio.AudioAttributes
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import org.jellyfin.mobile.R
import org.jellyfin.mobile.cast.CastPlayerProvider
import org.jellyfin.mobile.cast.ICastPlayerProvider
import org.jellyfin.mobile.controller.ApiController
import org.jellyfin.mobile.media.car.LibraryBrowser
import org.jellyfin.mobile.media.car.LibraryPage
import org.jellyfin.mobile.utils.toast
import org.jellyfin.sdk.api.client.exception.ApiClientException
import org.koin.android.ext.android.inject
import timber.log.Timber
import com.google.android.exoplayer2.MediaItem as ExoPlayerMediaItem
Expand Down Expand Up @@ -164,8 +173,8 @@ class MediaService : MediaBrowserServiceCompat() {

val items = try {
if (apiController.currentUser != null) libraryBrowser.loadLibrary(parentId) else null
} catch (t: Throwable) {
Timber.e(t)
} catch (e: ApiClientException) {
Timber.e(e)
null
}
result.sendResult(items ?: emptyList())
Expand Down Expand Up @@ -279,8 +288,8 @@ class MediaService : MediaBrowserServiceCompat() {
serviceScope.launch {
val recents = try {
libraryBrowser.getDefaultRecents()
} catch (t: Throwable) {
Timber.e(t)
} catch (e: ApiClientException) {
Timber.e(e)
null
}
if (recents != null) {
Expand Down Expand Up @@ -309,8 +318,8 @@ class MediaService : MediaBrowserServiceCompat() {
} else serviceScope.launch {
val results = try {
libraryBrowser.getSearchResults(query, extras)
} catch (t: Throwable) {
Timber.e(t)
} catch (e: ApiClientException) {
Timber.e(e)
null
}
if (results != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.jellyfin.mobile.media.setMediaId
import org.jellyfin.mobile.media.setMediaUri
import org.jellyfin.mobile.media.setTitle
import org.jellyfin.mobile.media.setTrackNumber
import org.jellyfin.sdk.api.client.exception.ApiClientException
import org.jellyfin.sdk.api.operations.GenresApi
import org.jellyfin.sdk.api.operations.ImageApi
import org.jellyfin.sdk.api.operations.ItemsApi
Expand All @@ -41,6 +42,7 @@ import org.jellyfin.sdk.model.serializer.toUUIDOrNull
import timber.log.Timber
import java.util.*

@Suppress("TooManyFunctions")
class LibraryBrowser(
private val context: Context,
private val apiController: ApiController,
Expand Down Expand Up @@ -73,6 +75,7 @@ class LibraryBrowser(

val split = parentId.split('|')

@Suppress("MagicNumber")
if (split.size !in 1..3)
return null

Expand Down Expand Up @@ -110,6 +113,7 @@ class LibraryBrowser(

suspend fun buildPlayQueue(mediaId: String): Pair<List<MediaMetadataCompat>, Int>? {
val split = mediaId.split('|')
@Suppress("MagicNumber")
if (split.size != 3)
return null

Expand All @@ -123,7 +127,8 @@ class LibraryBrowser(
LibraryPage.PLAYLIST -> getPlaylist(collectionId)
else -> null
}
} catch (t: Throwable) {
} catch (e: ApiClientException) {
Timber.e(e)
null
} ?: return null

Expand Down
18 changes: 10 additions & 8 deletions app/src/main/java/org/jellyfin/mobile/player/CodecHelpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.media.MediaCodecInfo.CodecProfileLevel
import android.media.MediaFormat
import com.google.android.exoplayer2.util.MimeTypes

@Suppress("TooManyFunctions")
object CodecHelpers {
fun getVideoCodec(mimeType: String): String? = when (mimeType) {
MediaFormat.MIMETYPE_VIDEO_MPEG2 -> "mpeg2video"
Expand Down Expand Up @@ -132,15 +133,16 @@ object CodecHelpers {
else -> null
}?.let { Integer.valueOf(it) }

// FIXME: server only handles numeric levels
private fun getMPEG2VideoLevel(@Suppress("UNUSED_PARAMETER") level: Int): String? = null /*when (level) {
CodecProfileLevel.MPEG2LevelLL -> "ll"
CodecProfileLevel.MPEG2LevelML -> "ml"
CodecProfileLevel.MPEG2LevelH14 -> "h14"
CodecProfileLevel.MPEG2LevelHL -> "hl"
CodecProfileLevel.MPEG2LevelHP -> "hp"
/**
* Level numbers taken from FFmpeg `libavcodec/mpeg12enc.c`.
*/
private fun getMPEG2VideoLevel(level: Int): String? = when (level) {
CodecProfileLevel.MPEG2LevelLL -> "10"
CodecProfileLevel.MPEG2LevelML -> "8"
CodecProfileLevel.MPEG2LevelH14 -> "6"
CodecProfileLevel.MPEG2LevelHL -> "4"
else -> null
}*/
}

private fun getH263Level(level: Int): String? = when (level) {
CodecProfileLevel.H263Level10 -> "10"
Expand Down
Loading