Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import android.content.Context
import android.webkit.WebStorage
import android.webkit.WebView
import android.webkit.WebViewDatabase
import androidx.test.annotation.UiThreadTest
import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.browser.session.WebViewSessionInMemoryStorage
import com.duckduckgo.app.fire.DuckDuckGoCookieManager
import com.duckduckgo.app.global.file.FileDeleter
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.junit.Assert.assertTrue
import org.junit.Test

Expand All @@ -38,28 +39,61 @@ class WebViewDataManagerTest {
private val mockStorage: WebStorage = mock()
private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val mockFileDeleter: FileDeleter = mock()
private val mockWebViewDatabase: WebViewDatabase = mock()
private val testee = WebViewDataManager(context, WebViewSessionInMemoryStorage(), mockCookieManager, mockFileDeleter)

@UiThreadTest
@Test
fun whenDataClearedThenCacheHistoryAndStorageDataCleared() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val webView = TestWebView(context)
val mockWebViewDatabase = mock<WebViewDatabase>()

testee.clearData(webView, mockStorage, mockWebViewDatabase)

assertTrue(webView.historyCleared)
assertTrue(webView.cacheCleared)
assertTrue(webView.clearedFormData)
verify(mockStorage).deleteAllData()
verify(mockWebViewDatabase).clearHttpAuthUsernamePassword()
fun whenDataClearedThenWebViewHistoryCleared() = runBlocking<Unit> {
withContext(Dispatchers.Main) {
val webView = TestWebView(context)
testee.clearData(webView, mockStorage, mockWebViewDatabase)
assertTrue(webView.historyCleared)
}
}

@Test
fun whenDataClearedThenWebViewCacheCleared() = runBlocking<Unit> {
withContext(Dispatchers.Main) {
val webView = TestWebView(context)
testee.clearData(webView, mockStorage, mockWebViewDatabase)
assertTrue(webView.cacheCleared)
}
}

@Test
fun whenDataClearedThenWebViewFormDataCleared() = runBlocking<Unit> {
withContext(Dispatchers.Main) {
val webView = TestWebView(context)
testee.clearData(webView, mockStorage, mockWebViewDatabase)
assertTrue(webView.clearedFormData)
}
}

@Test
fun whenExternalCookiesClearedThenCookiesRemoved() = runBlocking<Unit> {
testee.clearExternalCookies()
verify(mockCookieManager).removeExternalCookies()
fun whenDataClearedThenWebViewWebStorageCleared() = runBlocking<Unit> {
withContext(Dispatchers.Main) {
val webView = TestWebView(context)
testee.clearData(webView, mockStorage, mockWebViewDatabase)
verify(mockStorage).deleteAllData()
}
}

@Test
fun whenDataClearedThenWebViewAuthCredentialsCleared() = runBlocking<Unit> {
withContext(Dispatchers.Main) {
val webView = TestWebView(context)
testee.clearData(webView, mockStorage, mockWebViewDatabase)
verify(mockWebViewDatabase).clearHttpAuthUsernamePassword()
}
}

@Test
fun whenDataClearedThenWebViewCookiesRemoved() = runBlocking<Unit> {
withContext(Dispatchers.Main) {
val webView = TestWebView(context)
testee.clearData(webView, mockStorage, mockWebViewDatabase)
verify(mockCookieManager).removeExternalCookies()
}
}

private class TestWebView(context: Context) : WebView(context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ class ClearPersonalDataActionTest {
verify(mockDataManager).clearData(any(), any(), any())
}

@Test
fun whenClearCalledThenDataManagerClearsCookies() = runBlocking<Unit> {
testee.clearTabsAndAllDataAsync(false, false)
verify(mockDataManager).clearExternalCookies()
}

@Test
fun whenClearCalledThenAppCacheClearerClearsCache() = runBlocking<Unit> {
testee.clearTabsAndAllDataAsync(false, false)
Expand Down
33 changes: 16 additions & 17 deletions app/src/main/java/com/duckduckgo/app/browser/WebDataManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ import java.io.File
import javax.inject.Inject

interface WebDataManager {
suspend fun clearExternalCookies()
fun clearData(webView: WebView, webStorage: WebStorage, webViewDatabase: WebViewDatabase)
suspend fun clearData(webView: WebView, webStorage: WebStorage, webViewDatabase: WebViewDatabase)
fun clearWebViewSessions()
suspend fun deleteWebViewDirectory()
}

class WebViewDataManager @Inject constructor(
Expand All @@ -41,20 +39,17 @@ class WebViewDataManager @Inject constructor(
private val fileDeleter: FileDeleter
) : WebDataManager {

override fun clearData(webView: WebView, webStorage: WebStorage, webViewDatabase: WebViewDatabase) {
clearCache(webView)
override suspend fun clearData(webView: WebView, webStorage: WebStorage, webViewDatabase: WebViewDatabase) {
clearWebViewCache(webView)
clearHistory(webView)
clearWebStorage(webStorage)
clearFormData(webView)

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
clearFormData(webViewDatabase)
}

clearFormData(webView, webViewDatabase)
clearAuthentication(webViewDatabase)
clearExternalCookies()
clearWebViewDirectory(exclusions = WEBVIEW_FILES_EXCLUDED_FROM_DELETION)
}

private fun clearCache(webView: WebView) {
private fun clearWebViewCache(webView: WebView) {
webView.clearCache(true)
}

Expand All @@ -66,13 +61,17 @@ class WebViewDataManager @Inject constructor(
webStorage.deleteAllData()
}

private fun clearFormData(webView: WebView) {
private fun clearFormData(webView: WebView, webViewDatabase: WebViewDatabase) {
webView.clearFormData()

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
clearFormData(webViewDatabase)
}
}

override suspend fun deleteWebViewDirectory() {
private suspend fun clearWebViewDirectory(exclusions: List<String>) {
val webViewDataDirectory = File(context.applicationInfo.dataDir, WEBVIEW_DATA_DIRECTORY_NAME)
fileDeleter.deleteContents(webViewDataDirectory, FILENAMES_EXCLUDED_FROM_DELETION)
fileDeleter.deleteContents(webViewDataDirectory, exclusions)
}

/**
Expand All @@ -87,7 +86,7 @@ class WebViewDataManager @Inject constructor(
webViewDatabase.clearHttpAuthUsernamePassword()
}

override suspend fun clearExternalCookies() {
private suspend fun clearExternalCookies() {
cookieManager.removeExternalCookies()
}

Expand All @@ -98,7 +97,7 @@ class WebViewDataManager @Inject constructor(
companion object {
private const val WEBVIEW_DATA_DIRECTORY_NAME = "app_webview"

private val FILENAMES_EXCLUDED_FROM_DELETION = listOf(
private val WEBVIEW_FILES_EXCLUDED_FROM_DELETION = listOf(
"Cookies"
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ class ClearPersonalDataAction @Inject constructor(
}

dataManager.clearData(createWebView(), createWebStorage(), WebViewDatabase.getInstance(context))
dataManager.clearExternalCookies()
dataManager.deleteWebViewDirectory()

appCacheClearer.clearCache()

Timber.i("Finished clearing data")
Expand Down