Skip to content

Commit e97490d

Browse files
committed
Merge branch 'release/5.28.1'
2 parents 14c4dbe + 750609f commit e97490d

File tree

15 files changed

+153
-18
lines changed

15 files changed

+153
-18
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import androidx.test.annotation.UiThreadTest
2424
import androidx.test.platform.app.InstrumentationRegistry
2525
import com.duckduckgo.app.browser.session.WebViewSessionInMemoryStorage
2626
import com.duckduckgo.app.fire.DuckDuckGoCookieManager
27+
import com.duckduckgo.app.global.file.FileDeleter
2728
import com.nhaarman.mockitokotlin2.mock
2829
import com.nhaarman.mockitokotlin2.verify
2930
import kotlinx.coroutines.runBlocking
@@ -35,7 +36,9 @@ class WebViewDataManagerTest {
3536

3637
private val mockCookieManager: DuckDuckGoCookieManager = mock()
3738
private val mockStorage: WebStorage = mock()
38-
private val testee = WebViewDataManager(WebViewSessionInMemoryStorage(), mockCookieManager)
39+
private val context = InstrumentationRegistry.getInstrumentation().targetContext
40+
private val mockFileDeleter: FileDeleter = mock()
41+
private val testee = WebViewDataManager(context, WebViewSessionInMemoryStorage(), mockCookieManager, mockFileDeleter)
3942

4043
@UiThreadTest
4144
@Test

app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ import javax.inject.Singleton
6565
PrivacyModule::class,
6666
WidgetModule::class,
6767
RatingModule::class,
68-
AppUsageModule::class
68+
AppUsageModule::class,
69+
FileModule::class
6970
]
7071
)
7172
interface TestAppComponent : AppComponent {

app/src/androidTest/java/com/duckduckgo/app/fire/WebViewCookieManagerTest.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import org.junit.Assert.assertEquals
2424
import org.junit.Assert.assertTrue
2525
import org.junit.Before
2626
import org.junit.Test
27+
import kotlin.coroutines.resume
28+
import kotlin.coroutines.suspendCoroutine
2729

2830
@Suppress("RemoveExplicitTypeArguments")
2931
class WebViewCookieManagerTest {
@@ -33,10 +35,19 @@ class WebViewCookieManagerTest {
3335
private val cookieManager: CookieManager = CookieManager.getInstance()
3436

3537
@Before
36-
fun setup() {
38+
fun setup() = runBlocking {
39+
removeExistingCookies()
3740
testee = WebViewCookieManager(cookieManager, host)
3841
}
3942

43+
private suspend fun removeExistingCookies() {
44+
withContext(Dispatchers.Main) {
45+
suspendCoroutine<Unit> { continuation ->
46+
cookieManager.removeAllCookies { continuation.resume(Unit) }
47+
}
48+
}
49+
}
50+
4051
@Test
4152
fun whenExternalCookiesClearedThenInternalCookiesRecreated() = runBlocking<Unit> {
4253
cookieManager.setCookie(host, "da=abc")

app/src/androidTest/java/com/duckduckgo/app/global/UriStringTest.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ class UriStringTest {
216216
assertFalse(isWebUrl("localhost/pa th"))
217217
}
218218

219+
@Test
220+
fun whenPathIsValidContainsEncodedSpaceNormalUrlThenIsWebUrlIsTrue() {
221+
assertTrue(isWebUrl("http://www.example.com/pa%20th"))
222+
}
223+
219224
@Test
220225
fun whenParamsAreValidNormalUrlThenIsWebUrlIsTrue() {
221226
assertTrue(isWebUrl("http://test.com?s=dafas&d=342"))

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,29 @@
1616

1717
package com.duckduckgo.app.browser
1818

19+
import android.content.Context
1920
import android.os.Build
2021
import android.webkit.WebStorage
2122
import android.webkit.WebView
2223
import android.webkit.WebViewDatabase
2324
import com.duckduckgo.app.browser.session.WebViewSessionStorage
2425
import com.duckduckgo.app.fire.DuckDuckGoCookieManager
26+
import com.duckduckgo.app.global.file.FileDeleter
27+
import java.io.File
2528
import javax.inject.Inject
2629

2730
interface WebDataManager {
2831
suspend fun clearExternalCookies()
2932
fun clearData(webView: WebView, webStorage: WebStorage, webViewDatabase: WebViewDatabase)
3033
fun clearWebViewSessions()
34+
suspend fun deleteWebViewDirectory()
3135
}
3236

3337
class WebViewDataManager @Inject constructor(
38+
private val context: Context,
3439
private val webViewSessionStorage: WebViewSessionStorage,
35-
private val cookieManager: DuckDuckGoCookieManager
40+
private val cookieManager: DuckDuckGoCookieManager,
41+
private val fileDeleter: FileDeleter
3642
) : WebDataManager {
3743

3844
override fun clearData(webView: WebView, webStorage: WebStorage, webViewDatabase: WebViewDatabase) {
@@ -64,6 +70,11 @@ class WebViewDataManager @Inject constructor(
6470
webView.clearFormData()
6571
}
6672

73+
override suspend fun deleteWebViewDirectory() {
74+
val webViewDataDirectory = File(context.applicationInfo.dataDir, WEBVIEW_DATA_DIRECTORY_NAME)
75+
fileDeleter.deleteContents(webViewDataDirectory, FILENAMES_EXCLUDED_FROM_DELETION)
76+
}
77+
6778
/**
6879
* Deprecated and not needed on Oreo or later
6980
*/
@@ -83,4 +94,13 @@ class WebViewDataManager @Inject constructor(
8394
override fun clearWebViewSessions() {
8495
webViewSessionStorage.deleteAllSessions()
8596
}
97+
98+
companion object {
99+
private const val WEBVIEW_DATA_DIRECTORY_NAME = "app_webview"
100+
101+
private val FILENAMES_EXCLUDED_FROM_DELETION = listOf(
102+
"Cookies",
103+
"Local Storage"
104+
)
105+
}
86106
}

app/src/main/java/com/duckduckgo/app/browser/di/BrowserModule.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import com.duckduckgo.app.browser.session.WebViewSessionStorage
3030
import com.duckduckgo.app.fire.DuckDuckGoCookieManager
3131
import com.duckduckgo.app.fire.WebViewCookieManager
3232
import com.duckduckgo.app.global.AppUrl
33+
import com.duckduckgo.app.global.file.FileDeleter
3334
import com.duckduckgo.app.global.install.AppInstallStore
3435
import com.duckduckgo.app.httpsupgrade.HttpsUpgrader
3536
import com.duckduckgo.app.privacy.db.PrivacyProtectionCountDao
@@ -91,8 +92,13 @@ class BrowserModule {
9192

9293
@Singleton
9394
@Provides
94-
fun webDataManager(webViewSessionStorage: WebViewSessionStorage, cookieManager: DuckDuckGoCookieManager): WebDataManager =
95-
WebViewDataManager(webViewSessionStorage, cookieManager)
95+
fun webDataManager(
96+
context: Context,
97+
webViewSessionStorage: WebViewSessionStorage,
98+
cookieManager: DuckDuckGoCookieManager,
99+
fileDeleter: FileDeleter
100+
): WebDataManager =
101+
WebViewDataManager(context, webViewSessionStorage, cookieManager, fileDeleter)
96102

97103
@Provides
98104
fun clipboardManager(context: Context): ClipboardManager {

app/src/main/java/com/duckduckgo/app/di/AppComponent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ import javax.inject.Singleton
6363
PrivacyModule::class,
6464
WidgetModule::class,
6565
RatingModule::class,
66-
AppUsageModule::class
66+
AppUsageModule::class,
67+
FileModule::class
6768
]
6869
)
6970
interface AppComponent : AndroidInjector<DuckDuckGoApplication> {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2019 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.di
18+
19+
import com.duckduckgo.app.global.file.AndroidFileDeleter
20+
import com.duckduckgo.app.global.file.FileDeleter
21+
import dagger.Module
22+
import dagger.Provides
23+
24+
25+
@Module
26+
class FileModule {
27+
28+
@Provides
29+
fun providesFileDeleter(): FileDeleter {
30+
return AndroidFileDeleter()
31+
}
32+
33+
}

app/src/main/java/com/duckduckgo/app/di/PrivacyModule.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import android.content.Context
2020
import com.duckduckgo.app.browser.WebDataManager
2121
import com.duckduckgo.app.entities.EntityMapping
2222
import com.duckduckgo.app.fire.*
23+
import com.duckduckgo.app.global.file.FileDeleter
2324
import com.duckduckgo.app.global.install.AppInstallStore
2425
import com.duckduckgo.app.global.view.ClearDataAction
2526
import com.duckduckgo.app.global.view.ClearPersonalDataAction
@@ -82,7 +83,7 @@ class PrivacyModule {
8283

8384
@Provides
8485
@Singleton
85-
fun appCacheCleaner(context: Context): AppCacheClearer {
86-
return AndroidAppCacheClearer(context)
86+
fun appCacheCleaner(context: Context, fileDeleter: FileDeleter): AppCacheClearer {
87+
return AndroidAppCacheClearer(context, fileDeleter)
8788
}
8889
}

app/src/main/java/com/duckduckgo/app/fire/AppCacheClearer.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
package com.duckduckgo.app.fire
1818

1919
import android.content.Context
20-
import kotlinx.coroutines.Dispatchers
21-
import kotlinx.coroutines.withContext
20+
import com.duckduckgo.app.global.file.FileDeleter
2221

2322

2423
interface AppCacheClearer {
@@ -27,12 +26,22 @@ interface AppCacheClearer {
2726

2827
}
2928

30-
class AndroidAppCacheClearer(private val context: Context) : AppCacheClearer {
29+
class AndroidAppCacheClearer(private val context: Context, private val fileDeleter: FileDeleter) : AppCacheClearer {
3130

3231
override suspend fun clearCache() {
33-
withContext(Dispatchers.IO) {
34-
context.cacheDir.deleteRecursively()
35-
}
32+
fileDeleter.deleteContents(context.cacheDir, FILENAMES_EXCLUDED_FROM_DELETION)
33+
}
34+
35+
companion object {
36+
37+
/* Exclude this WebView cache directory, based on warning from Firefox Focus:
38+
* "If the folder or its contents are deleted, WebView will stop using the disk cache entirely."
39+
*/
40+
private const val WEBVIEW_CACHE_DIR = "org.chromium.android_webview"
41+
42+
private val FILENAMES_EXCLUDED_FROM_DELETION = listOf(
43+
WEBVIEW_CACHE_DIR
44+
)
3645
}
3746

3847
}

0 commit comments

Comments
 (0)