Skip to content

Commit 0127867

Browse files
authored
Feature/phishing url fix (#390)
* Make use of onProgressChanged instead on onPageCommitVisible We erroneously relied on onPageCommitVisible() but it was only ever called on API 23 or up, breaking functionality for Lollipop users. We put in a patch, which made use of onPageCommitVisible() for newer users only. Now, we're stopping relying on onPageCommitVisible altogether and making use of onProgressChanged instead for the functionality. * Alternative approach to handling when url has changed * Remove redundant variable
1 parent 161dbad commit 0127867

File tree

6 files changed

+104
-58
lines changed

6 files changed

+104
-58
lines changed

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserChromeClientTest.kt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
package com.duckduckgo.app.browser
1818

19+
import android.content.Context
1920
import android.support.test.InstrumentationRegistry
21+
import android.support.test.annotation.UiThreadTest
2022
import android.view.View
2123
import android.webkit.WebChromeClient
24+
import android.webkit.WebView
25+
import com.nhaarman.mockito_kotlin.any
2226
import com.nhaarman.mockito_kotlin.mock
2327
import com.nhaarman.mockito_kotlin.times
2428
import com.nhaarman.mockito_kotlin.verify
@@ -28,14 +32,17 @@ import org.junit.Test
2832
class BrowserChromeClientTest {
2933

3034
private lateinit var testee: BrowserChromeClient
35+
private lateinit var webView: TestWebView
3136
private lateinit var mockWebViewClientListener: WebViewClientListener
3237
private val fakeView = View(InstrumentationRegistry.getTargetContext())
3338

39+
@UiThreadTest
3440
@Before
3541
fun setup() {
3642
testee = BrowserChromeClient()
3743
mockWebViewClientListener = mock()
3844
testee.webViewClientListener = mockWebViewClientListener
45+
webView = TestWebView(InstrumentationRegistry.getTargetContext())
3946
}
4047

4148
@Test
@@ -66,4 +73,59 @@ class BrowserChromeClientTest {
6673
testee.onHideCustomView()
6774
verify(mockWebViewClientListener).exitFullScreen()
6875
}
76+
77+
@UiThreadTest
78+
@Test
79+
fun whenOnProgressChangedCalledThenListenerInstructedToUpdateProgress() {
80+
testee.onProgressChanged(webView, 10)
81+
verify(mockWebViewClientListener).progressChanged(10)
82+
}
83+
84+
@UiThreadTest
85+
@Test
86+
fun whenOnProgressChangedCalledButNoUrlChangeThenListenerInstructedToUpdateProgressASecondTime() {
87+
webView.stubUrl = "foo.com"
88+
testee.onProgressChanged(webView, 10)
89+
testee.onProgressChanged(webView, 20)
90+
verify(mockWebViewClientListener, times(2)).progressChanged(any())
91+
}
92+
93+
@UiThreadTest
94+
@Test
95+
fun whenOnProgressChangedCalledAfterUrlChangeThenListenerInstructedToUpdateProgressAgain() {
96+
webView.stubUrl = "foo.com"
97+
testee.onProgressChanged(webView, 10)
98+
testee.onProgressChanged(webView, 20)
99+
webView.stubUrl = "bar.com"
100+
testee.onProgressChanged(webView, 30)
101+
verify(mockWebViewClientListener, times(3)).progressChanged(any())
102+
}
103+
104+
@UiThreadTest
105+
@Test
106+
fun whenOnProgressChangedCalledThenListenerInstructedToUpdateUrl() {
107+
val url = "https://example.com"
108+
webView.stubUrl = url
109+
testee.onProgressChanged(webView, 10)
110+
verify(mockWebViewClientListener).urlChanged(url)
111+
}
112+
113+
@UiThreadTest
114+
@Test
115+
fun whenOnProgressChangedCalledAfterUrlChangeThenListenerInstructedToUpdateUrlEveryTime() {
116+
webView.stubUrl = "foo.com"
117+
testee.onProgressChanged(webView, 10)
118+
testee.onProgressChanged(webView, 20)
119+
webView.stubUrl = "bar.com"
120+
testee.onProgressChanged(webView, 30)
121+
verify(mockWebViewClientListener, times(3)).urlChanged(any())
122+
}
123+
124+
private class TestWebView(context: Context) : WebView(context) {
125+
var stubUrl: String = ""
126+
127+
override fun getUrl(): String {
128+
return stubUrl
129+
}
130+
}
69131
}

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserWebViewClientTest.kt

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@
1717
package com.duckduckgo.app.browser
1818

1919
import android.content.Context
20-
import android.os.Build
2120
import android.support.test.InstrumentationRegistry
2221
import android.support.test.annotation.UiThreadTest
23-
import android.support.test.filters.SdkSuppress
2422
import android.webkit.WebView
2523
import com.duckduckgo.app.httpsupgrade.HttpsUpgrader
2624
import com.duckduckgo.app.statistics.pixels.Pixel
@@ -63,35 +61,11 @@ class BrowserWebViewClientTest {
6361

6462
@UiThreadTest
6563
@Test
66-
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
67-
fun whenOnPageStartedCalledOnNewerDevicesThenListenerNotInstructedToUpdateUrl() {
64+
fun whenOnPageStartedCalledThenListenerNeverInstructedToUpdateUrl() {
6865
testee.onPageStarted(webView, EXAMPLE_URL, null)
6966
verify(listener, never()).urlChanged(any())
7067
}
7168

72-
@UiThreadTest
73-
@Test
74-
@SdkSuppress(maxSdkVersion = Build.VERSION_CODES.LOLLIPOP_MR1)
75-
fun whenOnPageStartedCalledOnOlderDevicesThenListenerInstructedToUpdateUrl() {
76-
testee.onPageStarted(webView, EXAMPLE_URL, null)
77-
verify(listener).urlChanged(any())
78-
}
79-
80-
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
81-
@UiThreadTest
82-
@Test
83-
fun whenOnPageCommitVisibleCalledThenListenerInstructedToUpdateUrl() {
84-
testee.onPageCommitVisible(webView, EXAMPLE_URL)
85-
verify(listener).urlChanged(EXAMPLE_URL)
86-
}
87-
88-
@UiThreadTest
89-
@Test
90-
fun whenOnPageCommitVisibleCalledThenListenerInstructedToUpdateNavigationOptions() {
91-
testee.onPageCommitVisible(webView, EXAMPLE_URL)
92-
verify(listener).navigationOptionsChanged(any())
93-
}
94-
9569
@UiThreadTest
9670
@Test
9771
fun whenOnPageFinishedCalledThenListenerNotified() {
@@ -106,6 +80,13 @@ class BrowserWebViewClientTest {
10680
verify(listener).navigationOptionsChanged(any())
10781
}
10882

83+
@UiThreadTest
84+
@Test
85+
fun whenOnPageFinishedCalledThenListenerInstructedToUpdateUrl() {
86+
testee.onPageFinished(webView, EXAMPLE_URL)
87+
verify(listener).urlChanged(EXAMPLE_URL)
88+
}
89+
10990
private class TestWebView(context: Context) : WebView(context)
11091

11192
companion object {

app/src/main/java/com/duckduckgo/app/browser/BrowserChromeClient.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class BrowserChromeClient @Inject constructor() : WebChromeClient() {
3232
private var customView: View? = null
3333

3434
override fun onShowCustomView(view: View, callback: CustomViewCallback?) {
35-
Timber.i("on show custom view")
35+
Timber.d("on show custom view")
3636

3737
if (customView != null) {
3838
callback?.onCustomViewHidden()
@@ -44,14 +44,22 @@ class BrowserChromeClient @Inject constructor() : WebChromeClient() {
4444
}
4545

4646
override fun onHideCustomView() {
47-
Timber.i("hide custom view")
47+
Timber.d("on hide custom view")
4848

4949
webViewClientListener?.exitFullScreen()
5050
customView = null
5151
}
5252

5353
override fun onProgressChanged(webView: WebView, newProgress: Int) {
54+
Timber.d("onProgressChanged - $newProgress - ${webView.url}")
55+
5456
webViewClientListener?.progressChanged(newProgress)
57+
58+
val currentUrl = webViewClientListener?.currentUrl()
59+
if (currentUrl != webView.url) {
60+
Timber.i("Url has changed from $currentUrl to ${webView.url}")
61+
webViewClientListener?.urlChanged(webView.url)
62+
}
5563
}
5664

5765
override fun onReceivedTitle(view: WebView, title: String) {

app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ class BrowserTabViewModel(
8585
private val addToHomeCapabilityDetector: AddToHomeCapabilityDetector,
8686
appConfigurationDao: AppConfigurationDao
8787
) : WebViewClientListener, SaveBookmarkListener, ViewModel() {
88-
8988
data class GlobalLayoutViewState(
9089
val isNewTabState: Boolean = true
9190
)
@@ -343,7 +342,11 @@ class BrowserTabViewModel(
343342
findInPageViewState.value = FindInPageViewState(visible = false, canFindInPage = false)
344343

345344
val currentBrowserViewState = currentBrowserViewState()
346-
browserViewState.value = currentBrowserViewState.copy(canAddBookmarks = false, addToHomeEnabled = false, addToHomeVisible = addToHomeCapabilityDetector.isAddToHomeSupported())
345+
browserViewState.value = currentBrowserViewState.copy(
346+
canAddBookmarks = false,
347+
addToHomeEnabled = false,
348+
addToHomeVisible = addToHomeCapabilityDetector.isAddToHomeSupported()
349+
)
347350

348351
return
349352
}
@@ -367,8 +370,10 @@ class BrowserTabViewModel(
367370
statisticsUpdater.refreshRetentionAtb()
368371
}
369372

370-
site = siteFactory.build(url)
371-
onSiteChanged()
373+
if (currentUrl() != url) {
374+
site = siteFactory.build(url)
375+
onSiteChanged()
376+
}
372377
}
373378

374379
private fun omnibarTextForUrl(url: String): String {
@@ -557,6 +562,10 @@ class BrowserTabViewModel(
557562
}
558563
}
559564

565+
override fun currentUrl(): String? {
566+
return site?.url
567+
}
568+
560569
fun resetView() {
561570
site = null
562571
url.value = null

app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ class BrowserWebViewClient @Inject constructor(
5252

5353
private var currentUrl: String? = null
5454

55-
private val willGetNotifiedOfPageCommits = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
56-
5755
/**
5856
* This is the new method of url overriding available from API 24 onwards
5957
*/
@@ -109,33 +107,27 @@ class BrowserWebViewClient @Inject constructor(
109107
}
110108

111109
override fun onPageStarted(webView: WebView, url: String?, favicon: Bitmap?) {
112-
Timber.d("onPageStarted $url")
113-
114-
webViewClientListener?.loadingStarted()
110+
Timber.d("\nonPageStarted {\nurl: $url\nwebView.url: ${webView.url}\n}\n")
115111

116-
if (!willGetNotifiedOfPageCommits) onUrlChanged(url, webView)
112+
currentUrl = url
113+
webViewClientListener?.let {
114+
it.loadingStarted()
115+
it.navigationOptionsChanged(determineNavigationOptions(webView))
116+
}
117117

118-
val uri = if (url != null) Uri.parse(url) else null
118+
val uri = if (currentUrl != null) Uri.parse(currentUrl) else null
119119
if (uri != null) {
120120
reportHttpsIfInUpgradeList(uri)
121121
}
122122
}
123123

124-
/**
125-
* Note, this method is only called on APIs >= 23
126-
* While this is the ideal time to indicate the URL has changed, on lower APIs we need to handle that instead in onPageStarted()
127-
*/
128-
override fun onPageCommitVisible(webView: WebView, url: String?) {
129-
Timber.d("onPageCommitVisible $url")
130-
131-
onUrlChanged(url, webView)
132-
}
133-
134124
override fun onPageFinished(webView: WebView, url: String?) {
135125
Timber.d("onPageFinished $url")
136126

127+
currentUrl = url
137128
webViewClientListener?.let {
138129
it.loadingFinished(url)
130+
it.urlChanged(url)
139131
it.navigationOptionsChanged(determineNavigationOptions(webView))
140132
}
141133
}
@@ -222,14 +214,6 @@ class BrowserWebViewClient @Inject constructor(
222214
return BrowserNavigationOptions(canGoBack, canGoForward)
223215
}
224216

225-
private fun onUrlChanged(url: String?, webView: WebView) {
226-
currentUrl = url
227-
webViewClientListener?.let {
228-
it.urlChanged(url)
229-
it.navigationOptionsChanged(determineNavigationOptions(webView))
230-
}
231-
}
232-
233217
data class BrowserNavigationOptions(val canGoBack: Boolean, val canGoForward: Boolean)
234218

235219
}

app/src/main/java/com/duckduckgo/app/browser/WebViewClientListener.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import com.duckduckgo.app.browser.BrowserWebViewClient.BrowserNavigationOptions
2424
import com.duckduckgo.app.trackerdetection.model.TrackingEvent
2525

2626
interface WebViewClientListener {
27+
fun currentUrl(): String?
28+
2729
fun loadingStarted()
2830
fun loadingFinished(url: String? = null)
2931
fun progressChanged(newProgress: Int)

0 commit comments

Comments
 (0)