generated from KyuubiRan/EzXHepler-template
-
Notifications
You must be signed in to change notification settings - Fork 39
/
WebView.kt
100 lines (89 loc) · 4.01 KB
/
WebView.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package org.matrix.chromext.hook
import android.app.Activity
import android.os.Build
import android.os.Handler
import java.lang.ref.WeakReference
import org.matrix.chromext.Chrome
import org.matrix.chromext.Listener
import org.matrix.chromext.script.Local
import org.matrix.chromext.script.ScriptDbManager
import org.matrix.chromext.utils.Log
import org.matrix.chromext.utils.findField
import org.matrix.chromext.utils.findMethod
import org.matrix.chromext.utils.hookAfter
import org.matrix.chromext.utils.hookBefore
import org.matrix.chromext.utils.invokeMethod
object WebViewHook : BaseHook() {
var ViewClient: Class<*>? = null
var ChromeClient: Class<*>? = null
var WebView: Class<*>? = null
val records = mutableListOf<WeakReference<Any>>()
fun evaluateJavascript(code: String?, view: Any?) {
val webView = (view ?: Chrome.getTab())
if (code != null && code.length > 0 && webView != null) {
val webSettings = webView.invokeMethod { name == "getSettings" }
if (webSettings?.invokeMethod { name == "getJavaScriptEnabled" } == true)
Handler(Chrome.getContext().mainLooper).post {
webView.invokeMethod(code, null) { name == "evaluateJavascript" }
}
}
}
override fun init() {
findMethod(ChromeClient!!, true) { name == "onConsoleMessage" && parameterCount == 1 }
// public boolean onConsoleMessage (ConsoleMessage consoleMessage)
.hookAfter {
// Don't use ConsoleMessage to specify this method since Mi Browser uses its own
// implementation
// This should be the way to communicate with the front-end of ChromeXt
val chromeClient = it.thisObject
val consoleMessage = it.args[0]
val messageLevel = consoleMessage.invokeMethod { name == "messageLevel" }
val sourceId = consoleMessage.invokeMethod { name == "sourceId" }
val lineNumber = consoleMessage.invokeMethod { name == "lineNumber" }
val message = consoleMessage.invokeMethod { name == "message" } as String
if (messageLevel.toString() == "TIP" &&
sourceId == "local://ChromeXt/init" &&
lineNumber == Local.anchorInChromeXt) {
val webView =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
records
.find {
if (Chrome.isQihoo) {
val mProvider = findField(WebView!!) { name == "mProvider" }
mProvider.get(it.get())
} else {
it.get()
}
?.invokeMethod { name == "getWebChromeClient" } == chromeClient
}
?.get()
} else Chrome.getTab()
Listener.startAction(message, webView, chromeClient)
} else {
Log.d(messageLevel.toString() + ": [${sourceId}@${lineNumber}] ${message}")
}
}
fun onUpdateUrl(url: String, view: Any?) {
if (url.startsWith("javascript") || view == null) return
Chrome.updateTab(view)
ScriptDbManager.invokeScript(url, view)
}
findMethod(WebView!!) { name == "setWebChromeClient" }
.hookAfter {
val webView = it.thisObject
records.removeAll(records.filter { it.get() == null || it.get() == webView })
if (it.args[0] != null) records.add(WeakReference(webView))
}
findMethod(WebView!!) { name == "onAttachedToWindow" }
.hookAfter { Chrome.updateTab(it.thisObject) }
findMethod(ViewClient!!, true) { name == "onPageStarted" }
// public void onPageStarted (WebView view, String url, Bitmap favicon)
.hookAfter {
if (Chrome.isQihoo && it.thisObject::class.java.declaredMethods.size > 1) return@hookAfter
onUpdateUrl(it.args[1] as String, it.args[0])
}
findMethod(Activity::class.java) { name == "onStop" }
.hookBefore { ScriptDbManager.updateScriptStorage() }
isInit = true
}
}