... |
... |
@@ -8,9 +8,13 @@ import android.app.Application |
8
|
8
|
import android.util.Log
|
9
|
9
|
import androidx.lifecycle.AndroidViewModel
|
10
|
10
|
import androidx.lifecycle.MutableLiveData
|
|
11
|
+import androidx.lifecycle.viewModelScope
|
|
12
|
+import kotlinx.coroutines.Dispatchers
|
11
|
13
|
import kotlinx.coroutines.flow.MutableStateFlow
|
12
|
14
|
import kotlinx.coroutines.flow.StateFlow
|
|
15
|
+import kotlinx.coroutines.launch
|
13
|
16
|
import mozilla.components.browser.state.ext.getUrl
|
|
17
|
+import mozilla.components.browser.state.state.recover.TabState
|
14
|
18
|
import org.mozilla.fenix.HomeActivity
|
15
|
19
|
import org.mozilla.fenix.R
|
16
|
20
|
import org.mozilla.fenix.ext.components
|
... |
... |
@@ -30,22 +34,38 @@ class TorConnectionAssistViewModel( |
30
|
34
|
|
31
|
35
|
init {
|
32
|
36
|
torAndroidIntegration.registerBootstrapStateChangeListener(this)
|
33
|
|
- loadDummyPage()
|
34
|
|
- }
|
35
|
|
-
|
36
|
|
- private fun loadDummyPage() {
|
37
|
|
- // Load local url (it just needs to begin with "about:" to get past filter) to initialize the browser,
|
38
|
|
- // Domain fronting needs Services.io.getProtocolHandler("http")... to actually work, and it
|
39
|
|
- // does not till the browser/engine is initialized, and this is so far the easiest way to do that.
|
40
|
|
- // Load early here so that it is ready when needed if we get to the step where DF is invoked
|
41
|
|
- // Then later remove it in onCleared so it doesn't show for the user
|
42
|
|
- components.useCases.tabsUseCases.addTab.invoke("about:")
|
|
37
|
+ loadAndUnloadDummyPage()
|
|
38
|
+ }
|
|
39
|
+
|
|
40
|
+ private fun loadAndUnloadDummyPage() {
|
|
41
|
+ viewModelScope.launch(Dispatchers.IO) {
|
|
42
|
+ // Load local url (it just needs to begin with "about:" to get past filter) to initialize the browser,
|
|
43
|
+ // Domain fronting needs Services.io.getProtocolHandler("http")... to actually work, and it
|
|
44
|
+ // does not till the browser/engine is initialized, and this is so far the easiest way to do that.
|
|
45
|
+ // Load early here so that it is ready when needed if we get to the step where DF is invoked
|
|
46
|
+ // Then later remove it so it doesn't show for the user
|
|
47
|
+ components.useCases.tabsUseCases.addTab.invoke("about:")
|
|
48
|
+ // removeTabs doesn't work without a delay.
|
|
49
|
+ Thread.sleep(500)
|
|
50
|
+ // Remove loaded URL so it is never visible to the user
|
|
51
|
+ components.useCases.tabsUseCases.removeTabs.invoke(
|
|
52
|
+ components.core.store.state.tabs.filter {
|
|
53
|
+ it.getUrl() == "about:" || it.getUrl() == "about:blank"
|
|
54
|
+ }.map { it.id },
|
|
55
|
+ )
|
|
56
|
+ // recentlyClosedTabsStorage.value.removeAllTabs() doesn't seem to work,
|
|
57
|
+ // so instead we collect and iteratively remove all tabs from recent history.
|
|
58
|
+ // Nothing should ever show up in history so we remove everything,
|
|
59
|
+ // including old "about:" tabs that may have stacked up.
|
|
60
|
+ components.core.recentlyClosedTabsStorage.value.getTabs()
|
|
61
|
+ .collect { tabs: List<TabState> ->
|
|
62
|
+ for (tab in tabs) {
|
|
63
|
+ components.core.recentlyClosedTabsStorage.value.removeTab(tab)
|
|
64
|
+ }
|
|
65
|
+ }
|
|
66
|
+ }
|
43
|
67
|
}
|
44
|
68
|
|
45
|
|
- private fun clearDummyPage() {
|
46
|
|
- // Remove loaded URL so it doesn't show up
|
47
|
|
- components.useCases.tabsUseCases.removeTab.invoke(components.core.store.state.tabs.find {it.getUrl() == "about:"}?.id ?: "")
|
48
|
|
- }
|
49
|
69
|
|
50
|
70
|
fun fetchRegionNames() {
|
51
|
71
|
torAndroidIntegration.regionNamesGet { regionNames : GeckoBundle? ->
|
... |
... |
@@ -63,7 +83,6 @@ class TorConnectionAssistViewModel( |
63
|
83
|
|
64
|
84
|
override fun onCleared() {
|
65
|
85
|
torAndroidIntegration.unregisterBootstrapStateChangeListener(this)
|
66
|
|
- clearDummyPage()
|
67
|
86
|
super.onCleared()
|
68
|
87
|
}
|
69
|
88
|
|