Skip to content

Commit

Permalink
Improve JS injection method (#439)
Browse files Browse the repository at this point in the history
Co-authored-by: Niels van Velzen <[email protected]>
Co-authored-by: Maxr1998 <[email protected]>
  • Loading branch information
3 people authored Jun 19, 2021
1 parent 373d196 commit 249bde9
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 55 deletions.
15 changes: 15 additions & 0 deletions app/src/main/assets/native/injectionScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(() => {
const scripts = [
'/native/nativeshell.js',
'/native/EventEmitter.js',
document.currentScript.src.concat('?deferred=true&ts=', Date.now())
];
for (const script of scripts) {
const scriptElement = document.createElement('script');
scriptElement.src = script;
scriptElement.charset = 'utf-8';
scriptElement.setAttribute('defer', '');
document.body.appendChild(scriptElement);
}
document.currentScript.remove();
})();
26 changes: 11 additions & 15 deletions app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.fragment.app.add
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.webkit.WebResourceErrorCompat
import androidx.webkit.WebViewAssetLoader.AssetsPathHandler
import androidx.webkit.WebViewClientCompat
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
Expand All @@ -43,14 +44,12 @@ import org.jellyfin.mobile.model.sql.entity.ServerEntity
import org.jellyfin.mobile.player.PlayerFragment
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
Expand All @@ -61,7 +60,7 @@ import org.json.JSONObject
import org.koin.android.ext.android.inject
import timber.log.Timber
import java.io.Reader
import java.util.*
import java.util.Locale
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
Expand All @@ -70,6 +69,7 @@ class WebViewFragment : Fragment(), NativePlayerHost {
private val appPreferences: AppPreferences by inject()
private val apiController: ApiController by inject()
private val webappFunctionChannel: WebappFunctionChannel by inject()
private lateinit var assetsPathHandler: AssetsPathHandler
private lateinit var externalPlayer: ExternalPlayer

lateinit var server: ServerEntity
Expand All @@ -85,6 +85,7 @@ class WebViewFragment : Fragment(), NativePlayerHost {
super.onCreate(savedInstanceState)
server = requireNotNull(requireArguments().getParcelable(FRAGMENT_WEB_VIEW_EXTRA_SERVER)) { "Server entity has not been supplied!" }

assetsPathHandler = AssetsPathHandler(requireContext())
externalPlayer = ExternalPlayer(requireContext(), this, requireActivity().activityResultRegistry)

requireActivity().onBackPressedDispatcher.addCallback(this) {
Expand Down Expand Up @@ -157,19 +158,14 @@ class WebViewFragment : Fragment(), NativePlayerHost {
val url = request.url
val path = url.path?.lowercase(Locale.ROOT) ?: return null
return when {
path.endsWith(Constants.WEB_CONFIG_PATH) -> {
runOnUiThread {
webView.evaluateJavascript(JS_INJECTION_CODE) {
onConnectedToWebapp()
}
}
null // continue loading normally
}
path.contains("native") -> webView.context.loadAsset("native/${url.lastPathSegment}")
path.endsWith(Constants.CAST_SDK_PATH) -> {
// Load the chrome.cast.js library instead
webView.context.loadAsset("native/chrome.cast.js")
path.matches(Constants.MAIN_BUNDLE_PATH_REGEX) && "deferred" !in url.query.orEmpty() -> {
onConnectedToWebapp()
assetsPathHandler.handle("native/injectionScript.js")
}
// Load injected scripts from application assets
path.contains("/native/") -> assetsPathHandler.handle("native/${url.lastPathSegment}")
// Load the chrome.cast.js library instead
path.endsWith(Constants.CAST_SDK_PATH) -> assetsPathHandler.handle("native/chrome.cast.js")
path.endsWith(Constants.SESSION_CAPABILITIES_PATH) -> {
lifecycleScope.launch {
val credentials = suspendCoroutine<JSONObject> { continuation ->
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/org/jellyfin/mobile/utils/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object Constants {

// Webapp constants
const val MINIMUM_WEB_VIEW_VERSION = 80
const val WEB_CONFIG_PATH = "config.json"
val MAIN_BUNDLE_PATH_REGEX = Regex(""".*/main\.[^/\s]+\.bundle\.js""")
const val CAST_SDK_PATH = "cast_sender.js"
const val SESSION_CAPABILITIES_PATH = "sessions/capabilities/full"

Expand Down
39 changes: 0 additions & 39 deletions app/src/main/java/org/jellyfin/mobile/utils/WebAppUtils.kt

This file was deleted.

0 comments on commit 249bde9

Please sign in to comment.