aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/web
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-12-31 02:44:46 -0500
committerGitHub <noreply@github.com>2017-12-31 02:44:46 -0500
commit725d6a99a07f91f940a07e6b49dd6224a6aa32d1 (patch)
tree4e0b1b3b9ffe9b5aef3c8d0f154ea9ab1058fd5e /app/src/main/kotlin/com/pitchedapps/frost/web
parent3076d9a97c203497aec1415d8ac6037d10eebb46 (diff)
downloadfrost-725d6a99a07f91f940a07e6b49dd6224a6aa32d1.tar.gz
frost-725d6a99a07f91f940a07e6b49dd6224a6aa32d1.tar.bz2
frost-725d6a99a07f91f940a07e6b49dd6224a6aa32d1.zip
Enhancement/proguard (#589)
* Add error log * Rewrite logger
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/web')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt30
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt15
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt49
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/HeadlessHtmlExtractor.kt91
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt8
7 files changed, 30 insertions, 169 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
index 960fe4c2..8c016e5c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
@@ -20,30 +20,6 @@ import io.reactivex.subjects.Subject
*/
/**
- * Fully quiet client that disables any prompts relating to the UI
- * (as nothing is attached)
- */
-class HeadlessChromeClient : WebChromeClient() {
-
- override fun onConsoleMessage(consoleMessage: ConsoleMessage) = true
-
- override fun onJsAlert(view: WebView, url: String?, message: String?, result: JsResult): Boolean {
- result.cancel()
- return true
- }
-
- override fun onJsConfirm(view: WebView, url: String?, message: String?, result: JsResult): Boolean {
- result.cancel()
- return true
- }
-
- override fun onJsPrompt(view: WebView, url: String?, message: String?, defaultValue: String?, result: JsPromptResult): Boolean {
- result.cancel()
- return true
- }
-}
-
-/**
* The default chrome client
*/
class FrostChromeClient(web: FrostWebView) : WebChromeClient() {
@@ -55,7 +31,7 @@ class FrostChromeClient(web: FrostWebView) : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
if (consoleBlacklist.any { consoleMessage.message().contains(it) }) return true
- L.v("Chrome Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
+ L.v { "Chrome Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}" }
return true
}
@@ -76,9 +52,9 @@ class FrostChromeClient(web: FrostWebView) : WebChromeClient() {
}
override fun onGeolocationPermissionsShowPrompt(origin: String, callback: GeolocationPermissions.Callback) {
- L.i("Requesting geolocation")
+ L.i { "Requesting geolocation" }
context.kauRequestPermissions(PERMISSION_ACCESS_FINE_LOCATION) { granted, _ ->
- L.i("Geolocation response received; ${if (granted) "granted" else "denied"}")
+ L.i { "Geolocation response received; ${if (granted) "granted" else "denied"}" }
callback(origin, granted, true)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
index b567801b..9264ea52 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -33,13 +33,13 @@ class FrostJSI(val web: FrostWebView) {
if (url != null)
web.post {
(context as? VideoViewHolder)?.showVideo(url, isGif)
- ?: L.d("Could not load video; contract not implemented")
+ ?: L.d { "Could not load video; contract not implemented" }
}
}
@JavascriptInterface
fun reloadBaseUrl(animate: Boolean) {
- L.d("FrostJSI reload")
+ L.d { "FrostJSI reload" }
web.post {
web.stopLoading()
web.reloadBase(animate)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
index f7f5666d..454e2a4b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
@@ -47,7 +47,7 @@ fun WebView.shouldFrostInterceptRequest(request: WebResourceRequest): WebResourc
if (whitelistHost.contains(host)) return null
if (!adWhitelistHost.contains(host) && FrostPglAdBlock.isAdHost(host)) return blankResource
// if (!shouldLoadImages && !Prefs.loadMediaOnMeteredNetwork && request.isMedia) return blankResource
- L.v("Intercept Request", "$host $url")
+ L.v { "Intercept Request: $host $url" }
return null
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
index 253d4801..8eec3402 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
@@ -29,34 +29,35 @@ import org.jetbrains.anko.runOnUiThread
* as we have no need of sending a new intent to the same activity
*/
fun FrostWebView.requestWebOverlay(url: String): Boolean {
+ L.v { "Request web overlay: $url" }
val context = context // finalize reference
if (url.isVideoUrl && context is VideoViewHolder) {
- L.i("Found video", url)
+ L.d { "Found video" }
context.runOnUiThread { context.showVideo(url) }
return true
}
if (!url.isIndependent) {
- L.i("Forbid overlay switch", url)
+ L.d { "Forbid overlay switch" }
return false
}
if (!Prefs.overlayEnabled) return false
if (context is WebOverlayActivityBase) {
- L.v("Check web request from overlay", url)
+ L.v { "Check web request from overlay" }
//already overlay; manage user agent
if (userAgentString != USER_AGENT_BASIC && url.formattedFbUrl.shouldUseBasicAgent) {
- L.i("Switch to basic agent overlay")
+ L.i { "Switch to basic agent overlay" }
context.launchWebOverlay(url, WebOverlayBasicActivity::class.java)
return true
}
if (context is WebOverlayBasicActivity && !url.formattedFbUrl.shouldUseBasicAgent) {
- L.i("Switch from basic agent")
+ L.i { "Switch from basic agent" }
context.launchWebOverlay(url)
return true
}
- L.i("return false switch")
+ L.i { "return false switch" }
return false
}
- L.v("Request web overlay passed", url)
+ L.v { "Request web overlay passed" }
context.launchWebOverlay(url)
return true
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
index 71c71b66..a826066d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
@@ -44,10 +44,12 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
private val refresh: Subject<Boolean> = web.parent.refreshObservable
private val isMain = web.parent.baseEnum != null
+ protected inline fun v(crossinline message: () -> Any?) = L.v { "web client: ${message()}" }
+
override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
if (url == null) return
- L.d("FWV Loading", url)
+ v { "loading $url" }
refresh.onNext(true)
}
@@ -87,7 +89,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
override fun onPageFinished(view: WebView, url: String?) {
url ?: return
- L.d("Page finished", url)
+ v { "finished $url" }
if (!url.isFacebookUrl) {
refresh.onNext(false)
return
@@ -102,7 +104,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
}
internal fun injectAndFinish() {
- L.d("Page finished reveal")
+ v { "page finished reveal" }
refresh.onNext(false)
injectBackgroundColor()
web.jsInject(
@@ -117,11 +119,11 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
}
open fun handleHtml(html: String?) {
- L.d("Handle Html")
+ L.d { "Handle Html" }
}
open fun emit(flag: Int) {
- L.d("Emit $flag")
+ L.d { "Emit $flag" }
}
/**
@@ -130,21 +132,21 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
* returns false if we are already in an overlaying activity
*/
private fun launchRequest(request: WebResourceRequest): Boolean {
- L.d("Launching Url", request.url?.toString() ?: "null")
+ v { "Launching url: ${request.url}" }
return web.requestWebOverlay(request.url.toString())
}
private fun launchImage(url: String, text: String? = null): Boolean {
- L.d("Launching Image", url)
+ v { "Launching image: $url" }
web.context.launchImageActivity(url, text)
if (web.canGoBack()) web.goBack()
return true
}
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
- L.i("Url Loading", request.url?.toString())
+ v { "Url loading: ${request.url}" }
val path = request.url?.path ?: return super.shouldOverrideUrlLoading(view, request)
- L.v("Url Loading Path", path)
+ v { "Url path $path" }
val url = request.url.toString()
if (url.isExplicitIntent) {
view.context.resolveActivityForUri(request.url)
@@ -184,34 +186,7 @@ class FrostWebViewClientMenu(web: FrostWebView) : FrostWebViewClient(web) {
}
override fun onPageFinishedActions(url: String) {
- L.d("Should inject ${url.shouldInjectMenu}")
+ v { "Should inject ${url.shouldInjectMenu}" }
if (!url.shouldInjectMenu) injectAndFinish()
}
-}
-
-/**
- * Headless client that injects content after a page load
- * The JSI is meant to handle everything else
- */
-class HeadlessWebViewClient(val tag: String, val postInjection: InjectorContract) : BaseWebViewClient() {
-
- override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
- super.onPageStarted(view, url, favicon)
- if (url == null) return
- L.d("Headless Page $tag Started", url)
- }
-
- override fun onPageFinished(view: WebView, url: String?) {
- super.onPageFinished(view, url)
- if (url == null) return
- L.d("Headless Page $tag Finished", url)
- postInjection.inject(view)
- }
-
- /**
- * In addition to general filtration, we will also strip away css and images
- */
- override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
- = super.shouldInterceptRequest(view, request).filterCss(request).filterImage(request)
-
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/HeadlessHtmlExtractor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/HeadlessHtmlExtractor.kt
deleted file mode 100644
index 2c7735a4..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/HeadlessHtmlExtractor.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.pitchedapps.frost.web
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.webkit.JavascriptInterface
-import android.webkit.WebView
-import ca.allanwang.kau.utils.gone
-import com.pitchedapps.frost.R
-import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
-import com.pitchedapps.frost.injectors.InjectorContract
-import com.pitchedapps.frost.utils.L
-import io.reactivex.Single
-import io.reactivex.SingleEmitter
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.schedulers.Schedulers
-import org.jetbrains.anko.runOnUiThread
-import java.util.concurrent.TimeUnit
-
-/**
- * Created by Allan Wang on 2017-08-12.
- *
- * Launches a headless html request and returns a result pair
- * When successful, the pair will contain the html content and -1
- * When unsuccessful, the pair will contain an empty string and a StringRes for the given error
- *
- * All errors are rerouted to success calls, so no exceptions should occur.
- * The headless extractor will also destroy itself on cancellation or when the request is finished
- */
-fun Context.launchHeadlessHtmlExtractor(url: String, injector: InjectorContract, action: (Single<Pair<String, Int>>) -> Unit) {
- val single = Single.create<Pair<String, Int>> { e: SingleEmitter<Pair<String, Int>> ->
- val extractor = HeadlessHtmlExtractor(this, url, injector, e)
- extractor.resumeTimers()
- e.setCancellable {
- runOnUiThread {
- extractor.pauseTimers()
- extractor.destroy()
- }
- e.onSuccess("" to R.string.html_extraction_cancelled)
- }
- }.subscribeOn(AndroidSchedulers.mainThread())
- .timeout(20, TimeUnit.SECONDS, Schedulers.io(), { it.onSuccess("" to R.string.html_extraction_timeout) })
- .onErrorReturn { "" to R.string.html_extraction_error }
- action(single)
-}
-
-/**
- * Given a link and some javascript, will load the link and load the JS on completion
- * The JS is expected to call [HeadlessHtmlExtractor.HtmlJSI.handleHtml], which will be sent
- * to the [emitter]
- */
-@SuppressLint("ViewConstructor")
-private class HeadlessHtmlExtractor(
- context: Context, url: String, val injector: InjectorContract, val emitter: SingleEmitter<Pair<String, Int>>
-) : WebView(context) {
-
- val startTime = System.currentTimeMillis()
-
- init {
- L.v("Created HeadlessHtmlExtractor for $url")
- gone()
- setupWebview(url)
- }
-
- @SuppressLint("SetJavaScriptEnabled")
- private fun setupWebview(url: String) {
- settings.javaScriptEnabled = true
- settings.userAgentString = USER_AGENT_BASIC
- webViewClient = HeadlessWebViewClient(url, injector) // basic client that loads our JS once the page has loaded
- webChromeClient = HeadlessChromeClient()
- addJavascriptInterface(HtmlJSI(), "Frost")
- loadUrl(url)
- }
-
- inner class HtmlJSI {
- @JavascriptInterface
- fun handleHtml(html: String?) {
- val time = System.currentTimeMillis() - startTime
- emitter.onSuccess((html ?: "") to -1)
- post {
- L.d("HeadlessHtmlExtractor fetched $url in $time ms")
- destroy()
- }
- }
- }
-
- override fun destroy() {
- pauseTimers()
- super.destroy()
- L.d("HeadlessHtmlExtractor destroyed")
- }
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
index 9855040d..a2f341ef 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -46,7 +46,7 @@ class LoginWebView @JvmOverloads constructor(
fun loadLogin(progressCallback: (Int) -> Unit, loginCallback: (CookieModel) -> Unit) {
this.progressCallback = progressCallback
this.loginCallback = loginCallback
- L.d("Begin loading login")
+ L.d { "Begin loading login" }
loadUrl(FB_LOGIN_URL)
}
@@ -62,7 +62,7 @@ class LoginWebView @JvmOverloads constructor(
doAsync {
if (!url.isFacebookUrl) return@doAsync
val cookie = CookieManager.getInstance().getCookie(url) ?: return@doAsync
- L.d("Checking cookie for login", cookie)
+ L.d { "Checking cookie for login" }
val id = FB_USER_MATCHER.find(cookie)[1]?.toLong() ?: return@doAsync
uiThread { onFound(id, cookie) }
}
@@ -70,7 +70,7 @@ class LoginWebView @JvmOverloads constructor(
override fun onPageCommitVisible(view: WebView, url: String?) {
super.onPageCommitVisible(view, url)
- L.d("Login page commit visible")
+ L.d { "Login page commit visible" }
view.setBackgroundColor(Color.TRANSPARENT)
if (url.isFacebookUrl)
view.jsInject(CssHider.HEADER,
@@ -88,7 +88,7 @@ class LoginWebView @JvmOverloads constructor(
inner class LoginChromeClient : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
- L.d("Login Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
+ L.v { "Login Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}" }
return true
}