aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt48
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt49
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt2
14 files changed, 145 insertions, 32 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index d6d6faea..2ebdd215 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -35,7 +35,7 @@ import com.pitchedapps.frost.db.FbTabsDb
import com.pitchedapps.frost.db.FrostDatabase
import com.pitchedapps.frost.db.NotificationDb
import com.pitchedapps.frost.glide.GlideApp
-import com.pitchedapps.frost.services.scheduleNotifications
+import com.pitchedapps.frost.services.scheduleNotificationsFromPrefs
import com.pitchedapps.frost.services.setupNotificationChannels
import com.pitchedapps.frost.utils.BuildUtils
import com.pitchedapps.frost.utils.FrostPglAdBlock
@@ -96,7 +96,7 @@ class FrostApp : Application() {
setupNotificationChannels(applicationContext)
- applicationContext.scheduleNotifications(Prefs.notificationFreq)
+ scheduleNotificationsFromPrefs()
/**
* Drawer profile loading logic
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
index 05321b69..521049e7 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -83,6 +83,7 @@ import com.pitchedapps.frost.facebook.parsers.SearchParser
import com.pitchedapps.frost.facebook.profilePictureUrl
import com.pitchedapps.frost.fragments.BaseFragment
import com.pitchedapps.frost.fragments.WebFragment
+import com.pitchedapps.frost.services.scheduleNotificationsFromPrefs
import com.pitchedapps.frost.utils.ACTIVITY_SETTINGS
import com.pitchedapps.frost.utils.EXTRA_COOKIES
import com.pitchedapps.frost.utils.L
@@ -90,6 +91,7 @@ import com.pitchedapps.frost.utils.MAIN_TIMEOUT_DURATION
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.REQUEST_FAB
import com.pitchedapps.frost.utils.REQUEST_NAV
+import com.pitchedapps.frost.utils.REQUEST_NOTIFICATION
import com.pitchedapps.frost.utils.REQUEST_REFRESH
import com.pitchedapps.frost.utils.REQUEST_RESTART
import com.pitchedapps.frost.utils.REQUEST_RESTART_APPLICATION
@@ -493,6 +495,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
if (hasRequest(REQUEST_FAB)) {
fragmentChannel.offer(lastPosition)
}
+ if (hasRequest(REQUEST_NOTIFICATION)) {
+ scheduleNotificationsFromPrefs()
+ }
}
}
@@ -635,12 +640,11 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun getPageTitle(position: Int): CharSequence = getString(pages[position].titleId)
override fun getItemPosition(fragment: Any) =
- if (fragment !is BaseFragment)
- POSITION_UNCHANGED
- else if (fragment is WebFragment || fragment.valid)
- POSITION_UNCHANGED
- else
- POSITION_NONE
+ when {
+ fragment !is BaseFragment -> POSITION_UNCHANGED
+ fragment is WebFragment || fragment.valid -> POSITION_UNCHANGED
+ else -> POSITION_NONE
+ }
}
override val lowerVideoPadding: PointF
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
index f6316470..032ff31e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
@@ -29,12 +29,15 @@ const val FB_LOGIN_URL = "${FB_URL_BASE}login"
const val FB_HOME_URL = "${FB_URL_BASE}home.php"
// Default user agent
-const val USER_AGENT_MOBILE =
+private const val USER_AGENT_MOBILE_CONST =
"Mozilla/5.0 (Linux; Android 8.0.0; ONEPLUS A3000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36"
// Desktop agent, for pages like messages
-const val USER_AGENT_DESKTOP =
+private const val USER_AGENT_DESKTOP_CONST =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Safari/537.36"
+const val USER_AGENT_MOBILE = USER_AGENT_DESKTOP_CONST
+const val USER_AGENT_DESKTOP = USER_AGENT_DESKTOP_CONST
+
/**
* Animation transition delay, just to ensure that the styles
* have properly set in
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
index 55fbcd40..c580c9ed 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
@@ -67,7 +67,7 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
data: FbItem,
position: Int
): BaseFragment {
- val fragment = if (!useFallback) base() else WebFragment()
+ val fragment = if (useFallback || Prefs.webOnly) WebFragment() else base()
val d = if (data == FbItem.FEED) FeedSort(Prefs.feedSort).item else data
fragment.withArguments(
ARG_URL to d.url,
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
index 00c7bcfc..3416c420 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -17,9 +17,11 @@
package com.pitchedapps.frost.injectors
import android.webkit.WebView
+import androidx.annotation.VisibleForTesting
+import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.web.FrostWebViewClient
import org.apache.commons.text.StringEscapeUtils
-import java.util.Locale
+import kotlin.random.Random
class JsBuilder {
private val css = StringBuilder()
@@ -38,7 +40,7 @@ class JsBuilder {
}
fun single(tag: String): JsBuilder {
- this.tag = "_frost_${tag.toLowerCase(Locale.CANADA)}"
+ this.tag = TagObfuscator.obfuscateTag(tag)
return this
}
@@ -52,14 +54,19 @@ class JsBuilder {
val cssMin = css.replace(Regex("\\s*\n\\s*"), "")
append("var a=document.createElement('style');")
append("a.innerHTML='$cssMin';")
- if (tag != null) append("a.id='$tag';")
+ if (tag != null) {
+ append("a.id='$tag';")
+ }
append("document.head.appendChild(a);")
}
- if (js.isNotBlank())
+ if (js.isNotBlank()) {
append(js)
+ }
}
var content = builder.append("}()").toString()
- if (tag != null) content = singleInjector(tag, content)
+ if (tag != null) {
+ content = singleInjector(tag, content)
+ }
return content
}
@@ -102,3 +109,34 @@ class JsInjector(val function: String) : InjectorContract {
override fun inject(webView: WebView) =
webView.evaluateJavascript(function, null)
}
+
+/**
+ * Helper object to obfuscate window tags for JS injection.
+ */
+@VisibleForTesting
+internal object TagObfuscator {
+
+ fun obfuscateTag(tag: String): String {
+ val rnd = Random(tag.hashCode() + salt)
+ val obfuscated = buildString {
+ append(prefix)
+ append('_')
+ appendRandomChars(rnd, 16)
+ }
+ L.v { "TagObfuscator: Obfuscating tag '$tag' to '$obfuscated'" }
+ return obfuscated
+ }
+
+ private val salt: Long = System.currentTimeMillis()
+
+ private val prefix: String by lazy {
+ val rnd = Random(System.currentTimeMillis())
+ buildString { appendRandomChars(rnd, 8) }
+ }
+
+ private fun Appendable.appendRandomChars(random: Random, count: Int) {
+ for (i in 1..count) {
+ append('a' + random.nextInt(26))
+ }
+ }
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
index bb5594fe..cab1311c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
@@ -43,6 +43,7 @@ import com.pitchedapps.frost.facebook.parsers.NotifParser
import com.pitchedapps.frost.facebook.parsers.ParseNotification
import com.pitchedapps.frost.glide.FrostGlide
import com.pitchedapps.frost.glide.GlideApp
+import com.pitchedapps.frost.settings.hasNotifications
import com.pitchedapps.frost.utils.ARG_USER_ID
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
@@ -321,6 +322,12 @@ data class FrostNotification(
NotificationManagerCompat.from(context).notify(tag, id, notif.build())
}
+fun Context.scheduleNotificationsFromPrefs(): Boolean {
+ val shouldSchedule = Prefs.hasNotifications
+ return if (shouldSchedule) scheduleNotifications(Prefs.notificationFreq)
+ else scheduleNotifications(-1)
+}
+
fun Context.scheduleNotifications(minutes: Long): Boolean =
scheduleJob<NotificationService>(NOTIFICATION_PERIODIC_JOB, minutes)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt
index 0d707dae..fe59c421 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt
@@ -31,6 +31,7 @@ import com.pitchedapps.frost.utils.EnumBundle
import com.pitchedapps.frost.utils.EnumBundleCompanion
import com.pitchedapps.frost.utils.EnumCompanion
import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -162,13 +163,17 @@ class FrostRequestService : BaseJobService() {
override fun onStartJob(params: JobParameters?): Boolean {
super.onStartJob(params)
+ if (Prefs.webOnly) {
+ L.i { "Web only; skipping request service" }
+ return false
+ }
val bundle = params?.extras
if (bundle == null) {
L.eThrow("Launched ${this::class.java.simpleName} without param data")
return false
}
val cookie = bundle.getCookie()
- if (cookie.isNullOrBlank()) {
+ if (cookie.isBlank()) {
L.eThrow("Launched ${this::class.java.simpleName} without cookie")
return false
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
index 95726974..091fbb4b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
@@ -72,6 +72,10 @@ class NotificationService : BaseJobService() {
override fun onStartJob(params: JobParameters?): Boolean {
super.onStartJob(params)
L.i { "Fetching notifications" }
+ if (Prefs.webOnly) {
+ L.i { "Web only mode; skipping notification service" }
+ return false
+ }
launch {
try {
sendNotifications(params)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
index 7aac7526..d0963665 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
@@ -43,6 +43,13 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
// Experimental content starts here ------------------
+ checkbox(R.string.web_only, Prefs::webOnly, {
+ Prefs.webOnly = it
+ shouldRestartMain()
+ }) {
+ descRes = R.string.web_only_desc
+ }
+
// Experimental content ends here --------------------
checkbox(R.string.verbose_logging, Prefs::verboseLogging, {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
index 4ef76b3b..ccf04935 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
@@ -22,6 +22,7 @@ import android.media.RingtoneManager
import android.os.Build
import android.provider.Settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.items.KPrefText
import ca.allanwang.kau.utils.materialDialog
import ca.allanwang.kau.utils.minuteToText
@@ -35,8 +36,8 @@ import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.db.FrostDatabase
import com.pitchedapps.frost.db.deleteAll
import com.pitchedapps.frost.services.fetchNotifications
-import com.pitchedapps.frost.services.scheduleNotifications
import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.REQUEST_NOTIFICATION
import com.pitchedapps.frost.utils.frostSnackbar
import com.pitchedapps.frost.utils.frostUri
import com.pitchedapps.frost.views.Keywords
@@ -45,9 +46,27 @@ import kotlinx.coroutines.launch
/**
* Created by Allan Wang on 2017-06-29.
*/
+
+val Prefs.hasNotifications: Boolean
+ get() = !webOnly && (notificationsGeneral || notificationsInstantMessages)
+
@SuppressLint("InlinedApi")
fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
+ fun KPrefItemActions.leaveWebOnlyDialog() {
+ if (Prefs.webOnly) {
+ materialDialog {
+ title(R.string.leave_web_only_title)
+ message(R.string.leave_web_only_desc)
+ positiveButton(R.string.kau_yes) {
+ Prefs.webOnly = false
+ reload()
+ }
+ negativeButton(R.string.kau_no)
+ }
+ }
+ }
+
text(
R.string.notification_frequency,
Prefs::notificationFreq,
@@ -63,16 +82,14 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
initialSelection = options.indexOf(item.pref)
) { _, index, _ ->
item.pref = options[index]
- scheduleNotifications(item.pref)
+ setFrostResult(REQUEST_NOTIFICATION)
}
}
}
- enabler = {
- val enabled = Prefs.notificationsGeneral || Prefs.notificationsInstantMessages
- if (!enabled)
- scheduleNotifications(-1)
- enabled
+ onDisabledClick = {
+ leaveWebOnlyDialog()
}
+ enabler = { Prefs.hasNotifications }
textGetter = { minuteToText(it) }
}
@@ -97,12 +114,19 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
reloadByTitle(R.string.notification_frequency)
}) {
descRes = R.string.notification_general_desc
+ enabler = { !Prefs.webOnly }
+ onDisabledClick = {
+ leaveWebOnlyDialog()
+ }
}
checkbox(R.string.notification_general_all_accounts, Prefs::notificationAllAccounts,
{ Prefs.notificationAllAccounts = it }) {
descRes = R.string.notification_general_all_accounts_desc
- enabler = Prefs::notificationsGeneral
+ enabler = { !Prefs.webOnly && Prefs.notificationsGeneral }
+ onDisabledClick = {
+ leaveWebOnlyDialog()
+ }
}
checkbox(R.string.notification_messages, Prefs::notificationsInstantMessages,
@@ -113,12 +137,19 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
reloadByTitle(R.string.notification_frequency)
}) {
descRes = R.string.notification_messages_desc
+ enabler = { !Prefs.webOnly }
+ onDisabledClick = {
+ leaveWebOnlyDialog()
+ }
}
checkbox(R.string.notification_messages_all_accounts, Prefs::notificationsImAllAccounts,
{ Prefs.notificationsImAllAccounts = it }) {
descRes = R.string.notification_messages_all_accounts_desc
- enabler = Prefs::notificationsInstantMessages
+ enabler = { !Prefs.webOnly && Prefs.notificationsInstantMessages }
+ onDisabledClick = {
+ leaveWebOnlyDialog()
+ }
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt
index daca9676..5f65bba1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt
@@ -32,5 +32,6 @@ const val REQUEST_TEXT_ZOOM = 1 shl 8
const val REQUEST_NAV = 1 shl 9
const val REQUEST_SEARCH = 1 shl 10
const val REQUEST_FAB = 1 shl 11
+const val REQUEST_NOTIFICATION = 1 shl 12
const val MAIN_TIMEOUT_DURATION = 30 * 60 * 1000 // 30 min
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
index eb8e4b35..f17645d0 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -191,6 +191,8 @@ object Prefs : KPref() {
var showCreateFab: Boolean by kpref("show_create_fab", true)
+ var webOnly: Boolean by kpref("web_only", false)
+
inline val mainActivityLayout: MainActivityLayout
get() = MainActivityLayout(mainActivityLayoutType)
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 ecedc997..025119aa 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
@@ -91,7 +91,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
override fun onPageCommitVisible(view: WebView, url: String?) {
super.onPageCommitVisible(view, url)
injectBackgroundColor()
- if (url.isFacebookUrl)
+ if (url.isFacebookUrl) {
view.jsInject(
// CssHider.CORE,
CssHider.HEADER,
@@ -111,8 +111,9 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
JsAssets.CONTEXT_A,
JsAssets.MEDIA
)
- else
+ } else {
refresh.offer(false)
+ }
}
override fun onPageFinished(view: WebView, url: String?) {
@@ -212,19 +213,27 @@ class FrostWebViewClientMenu(web: FrostWebView) : FrostWebViewClient(web) {
override fun onPageFinished(view: WebView, url: String?) {
super.onPageFinished(view, url)
- if (url == null) return
- if (url.shouldInjectMenu) jsInject(JsAssets.MENU)
+ if (url == null) {
+ return
+ }
+ if (url.shouldInjectMenu) {
+ jsInject(JsAssets.MENU)
+ }
}
override fun emit(flag: Int) {
super.emit(flag)
when (flag) {
- EMIT_FINISH -> super.injectAndFinish()
+ EMIT_FINISH -> {
+ super.injectAndFinish()
+ }
}
}
override fun onPageFinishedActions(url: String) {
v { "Should inject ${url.shouldInjectMenu}" }
- if (!url.shouldInjectMenu) injectAndFinish()
+ if (!url.shouldInjectMenu) {
+ injectAndFinish()
+ }
}
}
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 09796b15..8e437c29 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -33,6 +33,7 @@ import com.pitchedapps.frost.db.CookieEntity
import com.pitchedapps.frost.facebook.FB_LOGIN_URL
import com.pitchedapps.frost.facebook.FB_USER_MATCHER
import com.pitchedapps.frost.facebook.FbCookie
+import com.pitchedapps.frost.facebook.USER_AGENT_MOBILE
import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.injectors.CssHider
import com.pitchedapps.frost.injectors.jsInject
@@ -57,6 +58,7 @@ class LoginWebView @JvmOverloads constructor(
@SuppressLint("SetJavaScriptEnabled")
private fun setupWebview() {
settings.javaScriptEnabled = true
+ settings.userAgentString = USER_AGENT_MOBILE
setLayerType(View.LAYER_TYPE_HARDWARE, null)
webViewClient = LoginClient()
webChromeClient = LoginChromeClient()