Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Tor Project
Applications
android-components
Commits
976349ba
Commit
976349ba
authored
Sep 26, 2019
by
Arturo Mejia
Browse files
For issue #3264 Add api for interacting with the tracking protection
exceptions.
parent
44eac4b1
Changes
17
Hide whitespace changes
Inline
Side-by-side
components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt
View file @
976349ba
...
...
@@ -19,6 +19,7 @@ import mozilla.components.concept.engine.EngineSessionState
import
mozilla.components.concept.engine.EngineView
import
mozilla.components.concept.engine.Settings
import
mozilla.components.concept.engine.content.blocking.TrackerLog
import
mozilla.components.concept.engine.content.blocking.TrackingProtectionExceptionStorage
import
mozilla.components.concept.engine.history.HistoryTrackingDelegate
import
mozilla.components.concept.engine.mediaquery.PreferredColorScheme
import
mozilla.components.concept.engine.utils.EngineVersion
...
...
@@ -40,7 +41,9 @@ class GeckoEngine(
context
:
Context
,
private
val
defaultSettings
:
Settings
?
=
null
,
private
val
runtime
:
GeckoRuntime
=
GeckoRuntime
.
getDefault
(
context
),
executorProvider
:
()
->
GeckoWebExecutor
=
{
GeckoWebExecutor
(
runtime
)
}
executorProvider
:
()
->
GeckoWebExecutor
=
{
GeckoWebExecutor
(
runtime
)
},
override
val
trackingProtectionExceptionStore
:
TrackingProtectionExceptionStorage
=
TrackingProtectionExceptionFileStorage
(
context
,
runtime
)
)
:
Engine
{
private
val
executor
by
lazy
{
executorProvider
.
invoke
()
}
...
...
@@ -56,6 +59,7 @@ class GeckoEngine(
@Suppress
(
"TooGenericExceptionThrown"
)
throw
RuntimeException
(
"GeckoRuntime is shutting down"
)
}
trackingProtectionExceptionStore
.
restore
()
}
/**
...
...
components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/TrackingProtectionExceptionFileStorage.kt
0 → 100644
View file @
976349ba
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package
mozilla.components.browser.engine.gecko
import
android.content.Context
import
android.util.AtomicFile
import
androidx.annotation.VisibleForTesting
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
import
mozilla.components.concept.engine.EngineSession
import
mozilla.components.concept.engine.content.blocking.TrackingProtectionExceptionStorage
import
mozilla.components.support.ktx.util.readAndDeserialize
import
mozilla.components.support.ktx.util.writeString
import
org.mozilla.geckoview.GeckoRuntime
import
java.io.File
private
const
val
STORE_FILE_NAME_FORMAT
=
"mozilla_components_tracking_protection_storage_gecko.json"
/**
* A [TrackingProtectionExceptionStorage] implementation to store tracking protection exceptions.
*/
internal
class
TrackingProtectionExceptionFileStorage
(
private
val
context
:
Context
,
private
val
runtime
:
GeckoRuntime
)
:
TrackingProtectionExceptionStorage
{
private
val
fileLock
=
Any
()
internal
var
scope
=
CoroutineScope
(
Dispatchers
.
IO
)
/**
* Restore all exceptions from the [STORE_FILE_NAME_FORMAT] file,
* and provides them to the gecko [runtime].
*/
override
fun
restore
()
{
scope
.
launch
{
synchronized
(
fileLock
)
{
getFile
(
context
).
readAndDeserialize
{
json
->
if
(
json
.
isNotEmpty
())
{
val
exceptionList
=
runtime
.
contentBlockingController
.
ExceptionList
(
json
)
runtime
.
contentBlockingController
.
restoreExceptionList
(
exceptionList
)
}
}
}
}
}
override
fun
contains
(
session
:
EngineSession
,
onResult
:
(
Boolean
)
->
Unit
)
{
val
geckoSession
=
(
session
as
GeckoEngineSession
).
geckoSession
runtime
.
contentBlockingController
.
checkException
(
geckoSession
).
accept
{
if
(
it
!=
null
)
{
onResult
(
it
)
}
else
{
onResult
(
false
)
}
}
}
override
fun
fetchAll
(
onResult
:
(
List
<
String
>)
->
Unit
)
{
runtime
.
contentBlockingController
.
saveExceptionList
().
accept
{
exceptionList
->
val
exceptions
=
if
(
exceptionList
!=
null
)
{
val
uris
=
exceptionList
.
uris
.
map
{
uri
->
uri
}
uris
}
else
{
emptyList
()
}
onResult
(
exceptions
)
}
}
override
fun
add
(
session
:
EngineSession
)
{
val
geckoSession
=
(
session
as
GeckoEngineSession
).
geckoSession
runtime
.
contentBlockingController
.
addException
(
geckoSession
)
persist
()
}
override
fun
remove
(
session
:
EngineSession
)
{
val
geckoSession
=
(
session
as
GeckoEngineSession
).
geckoSession
runtime
.
contentBlockingController
.
removeException
(
geckoSession
)
persist
()
}
override
fun
removeAll
()
{
runtime
.
contentBlockingController
.
clearExceptionList
()
removeFileFromDisk
(
context
)
}
@VisibleForTesting
(
otherwise
=
VisibleForTesting
.
PRIVATE
)
internal
fun
getFile
(
context
:
Context
):
AtomicFile
{
return
AtomicFile
(
File
(
context
.
filesDir
,
STORE_FILE_NAME_FORMAT
)
)
}
/**
* Take all the exception from the gecko [runtime] and saves them into the
* [STORE_FILE_NAME_FORMAT] file.
*/
private
fun
persist
()
{
runtime
.
contentBlockingController
.
saveExceptionList
().
accept
{
exceptionList
->
if
(
exceptionList
!=
null
)
{
scope
.
launch
{
synchronized
(
fileLock
)
{
getFile
(
context
).
writeString
{
exceptionList
.
toJson
().
toString
()
}
}
}
}
else
{
removeFileFromDisk
(
context
)
}
}
}
private
fun
removeFileFromDisk
(
context
:
Context
)
{
scope
.
launch
{
synchronized
(
fileLock
)
{
getFile
(
context
)
.
delete
()
}
}
}
}
components/browser/engine-gecko-beta/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineTest.kt
View file @
976349ba
...
...
@@ -15,6 +15,7 @@ import mozilla.components.concept.engine.EngineSession.SafeBrowsingPolicy
import
mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.CookiePolicy
import
mozilla.components.concept.engine.UnsupportedSettingException
import
mozilla.components.concept.engine.content.blocking.TrackerLog
import
mozilla.components.concept.engine.content.blocking.TrackingProtectionExceptionStorage
import
mozilla.components.concept.engine.mediaquery.PreferredColorScheme
import
mozilla.components.support.test.any
import
mozilla.components.support.test.argumentCaptor
...
...
@@ -585,6 +586,15 @@ class GeckoEngineTest {
assertTrue
(
version
.
isAtLeast
(
69
,
0
,
0
))
}
@Test
fun
`after
init
is
called
the
trackingProtectionExceptionStore
must
be
restored`
()
{
val
mockStore
:
TrackingProtectionExceptionStorage
=
mock
()
val
runtime
:
GeckoRuntime
=
mock
()
GeckoEngine
(
context
,
runtime
=
runtime
,
trackingProtectionExceptionStore
=
mockStore
)
verify
(
mockStore
).
restore
()
}
private
fun
createDummyLogEntryList
():
List
<
ContentBlockingController
.
LogEntry
>
{
val
addLogEntry
=
object
:
ContentBlockingController
.
LogEntry
()
{}
...
...
components/browser/engine-gecko-beta/src/test/java/mozilla/components/browser/engine/gecko/TrackingProtectionExceptionFileStorageTest.kt
0 → 100644
View file @
976349ba
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package
mozilla.components.browser.engine.gecko
import
android.app.Activity
import
android.content.Context
import
androidx.test.ext.junit.runners.AndroidJUnit4
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
mozilla.components.support.ktx.util.readAndDeserialize
import
mozilla.components.support.test.any
import
mozilla.components.support.test.mock
import
mozilla.components.support.test.robolectric.testContext
import
mozilla.components.support.test.whenever
import
org.json.JSONObject
import
org.junit.Assert.assertFalse
import
org.junit.Assert.assertNotNull
import
org.junit.Assert.assertNull
import
org.junit.Assert.assertTrue
import
org.junit.Test
import
org.junit.runner.RunWith
import
org.mockito.Mockito.verify
import
org.mozilla.geckoview.ContentBlockingController
import
org.mozilla.geckoview.GeckoResult
import
org.mozilla.geckoview.GeckoRuntime
import
org.mozilla.geckoview.GeckoSession
import
org.robolectric.Robolectric.buildActivity
@RunWith
(
AndroidJUnit4
::
class
)
class
TrackingProtectionExceptionFileStorageTest
{
private
val
context
:
Context
get
()
=
buildActivity
(
Activity
::
class
.
java
).
get
()
@Test
fun
`restoreAsync
exception`
()
{
val
mockContentBlocking
=
mock
<
ContentBlockingController
>()
val
runtime
:
GeckoRuntime
=
mock
()
val
session
=
mock
<
GeckoEngineSession
>()
val
geckoResult
=
GeckoResult
<
ContentBlockingController
.
ExceptionList
>()
val
mockGeckoSession
=
mock
<
GeckoSession
>()
val
mockExceptionList
=
mock
<
ContentBlockingController
.
ExceptionList
>()
whenever
(
session
.
geckoSession
).
thenReturn
(
mockGeckoSession
)
whenever
(
runtime
.
contentBlockingController
).
thenReturn
(
mockContentBlocking
)
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
whenever
(
mockExceptionList
.
toJson
()).
thenReturn
(
JSONObject
(
"{\"principals\":[\"eyIxIjp7IjAiOiJodHRwczovL3d3dy5jbm4uY29tLyJ9fQ==\"],\"uris\":[\"https:\\/\\/www.cnn.com\\/\"]}"
))
val
storage
=
TrackingProtectionExceptionFileStorage
(
testContext
,
runtime
)
storage
.
scope
=
CoroutineScope
(
Dispatchers
.
Main
)
assertNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
storage
.
add
(
session
)
geckoResult
.
complete
(
mockExceptionList
)
storage
.
restore
()
verify
(
mockContentBlocking
).
restoreExceptionList
(
any
())
assertNotNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
}
@Test
fun
`add
exception`
()
{
val
mockContentBlocking
=
mock
<
ContentBlockingController
>()
val
runtime
:
GeckoRuntime
=
mock
()
val
session
=
mock
<
GeckoEngineSession
>()
val
geckoResult
=
GeckoResult
<
ContentBlockingController
.
ExceptionList
>()
val
mockGeckoSession
=
mock
<
GeckoSession
>()
val
mockExceptionList
=
mock
<
ContentBlockingController
.
ExceptionList
>()
whenever
(
session
.
geckoSession
).
thenReturn
(
mockGeckoSession
)
whenever
(
runtime
.
contentBlockingController
).
thenReturn
(
mockContentBlocking
)
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
whenever
(
mockExceptionList
.
toJson
()).
thenReturn
(
JSONObject
(
"{\"principals\":[\"eyIxIjp7IjAiOiJodHRwczovL3d3dy5jbm4uY29tLyJ9fQ==\"],\"uris\":[\"https:\\/\\/www.cnn.com\\/\"]}"
))
val
storage
=
TrackingProtectionExceptionFileStorage
(
testContext
,
runtime
)
storage
.
scope
=
CoroutineScope
(
Dispatchers
.
Main
)
assertNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
storage
.
add
(
session
)
geckoResult
.
complete
(
mockExceptionList
)
verify
(
mockContentBlocking
).
addException
(
mockGeckoSession
)
verify
(
mockContentBlocking
).
saveExceptionList
()
assertNotNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
}
@Test
fun
`remove
all
exceptions`
()
{
val
mockContentBlocking
=
mock
<
ContentBlockingController
>()
val
runtime
:
GeckoRuntime
=
mock
()
val
session
=
mock
<
GeckoEngineSession
>()
val
geckoResult
=
GeckoResult
<
ContentBlockingController
.
ExceptionList
>()
val
mockGeckoSession
=
mock
<
GeckoSession
>()
val
mockExceptionList
=
mock
<
ContentBlockingController
.
ExceptionList
>()
whenever
(
session
.
geckoSession
).
thenReturn
(
mockGeckoSession
)
whenever
(
runtime
.
contentBlockingController
).
thenReturn
(
mockContentBlocking
)
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
whenever
(
mockExceptionList
.
toJson
()).
thenReturn
(
JSONObject
(
"{\"principals\":[\"eyIxIjp7IjAiOiJodHRwczovL3d3dy5jbm4uY29tLyJ9fQ==\"],\"uris\":[\"https:\\/\\/www.cnn.com\\/\"]}"
))
// Adding exception
val
storage
=
TrackingProtectionExceptionFileStorage
(
testContext
,
runtime
)
storage
.
scope
=
CoroutineScope
(
Dispatchers
.
Main
)
assertNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
storage
.
add
(
session
)
geckoResult
.
complete
(
mockExceptionList
)
verify
(
mockContentBlocking
).
addException
(
mockGeckoSession
)
verify
(
mockContentBlocking
).
saveExceptionList
()
assertNotNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
// Removing exceptions
storage
.
removeAll
()
verify
(
mockContentBlocking
).
clearExceptionList
()
assertNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
}
@Test
fun
`remove
exception`
()
{
val
mockContentBlocking
=
mock
<
ContentBlockingController
>()
val
runtime
:
GeckoRuntime
=
mock
()
val
session
=
mock
<
GeckoEngineSession
>()
var
geckoResult
=
GeckoResult
<
ContentBlockingController
.
ExceptionList
>()
val
mockGeckoSession
=
mock
<
GeckoSession
>()
val
mockExceptionList
=
mock
<
ContentBlockingController
.
ExceptionList
>()
whenever
(
session
.
geckoSession
).
thenReturn
(
mockGeckoSession
)
whenever
(
runtime
.
contentBlockingController
).
thenReturn
(
mockContentBlocking
)
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
whenever
(
mockExceptionList
.
toJson
()).
thenReturn
(
JSONObject
(
"{\"principals\":[\"eyIxIjp7IjAiOiJodHRwczovL3d3dy5jbm4uY29tLyJ9fQ==\"],\"uris\":[\"https:\\/\\/www.cnn.com\\/\"]}"
))
// Adding exception
val
storage
=
TrackingProtectionExceptionFileStorage
(
testContext
,
runtime
)
storage
.
scope
=
CoroutineScope
(
Dispatchers
.
Main
)
assertNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
storage
.
add
(
session
)
geckoResult
.
complete
(
mockExceptionList
)
verify
(
mockContentBlocking
).
addException
(
mockGeckoSession
)
verify
(
mockContentBlocking
).
saveExceptionList
()
assertNotNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
// Removing exception
geckoResult
=
GeckoResult
()
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
storage
.
remove
(
session
)
verify
(
mockContentBlocking
).
removeException
(
mockGeckoSession
)
geckoResult
.
complete
(
null
)
assertNull
(
storage
.
getFile
(
context
).
readAndDeserialize
{
})
}
@Test
fun
`contains
exception`
()
{
val
mockContentBlocking
=
mock
<
ContentBlockingController
>()
val
runtime
:
GeckoRuntime
=
mock
()
val
session
=
mock
<
GeckoEngineSession
>()
var
geckoResult
=
GeckoResult
<
Boolean
>()
val
mockGeckoSession
=
mock
<
GeckoSession
>()
var
containsException
=
false
whenever
(
session
.
geckoSession
).
thenReturn
(
mockGeckoSession
)
whenever
(
runtime
.
contentBlockingController
).
thenReturn
(
mockContentBlocking
)
whenever
(
runtime
.
contentBlockingController
.
checkException
(
mockGeckoSession
)).
thenReturn
(
geckoResult
)
val
storage
=
TrackingProtectionExceptionFileStorage
(
testContext
,
runtime
)
storage
.
contains
(
session
)
{
contains
->
containsException
=
contains
}
geckoResult
.
complete
(
true
)
verify
(
mockContentBlocking
).
checkException
(
mockGeckoSession
)
assertTrue
(
containsException
)
geckoResult
=
GeckoResult
()
whenever
(
runtime
.
contentBlockingController
.
checkException
(
mockGeckoSession
)).
thenReturn
(
geckoResult
)
storage
.
contains
(
session
)
{
contains
->
containsException
=
contains
}
geckoResult
.
complete
(
null
)
assertFalse
(
containsException
)
}
@Test
fun
`getAll
exceptions`
()
{
val
mockContentBlocking
=
mock
<
ContentBlockingController
>()
val
runtime
:
GeckoRuntime
=
mock
()
val
session
=
mock
<
GeckoEngineSession
>()
var
geckoResult
=
GeckoResult
<
ContentBlockingController
.
ExceptionList
>()
val
mockGeckoSession
=
mock
<
GeckoSession
>()
val
mockExceptionList
=
mock
<
ContentBlockingController
.
ExceptionList
>()
var
exceptionList
:
List
<
String
>?
=
null
whenever
(
session
.
geckoSession
).
thenReturn
(
mockGeckoSession
)
whenever
(
runtime
.
contentBlockingController
).
thenReturn
(
mockContentBlocking
)
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
whenever
(
mockExceptionList
.
uris
).
thenReturn
(
arrayOf
(
"mozilla.com"
))
val
storage
=
TrackingProtectionExceptionFileStorage
(
testContext
,
runtime
)
storage
.
fetchAll
{
exceptions
->
exceptionList
=
exceptions
}
geckoResult
.
complete
(
mockExceptionList
)
verify
(
mockContentBlocking
).
saveExceptionList
()
assertTrue
(
exceptionList
!!
.
isNotEmpty
())
geckoResult
=
GeckoResult
()
whenever
(
runtime
.
contentBlockingController
.
saveExceptionList
()).
thenReturn
(
geckoResult
)
storage
.
fetchAll
{
exceptions
->
exceptionList
=
exceptions
}
geckoResult
.
complete
(
null
)
assertTrue
(
exceptionList
!!
.
isEmpty
())
}
}
components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt
View file @
976349ba
...
...
@@ -19,6 +19,7 @@ import mozilla.components.concept.engine.EngineSessionState
import
mozilla.components.concept.engine.EngineView
import
mozilla.components.concept.engine.Settings
import
mozilla.components.concept.engine.content.blocking.TrackerLog
import
mozilla.components.concept.engine.content.blocking.TrackingProtectionExceptionStorage
import
mozilla.components.concept.engine.history.HistoryTrackingDelegate
import
mozilla.components.concept.engine.mediaquery.PreferredColorScheme
import
mozilla.components.concept.engine.utils.EngineVersion
...
...
@@ -40,10 +41,11 @@ class GeckoEngine(
context
:
Context
,
private
val
defaultSettings
:
Settings
?
=
null
,
private
val
runtime
:
GeckoRuntime
=
GeckoRuntime
.
getDefault
(
context
),
executorProvider
:
()
->
GeckoWebExecutor
=
{
GeckoWebExecutor
(
runtime
)
}
executorProvider
:
()
->
GeckoWebExecutor
=
{
GeckoWebExecutor
(
runtime
)
},
override
val
trackingProtectionExceptionStore
:
TrackingProtectionExceptionStorage
=
TrackingProtectionExceptionFileStorage
(
context
,
runtime
)
)
:
Engine
{
private
val
executor
by
lazy
{
executorProvider
.
invoke
()
}
private
val
localeUpdater
=
LocaleSettingUpdater
(
context
,
runtime
)
init
{
...
...
@@ -56,6 +58,7 @@ class GeckoEngine(
@Suppress
(
"TooGenericExceptionThrown"
)
throw
RuntimeException
(
"GeckoRuntime is shutting down"
)
}
trackingProtectionExceptionStore
.
restore
()
}
/**
...
...
components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/TrackingProtectionExceptionFileStorage.kt
0 → 100644
View file @
976349ba
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package
mozilla.components.browser.engine.gecko
import
android.content.Context
import
android.util.AtomicFile
import
androidx.annotation.VisibleForTesting
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
import
mozilla.components.concept.engine.EngineSession
import
mozilla.components.concept.engine.content.blocking.TrackingProtectionExceptionStorage
import
mozilla.components.support.ktx.util.readAndDeserialize
import
mozilla.components.support.ktx.util.writeString
import
org.mozilla.geckoview.GeckoRuntime
import
java.io.File
private
const
val
STORE_FILE_NAME_FORMAT
=
"mozilla_components_tracking_protection_storage_gecko.json"
/**
* A [TrackingProtectionExceptionStorage] implementation to store tracking protection exceptions.
*/
internal
class
TrackingProtectionExceptionFileStorage
(
private
val
context
:
Context
,
private
val
runtime
:
GeckoRuntime
)
:
TrackingProtectionExceptionStorage
{
private
val
fileLock
=
Any
()
internal
var
scope
=
CoroutineScope
(
Dispatchers
.
IO
)
/**
* Restore all exceptions from the [STORE_FILE_NAME_FORMAT] file,
* and provides them to the gecko [runtime].
*/
override
fun
restore
()
{
scope
.
launch
{
synchronized
(
fileLock
)
{
getFile
(
context
).
readAndDeserialize
{
json
->
if
(
json
.
isNotEmpty
())
{
val
exceptionList
=
runtime
.
contentBlockingController
.
ExceptionList
(
json
)
runtime
.
contentBlockingController
.
restoreExceptionList
(
exceptionList
)
}
}
}
}
}
override
fun
contains
(
session
:
EngineSession
,
onResult
:
(
Boolean
)
->
Unit
)
{
val
geckoSession
=
(
session
as
GeckoEngineSession
).
geckoSession
runtime
.
contentBlockingController
.
checkException
(
geckoSession
).
accept
{
if
(
it
!=
null
)
{
onResult
(
it
)
}
else
{
onResult
(
false
)
}
}
}
override
fun
fetchAll
(
onResult
:
(
List
<
String
>)
->
Unit
)
{
runtime
.
contentBlockingController
.
saveExceptionList
().
accept
{
exceptionList
->
val
exceptions
=
if
(
exceptionList
!=
null
)
{
val
uris
=
exceptionList
.
uris
.
map
{
uri
->
uri
}
uris
}
else
{
emptyList
()
}
onResult
(
exceptions
)
}
}
override
fun
add
(
session
:
EngineSession
)
{
val
geckoSession
=
(
session
as
GeckoEngineSession
).
geckoSession
runtime
.
contentBlockingController
.
addException
(
geckoSession
)
persist
()
}
override
fun
remove
(
session
:
EngineSession
)
{
val
geckoSession
=
(
session
as
GeckoEngineSession
).
geckoSession
runtime
.
contentBlockingController
.
removeException
(
geckoSession
)
persist
()
}
override
fun
removeAll
()
{
runtime
.
contentBlockingController
.
clearExceptionList
()
removeFileFromDisk
(
context
)
}