import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import androidx.viewpager.widget.ViewPager
+import androidx.viewpager2.widget.ViewPager2
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
import com.google.android.material.tabs.TabLayout
import com.stoutner.privacybrowser.R
-import com.stoutner.privacybrowser.adapters.WebViewPagerAdapter
+import com.stoutner.privacybrowser.adapters.WebViewStateAdapter
import com.stoutner.privacybrowser.coroutines.GetHostIpAddressesCoroutine
-import com.stoutner.privacybrowser.coroutines.PopulateBlocklistsCoroutine
+import com.stoutner.privacybrowser.coroutines.PopulateFilterListsCoroutine
import com.stoutner.privacybrowser.coroutines.PrepareSaveDialogCoroutine
import com.stoutner.privacybrowser.coroutines.SaveUrlCoroutine
import com.stoutner.privacybrowser.coroutines.SaveWebpageImageCoroutine
import com.stoutner.privacybrowser.helpers.REQUEST_DEFAULT
import com.stoutner.privacybrowser.helpers.REQUEST_THIRD_PARTY
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper
-import com.stoutner.privacybrowser.helpers.CheckBlocklistHelper
+import com.stoutner.privacybrowser.helpers.CheckFilterListHelper
import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper
import com.stoutner.privacybrowser.helpers.ProxyHelper
import com.stoutner.privacybrowser.helpers.SanitizeUrlHelper
private const val TEMPORARY_MHT_FILE = "temporary_mht_file"
class MainWebViewActivity : AppCompatActivity(), CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, FontSizeDialog.UpdateFontSizeListener,
- NavigationView.OnNavigationItemSelectedListener, OpenDialog.OpenListener, PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklistsCoroutine.PopulateBlocklistsListener, SaveDialog.SaveListener,
+ NavigationView.OnNavigationItemSelectedListener, OpenDialog.OpenListener, PinnedMismatchDialog.PinnedMismatchListener, PopulateFilterListsCoroutine.PopulateFilterListsListener, SaveDialog.SaveListener,
UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener {
companion object {
val pendingDialogsArrayList = ArrayList<PendingDialogDataClass>()
var proxyMode = ProxyHelper.NONE
var restartFromBookmarksActivity = false
- var webViewPagerAdapter: WebViewPagerAdapter? = null
+ var webViewStateAdapter: WebViewStateAdapter? = null
// Declare the public static variables.
lateinit var appBarLayout: AppBarLayout
// Declare the class variables.
private lateinit var appBar: ActionBar
- private lateinit var checkBlocklistHelper: CheckBlocklistHelper
+ private lateinit var checkFilterListHelper: CheckFilterListHelper
private lateinit var bookmarksCursorAdapter: CursorAdapter
private lateinit var bookmarksListView: ListView
private lateinit var bookmarksDrawerPinnedImageView: ImageView
private lateinit var navigationRequestsMenuItem: MenuItem
private lateinit var optionsAddOrEditDomainMenuItem: MenuItem
private lateinit var optionsBlockAllThirdPartyRequestsMenuItem: MenuItem
- private lateinit var optionsBlocklistsMenuItem: MenuItem
private lateinit var optionsClearCookiesMenuItem: MenuItem
private lateinit var optionsClearDataMenuItem: MenuItem
private lateinit var optionsClearDomStorageMenuItem: MenuItem
private lateinit var optionsEasyPrivacyMenuItem: MenuItem
private lateinit var optionsFanboysAnnoyanceListMenuItem: MenuItem
private lateinit var optionsFanboysSocialBlockingListMenuItem: MenuItem
+ private lateinit var optionsFilterListsMenuItem: MenuItem
private lateinit var optionsFontSizeMenuItem: MenuItem
private lateinit var optionsPrivacyMenuItem: MenuItem
private lateinit var optionsProxyCustomMenuItem: MenuItem
private lateinit var tabsLinearLayout: LinearLayout
private lateinit var toolbar: Toolbar
private lateinit var webViewDefaultUserAgent: String
- private lateinit var webViewPager: ViewPager
+ private lateinit var webViewViewPager2: ViewPager2
private lateinit var ultraList: ArrayList<List<Array<String>>>
private lateinit var urlEditText: EditText
private lateinit var urlRelativeLayout: RelativeLayout
// Do not continue if the app theme is different than the OS theme. The app always initially starts in the OS theme.
// If the user has specified the opposite theme should be used, the app will restart in that mode after the above `setDefaultNightMode()` code processes. However, the restart is delayed.
- // If the blacklist coroutine starts below it will continue to run during the restart, which leads to indeterminate behavior, with the system often not knowing how many tabs exist.
+ // If the filter list coroutine starts below it will continue to run during the restart, which leads to indeterminate behavior, with the system often not knowing how many tabs exist.
// See https://redmine.stoutner.com/issues/952.
if ((appTheme == appThemeEntryValuesStringArray[0]) || // The system default theme is used.
((appTheme == appThemeEntryValuesStringArray[1]) && (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO)) || // The app is running in day theme as desired.
tabsLinearLayout = findViewById(R.id.tabs_linearlayout)
tabLayout = findViewById(R.id.tablayout)
swipeRefreshLayout = findViewById(R.id.swiperefreshlayout)
- webViewPager = findViewById(R.id.webviewpager)
+ webViewViewPager2 = findViewById(R.id.webview_viewpager2)
val navigationView = findViewById<NavigationView>(R.id.navigationview)
bookmarksListView = findViewById(R.id.bookmarks_drawer_listview)
bookmarksTitleTextView = findViewById(R.id.bookmarks_title_textview)
// Create the hamburger icon at the start of the AppBar.
actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer)
- // Initially disable the sliding drawers. They will be enabled once the blocklists are loaded.
+ // Initially disable the sliding drawers. They will be enabled once the filter lists are loaded.
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
- // Initially hide the user interface so that only the blocklist loading screen is shown (if reloading).
+ // Initially hide the user interface so that only the filter list loading screen is shown (if reloading).
drawerLayout.visibility = View.GONE
- // Initialize the WebView pager adapter.
- webViewPagerAdapter = WebViewPagerAdapter(supportFragmentManager)
+ // Initialize the WebView state adapter.
+ webViewStateAdapter = WebViewStateAdapter(this)
// Set the pager adapter on the web view pager.
- webViewPager.adapter = webViewPagerAdapter
+ webViewViewPager2.adapter = webViewStateAdapter
// Store up to 100 tabs in memory.
- webViewPager.offscreenPageLimit = 100
+ webViewViewPager2.offscreenPageLimit = 100
+
+ // Disable swiping between pages in the view pager.
+ webViewViewPager2.isUserInputEnabled = false
// Get a handle for the cookie manager.
cookieManager = CookieManager.getInstance()
// Register the on back pressed callback.
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
- // Instantiate the populate blocklists coroutine.
- val populateBlocklistsCoroutine = PopulateBlocklistsCoroutine(this)
+ // Instantiate the populate filter lists coroutine.
+ val populateFilterListsCoroutine = PopulateFilterListsCoroutine(this)
- // Populate the blocklists.
- populateBlocklistsCoroutine.populateBlocklists(this)
+ // Populate the filter lists.
+ populateFilterListsCoroutine.populateFilterLists(this)
}
}
updateDomainsSettingsSet()
// Reapply the domain settings for each tab.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
// Run the default commands.
super.onStart()
- // Resume any WebViews if the pager adapter exists. If the app is restarting to change the initial app theme it won't have been populated yet.
- if (webViewPagerAdapter != null) {
- for (i in 0 until webViewPagerAdapter!!.count) {
+ // Resume any WebViews if the state adapter exists. If the app is restarting to change the initial app theme it won't have been populated yet.
+ if (webViewStateAdapter != null) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
// Run the default commands.
super.onSaveInstanceState(savedInstanceState)
- // Only save the instance state if the WebView pager adapter is not null, which will be the case if the app is restarting to change the initial app theme.
- if (webViewPagerAdapter != null) {
+ // Only save the instance state if the WebView state adapter is not null, which will be the case if the app is restarting to change the initial app theme.
+ if (webViewStateAdapter != null) {
// Initialize the saved state array lists.
savedStateArrayList = ArrayList<Bundle>()
savedNestedScrollWebViewStateArrayList = ArrayList<Bundle>()
// Get the URLs from each tab.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
// Run the default commands.
super.onStop()
- // Only pause the WebViews if the pager adapter is not null, which is the case if the app is restarting to change the initial app theme.
- if (webViewPagerAdapter != null) {
+ // Only pause the WebViews if the state adapter is not null, which is the case if the app is restarting to change the initial app theme.
+ if (webViewStateAdapter != null) {
// Pause each web view.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
optionsClearCookiesMenuItem = menu.findItem(R.id.clear_cookies)
optionsClearDomStorageMenuItem = menu.findItem(R.id.clear_dom_storage)
optionsClearFormDataMenuItem = menu.findItem(R.id.clear_form_data) // Form data can be removed once the minimum API >= 26.
- optionsBlocklistsMenuItem = menu.findItem(R.id.blocklists)
optionsEasyListMenuItem = menu.findItem(R.id.easylist)
optionsEasyPrivacyMenuItem = menu.findItem(R.id.easyprivacy)
optionsFanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list)
optionsFanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list)
+ optionsFilterListsMenuItem = menu.findItem(R.id.filterlists)
optionsUltraListMenuItem = menu.findItem(R.id.ultralist)
optionsUltraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy)
optionsBlockAllThirdPartyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests)
optionsWideViewportMenuItem.isChecked = currentWebView!!.settings.useWideViewPort
optionsDisplayImagesMenuItem.isChecked = currentWebView!!.settings.loadsImagesAutomatically
- // Initialize the display names for the blocklists with the number of blocked requests.
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + currentWebView!!.getRequestsCount(BLOCKED_REQUESTS)
+ // Initialize the display names for the filter lists with the number of blocked requests.
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + currentWebView!!.getRequestsCount(BLOCKED_REQUESTS)
optionsEasyListMenuItem.title = currentWebView!!.getRequestsCount(EASYLIST).toString() + " - " + getString(R.string.easylist)
optionsEasyPrivacyMenuItem.title = currentWebView!!.getRequestsCount(EASYPRIVACY).toString() + " - " + getString(R.string.easyprivacy)
optionsFanboysAnnoyanceListMenuItem.title = currentWebView!!.getRequestsCount(FANBOYS_ANNOYANCE_LIST).toString() + " - " + getString(R.string.fanboys_annoyance_list)
// Display a snackbar.
if (currentWebView!!.settings.javaScriptEnabled) // JavaScrip is enabled.
- Snackbar.make(webViewPager, R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show()
else if (cookieManager.acceptCookie()) // JavaScript is disabled, but cookies are enabled.
- Snackbar.make(webViewPager, R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show()
else // Privacy mode.
- Snackbar.make(webViewPager, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show()
// Reload the current WebView.
currentWebView!!.reload()
// Display a snackbar.
if (cookieManager.acceptCookie()) // Cookies are enabled.
- Snackbar.make(webViewPager, R.string.cookies_enabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.cookies_enabled, Snackbar.LENGTH_SHORT).show()
else if (currentWebView!!.settings.javaScriptEnabled) // JavaScript is still enabled.
- Snackbar.make(webViewPager, R.string.cookies_disabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.cookies_disabled, Snackbar.LENGTH_SHORT).show()
else // Privacy mode.
- Snackbar.make(webViewPager, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.privacy_mode, Snackbar.LENGTH_SHORT).show()
// Reload the current WebView.
currentWebView!!.reload()
// Display a snackbar.
if (currentWebView!!.settings.domStorageEnabled)
- Snackbar.make(webViewPager, R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show()
else
- Snackbar.make(webViewPager, R.string.dom_storage_disabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.dom_storage_disabled, Snackbar.LENGTH_SHORT).show()
// Reload the current WebView.
currentWebView!!.reload()
// Display a snackbar.
@Suppress("DEPRECATION")
if (currentWebView!!.settings.saveFormData)
- Snackbar.make(webViewPager, R.string.form_data_enabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.form_data_enabled, Snackbar.LENGTH_SHORT).show()
else
- Snackbar.make(webViewPager, R.string.form_data_disabled, Snackbar.LENGTH_SHORT).show()
+ Snackbar.make(webViewViewPager2, R.string.form_data_disabled, Snackbar.LENGTH_SHORT).show()
// Update the privacy icon.
updatePrivacyIcons(true)
R.id.clear_cookies -> { // Clear cookies.
// Create a snackbar.
- Snackbar.make(webViewPager, R.string.cookies_deleted, Snackbar.LENGTH_LONG)
+ Snackbar.make(webViewViewPager2, R.string.cookies_deleted, Snackbar.LENGTH_LONG)
.setAction(R.string.undo) {} // Everything will be handled by `onDismissed()` below.
.addCallback(object : Snackbar.Callback() {
override fun onDismissed(snackbar: Snackbar, event: Int) {
R.id.clear_dom_storage -> { // Clear DOM storage.
// Create a snackbar.
- Snackbar.make(webViewPager, R.string.dom_storage_deleted, Snackbar.LENGTH_LONG)
+ Snackbar.make(webViewViewPager2, R.string.dom_storage_deleted, Snackbar.LENGTH_LONG)
.setAction(R.string.undo) {} // Everything will be handled by `onDismissed()` below.
.addCallback(object : Snackbar.Callback() {
override fun onDismissed(snackbar: Snackbar, event: Int) {
R.id.clear_form_data -> { // Clear form data. This can be remove once the minimum API >= 26.
// Create a snackbar.
- Snackbar.make(webViewPager, R.string.form_data_deleted, Snackbar.LENGTH_LONG)
+ Snackbar.make(webViewViewPager2, R.string.form_data_deleted, Snackbar.LENGTH_LONG)
.setAction(R.string.undo) {} // Everything will be handled by `onDismissed()` below.
.addCallback(object : Snackbar.Callback() {
override fun onDismissed(snackbar: Snackbar, event: Int) {
// Create an intent to launch the about activity.
val aboutIntent = Intent(this, AboutActivity::class.java)
- // Create a string array for the blocklist versions.
- val blocklistVersions = arrayOf(easyList[0][0][0], easyPrivacy[0][0][0], fanboysAnnoyanceList[0][0][0], fanboysSocialList[0][0][0], ultraList[0][0][0], ultraPrivacy!![0][0][0])
+ // Create a string array for the filter list versions.
+ val filterListVersions = arrayOf(easyList[0][0][0], easyPrivacy[0][0][0], fanboysAnnoyanceList[0][0][0], fanboysSocialList[0][0][0], ultraList[0][0][0], ultraPrivacy!![0][0][0])
- // Add the blocklist versions to the intent.
- aboutIntent.putExtra(AboutActivity.BLOCKLIST_VERSIONS, blocklistVersions)
+ // Add the filter list versions to the intent.
+ aboutIntent.putExtra(FILTERLIST_VERSIONS, filterListVersions)
// Make it so.
startActivity(aboutIntent)
newTab.setCustomView(R.layout.tab_custom_view)
// Add the new WebView page.
- webViewPagerAdapter!!.addPage(newTabNumber, webViewPager, urlString, moveToTab)
+ webViewStateAdapter!!.addPage(newTabNumber, webViewViewPager2, urlString, moveToTab)
// Show the app bar if it is at the bottom of the screen and the new tab is taking focus.
if (bottomAppBar && moveToTab && appBarLayout.translationY != 0f) {
}
// Set the app bar scrolling for each WebView.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
nestedScrollWebView.initializeFavoriteIcon()
// Get the current page position.
- val currentPagePosition = webViewPagerAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
+ val currentPagePosition = webViewStateAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
// Get the corresponding tab.
val tab = tabLayout.getTabAt(currentPagePosition)
ProxyHelper.TOR -> {
// Set the app bar background to indicate proxying is enabled.
- appBarLayout.setBackgroundResource(R.color.proxy_appbar_background)
+ appBarLayout.setBackgroundResource(R.color.blue_background)
// Check to see if Orbot is installed.
try {
ProxyHelper.I2P -> {
// Set the app bar background to indicate proxying is enabled.
- appBarLayout.setBackgroundResource(R.color.proxy_appbar_background)
+ appBarLayout.setBackgroundResource(R.color.blue_background)
// Check to see if I2P is installed.
try {
ProxyHelper.CUSTOM ->
// Set the app bar background to indicate proxying is enabled.
- appBarLayout.setBackgroundResource(R.color.proxy_appbar_background)
+ appBarLayout.setBackgroundResource(R.color.blue_background)
}
// Reload the WebViews if requested and not waiting for the proxy.
if (reloadWebViews && !waitingForProxy) {
// Reload the WebViews.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
// Clear the cache.
if (clearEverything || sharedPreferences.getBoolean(getString(R.string.clear_cache_key), true)) {
// Clear the cache from each WebView.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the WebView fragment view.
val webViewFragmentView = webViewTabFragment.view
}
// Wipe out each WebView.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the WebView frame layout.
val webViewFrameLayout = webViewTabFragment.view as FrameLayout?
// Delete the current page. If the selected page number did not change during the delete (because the newly selected tab has has same number as the previously deleted tab), it will return true,
// meaning that the current WebView must be reset. Otherwise it will happen automatically as the selected tab number changes.
- if (webViewPagerAdapter!!.deletePage(currentTabNumber, webViewPager))
+ if (webViewStateAdapter!!.deletePage(currentTabNumber, webViewViewPager2))
setCurrentWebView(currentTabNumber)
} else { // There is only one tab open.
clearAndExit()
currentWebView!!.findNext(false)
}
- override fun finishedPopulatingBlocklists(combinedBlocklists: ArrayList<ArrayList<List<Array<String>>>>) {
- // Store the blocklists.
- easyList = combinedBlocklists[0]
- easyPrivacy = combinedBlocklists[1]
- fanboysAnnoyanceList = combinedBlocklists[2]
- fanboysSocialList = combinedBlocklists[3]
- ultraList = combinedBlocklists[4]
- ultraPrivacy = combinedBlocklists[5]
+ override fun finishedPopulatingFilterLists(combinedFilterLists: ArrayList<ArrayList<List<Array<String>>>>) {
+ // Store the filter lists.
+ easyList = combinedFilterLists[0]
+ easyPrivacy = combinedFilterLists[1]
+ fanboysAnnoyanceList = combinedFilterLists[2]
+ fanboysSocialList = combinedFilterLists[3]
+ ultraList = combinedFilterLists[4]
+ ultraPrivacy = combinedFilterLists[5]
// Check to see if the activity has been restarted with a saved state.
if ((savedStateArrayList == null) || (savedStateArrayList!!.size == 0)) { // The activity has not been restarted or it was restarted on start to change the theme.
// Add the first tab.
- addNewTab("", true)
+ addNewTab("", false)
} else { // The activity has been restarted.
// Restore each tab.
for (i in savedStateArrayList!!.indices) {
newTab.setCustomView(R.layout.tab_custom_view)
// Add the new page.
- webViewPagerAdapter!!.restorePage(savedStateArrayList!![i], savedNestedScrollWebViewStateArrayList!![i])
+ webViewStateAdapter!!.restorePage(savedStateArrayList!![i], savedNestedScrollWebViewStateArrayList!![i])
}
// Reset the saved state variables.
setCurrentWebView(0)
} else { // The first tab is not selected.
// Move to the selected tab.
- webViewPager.currentItem = savedTabPosition
+ webViewViewPager2.currentItem = savedTabPosition
}
// Get the intent that started the app.
}
// Reload existing URLs and load any URLs that are waiting for the proxy.
- for (i in 0 until webViewPagerAdapter!!.count) {
+ for (i in 0 until webViewStateAdapter!!.itemCount) {
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(i)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(i)
// Get the fragment view.
val fragmentView = webViewTabFragment.view
val createBookmarkFab = findViewById<FloatingActionButton>(R.id.create_bookmark_fab)
// Update the WebView pager every time a tab is modified.
- webViewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
-
+ webViewViewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
// Close the find on page bar if it is open.
closeFindOnPage(null)
}
}
}
-
- override fun onPageScrollStateChanged(state: Int) {}
})
// Handle tab selections.
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
// Select the same page in the view pager.
- webViewPager.currentItem = tab.position
+ webViewViewPager2.currentItem = tab.position
}
override fun onTabUnselected(tab: TabLayout.Tab) {}
// Update the domains settings set.
updateDomainsSettingsSet()
- // Instantiate the check blocklist helper.
- checkBlocklistHelper = CheckBlocklistHelper()
+ // Instantiate the check filter list helper.
+ checkFilterListHelper = CheckFilterListHelper()
}
@SuppressLint("ClickableViewAccessibility")
nestedScrollWebView.setFavoriteIcon(icon)
// Get the current page position.
- val currentPosition = webViewPagerAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
+ val currentPosition = webViewStateAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
// Get the current tab.
val tab = tabLayout.getTabAt(currentPosition)
// Save a copy of the title when it changes.
override fun onReceivedTitle(view: WebView, title: String) {
// Get the current page position.
- val currentPosition = webViewPagerAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
+ val currentPosition = webViewStateAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
// Get the current tab.
val tab = tabLayout.getTabAt(currentPosition)
return null
}
- // Wait until the blocklists have been populated. When Privacy Browser is being resumed after having the process killed in the background it will try to load the URLs immediately.
+ // Wait until the filter lists have been populated. When Privacy Browser is being resumed after having the process killed in the background it will try to load the URLs immediately.
while (ultraPrivacy == null) {
try {
- // Check to see if the blocklists have been populated after 100 ms.
+ // Check to see if the filter lists have been populated after 100 ms.
Thread.sleep(100)
} catch (exception: InterruptedException) {
// Do nothing.
val emptyWebResourceResponse = WebResourceResponse("text/plain", "utf8", ByteArrayInputStream("".toByteArray()))
// Initialize the variables.
- var whitelistResultStringArray: Array<String>? = null
+ var allowListResultStringArray: Array<String>? = null
var isThirdPartyRequest = false
// Get the current URL. `.getUrl()` throws an error because operations on the WebView cannot be made from this thread.
}
// Get the current WebView page position.
- val webViewPagePosition = webViewPagerAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
+ val webViewPagePosition = webViewStateAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
// Determine if the WebView is currently displayed.
- val webViewDisplayed = webViewPagePosition == tabLayout.selectedTabPosition
+ val webViewDisplayed = (webViewPagePosition == tabLayout.selectedTabPosition)
// Block third-party requests if enabled.
if (isThirdPartyRequest && nestedScrollWebView.blockAllThirdPartyRequests) {
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(THIRD_PARTY_REQUESTS)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsBlockAllThirdPartyRequestsMenuItem.title =
nestedScrollWebView.getRequestsCount(THIRD_PARTY_REQUESTS).toString() + " - " + getString(R.string.block_all_third_party_requests)
}
// Check UltraList if it is enabled.
if (nestedScrollWebView.ultraListEnabled) {
// Check the URL against UltraList.
- val ultraListResults = checkBlocklistHelper.checkBlocklist(currentDomain, requestUrlString, isThirdPartyRequest, ultraList)
+ val ultraListResults = checkFilterListHelper.checkFilterList(currentDomain, requestUrlString, isThirdPartyRequest, ultraList)
// Process the UltraList results.
- if (ultraListResults[0] == REQUEST_BLOCKED) { // The resource request matched UltraList's blacklist.
+ if (ultraListResults[0] == REQUEST_BLOCKED) { // The resource request matched UltraList's block list.
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(arrayOf(ultraListResults[0], ultraListResults[1], ultraListResults[2], ultraListResults[3], ultraListResults[4], ultraListResults[5]))
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(ULTRALIST)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsUltraListMenuItem.title = nestedScrollWebView.getRequestsCount(ULTRALIST).toString() + " - " + getString(R.string.ultralist)
}
}
// The resource request was blocked. Return an empty web resource response.
return emptyWebResourceResponse
- } else if (ultraListResults[0] == REQUEST_ALLOWED) { // The resource request matched UltraList's whitelist.
- // Add a whitelist entry to the resource requests array.
+ } else if (ultraListResults[0] == REQUEST_ALLOWED) { // The resource request matched UltraList's allow list.
+ // Add an allow list entry to the resource requests array.
nestedScrollWebView.addResourceRequest(arrayOf(ultraListResults[0], ultraListResults[1], ultraListResults[2], ultraListResults[3], ultraListResults[4], ultraListResults[5]))
- // The resource request has been allowed by UltraPrivacy. `return null` loads the requested resource.
+ // The resource request has been allowed by UltraList. `return null` loads the requested resource.
return null
}
}
// Check UltraPrivacy if it is enabled.
if (nestedScrollWebView.ultraPrivacyEnabled) {
// Check the URL against UltraPrivacy.
- val ultraPrivacyResults = checkBlocklistHelper.checkBlocklist(currentDomain, requestUrlString, isThirdPartyRequest, ultraPrivacy!!)
+ val ultraPrivacyResults = checkFilterListHelper.checkFilterList(currentDomain, requestUrlString, isThirdPartyRequest, ultraPrivacy!!)
// Process the UltraPrivacy results.
- if (ultraPrivacyResults[0] == REQUEST_BLOCKED) { // The resource request matched UltraPrivacy's blacklist.
+ if (ultraPrivacyResults[0] == REQUEST_BLOCKED) { // The resource request matched UltraPrivacy's block list.
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(arrayOf(ultraPrivacyResults[0], ultraPrivacyResults[1], ultraPrivacyResults[2], ultraPrivacyResults[3], ultraPrivacyResults[4],
ultraPrivacyResults[5]))
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(ULTRAPRIVACY)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsUltraPrivacyMenuItem.title = nestedScrollWebView.getRequestsCount(ULTRAPRIVACY).toString() + " - " + getString(R.string.ultraprivacy)
}
}
// The resource request was blocked. Return an empty web resource response.
return emptyWebResourceResponse
- } else if (ultraPrivacyResults[0] == REQUEST_ALLOWED) { // The resource request matched UltraPrivacy's whitelist.
- // Add a whitelist entry to the resource requests array.
+ } else if (ultraPrivacyResults[0] == REQUEST_ALLOWED) { // The resource request matched UltraPrivacy's allow list.
+ // Add an allow list entry to the resource requests array.
nestedScrollWebView.addResourceRequest(arrayOf(ultraPrivacyResults[0], ultraPrivacyResults[1], ultraPrivacyResults[2], ultraPrivacyResults[3], ultraPrivacyResults[4],
ultraPrivacyResults[5]))
// Check EasyList if it is enabled.
if (nestedScrollWebView.easyListEnabled) {
// Check the URL against EasyList.
- val easyListResults = checkBlocklistHelper.checkBlocklist(currentDomain, requestUrlString, isThirdPartyRequest, easyList)
+ val easyListResults = checkFilterListHelper.checkFilterList(currentDomain, requestUrlString, isThirdPartyRequest, easyList)
// Process the EasyList results.
- if (easyListResults[0] == REQUEST_BLOCKED) { // The resource request matched EasyList's blacklist.
+ if (easyListResults[0] == REQUEST_BLOCKED) { // The resource request matched EasyList's block list.
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(arrayOf(easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5]))
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(EASYLIST)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsEasyListMenuItem.title = nestedScrollWebView.getRequestsCount(EASYLIST).toString() + " - " + getString(R.string.easylist)
}
}
// The resource request was blocked. Return an empty web resource response.
return emptyWebResourceResponse
- } else if (easyListResults[0] == REQUEST_ALLOWED) { // The resource request matched EasyList's whitelist.
- // Update the whitelist result string array tracker.
- whitelistResultStringArray = arrayOf(easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5])
+ } else if (easyListResults[0] == REQUEST_ALLOWED) { // The resource request matched EasyList's allow list.
+ // Update the allow list result string array tracker.
+ allowListResultStringArray = arrayOf(easyListResults[0], easyListResults[1], easyListResults[2], easyListResults[3], easyListResults[4], easyListResults[5])
}
}
// Check EasyPrivacy if it is enabled.
if (nestedScrollWebView.easyPrivacyEnabled) {
// Check the URL against EasyPrivacy.
- val easyPrivacyResults = checkBlocklistHelper.checkBlocklist(currentDomain, requestUrlString, isThirdPartyRequest, easyPrivacy)
+ val easyPrivacyResults = checkFilterListHelper.checkFilterList(currentDomain, requestUrlString, isThirdPartyRequest, easyPrivacy)
// Process the EasyPrivacy results.
- if (easyPrivacyResults[0] == REQUEST_BLOCKED) { // The resource request matched EasyPrivacy's blacklist.
+ if (easyPrivacyResults[0] == REQUEST_BLOCKED) { // The resource request matched EasyPrivacy's block list.
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(arrayOf(easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4], easyPrivacyResults[5]))
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(EASYPRIVACY)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsEasyPrivacyMenuItem.title = nestedScrollWebView.getRequestsCount(EASYPRIVACY).toString() + " - " + getString(R.string.easyprivacy)
}
}
// The resource request was blocked. Return an empty web resource response.
return emptyWebResourceResponse
- } else if (easyPrivacyResults[0] == REQUEST_ALLOWED) { // The resource request matched EasyPrivacy's whitelist.
- // Update the whitelist result string array tracker.
- whitelistResultStringArray = arrayOf(easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4], easyPrivacyResults[5])
+ } else if (easyPrivacyResults[0] == REQUEST_ALLOWED) { // The resource request matched EasyPrivacy's allow list.
+ // Update the allow list result string array tracker.
+ allowListResultStringArray = arrayOf(easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4], easyPrivacyResults[5])
}
}
// Check Fanboy’s Annoyance List if it is enabled.
if (nestedScrollWebView.fanboysAnnoyanceListEnabled) {
// Check the URL against Fanboy's Annoyance List.
- val fanboysAnnoyanceListResults = checkBlocklistHelper.checkBlocklist(currentDomain, requestUrlString, isThirdPartyRequest, fanboysAnnoyanceList)
+ val fanboysAnnoyanceListResults = checkFilterListHelper.checkFilterList(currentDomain, requestUrlString, isThirdPartyRequest, fanboysAnnoyanceList)
// Process the Fanboy's Annoyance List results.
- if (fanboysAnnoyanceListResults[0] == REQUEST_BLOCKED) { // The resource request matched Fanboy's Annoyance List's blacklist.
+ if (fanboysAnnoyanceListResults[0] == REQUEST_BLOCKED) { // The resource request matched Fanboy's Annoyance List's block list.
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(arrayOf(fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3],
fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5]))
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(FANBOYS_ANNOYANCE_LIST)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsFanboysAnnoyanceListMenuItem.title = nestedScrollWebView.getRequestsCount(FANBOYS_ANNOYANCE_LIST).toString() + " - " + getString(R.string.fanboys_annoyance_list)
}
}
// The resource request was blocked. Return an empty web resource response.
return emptyWebResourceResponse
- } else if (fanboysAnnoyanceListResults[0] == REQUEST_ALLOWED) { // The resource request matched Fanboy's Annoyance List's whitelist.
- // Update the whitelist result string array tracker.
- whitelistResultStringArray = arrayOf(fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3],
+ } else if (fanboysAnnoyanceListResults[0] == REQUEST_ALLOWED) { // The resource request matched Fanboy's Annoyance List's allow list.
+ // Update the allow list result string array tracker.
+ allowListResultStringArray = arrayOf(fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3],
fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5])
}
} else if (nestedScrollWebView.fanboysSocialBlockingListEnabled) { // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled.
// Check the URL against Fanboy's Annoyance List.
- val fanboysSocialListResults = checkBlocklistHelper.checkBlocklist(currentDomain, requestUrlString, isThirdPartyRequest, fanboysSocialList)
+ val fanboysSocialListResults = checkFilterListHelper.checkFilterList(currentDomain, requestUrlString, isThirdPartyRequest, fanboysSocialList)
// Process the Fanboy's Social Blocking List results.
- if (fanboysSocialListResults[0] == REQUEST_BLOCKED) { // The resource request matched Fanboy's Social Blocking List's blacklist.
+ if (fanboysSocialListResults[0] == REQUEST_BLOCKED) { // The resource request matched Fanboy's Social Blocking List's block list.
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(arrayOf(fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3],
fanboysSocialListResults[4], fanboysSocialListResults[5]))
nestedScrollWebView.incrementRequestsCount(BLOCKED_REQUESTS)
nestedScrollWebView.incrementRequestsCount(FANBOYS_SOCIAL_BLOCKING_LIST)
- // Update the titles of the blocklist menu items if the WebView is currently displayed.
+ // Update the titles of the filter lists menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Updating the UI must be run from the UI thread.
runOnUiThread {
// Update the options menu if it has been populated.
if (optionsMenu != null) {
- optionsBlocklistsMenuItem.title = getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
+ optionsFilterListsMenuItem.title = getString(R.string.filterlists) + " - " + nestedScrollWebView.getRequestsCount(BLOCKED_REQUESTS)
optionsFanboysSocialBlockingListMenuItem.title =
nestedScrollWebView.getRequestsCount(FANBOYS_SOCIAL_BLOCKING_LIST).toString() + " - " + getString(R.string.fanboys_social_blocking_list)
}
// The resource request was blocked. Return an empty web resource response.
return emptyWebResourceResponse
- } else if (fanboysSocialListResults[0] == REQUEST_ALLOWED) { // The resource request matched Fanboy's Social Blocking List's whitelist.
- // Update the whitelist result string array tracker.
- whitelistResultStringArray = arrayOf(fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3], fanboysSocialListResults[4],
+ } else if (fanboysSocialListResults[0] == REQUEST_ALLOWED) { // The resource request matched Fanboy's Social Blocking List's allow list.
+ // Update the allow list result string array tracker.
+ allowListResultStringArray = arrayOf(fanboysSocialListResults[0], fanboysSocialListResults[1], fanboysSocialListResults[2], fanboysSocialListResults[3], fanboysSocialListResults[4],
fanboysSocialListResults[5])
}
}
// Add the request to the log because it hasn't been processed by any of the previous checks.
- if (whitelistResultStringArray != null) { // The request was processed by a whitelist.
- nestedScrollWebView.addResourceRequest(whitelistResultStringArray)
- } else { // The request didn't match any blocklist entry. Log it as a default request.
+ if (allowListResultStringArray != null) { // The request was processed by an allow list.
+ nestedScrollWebView.addResourceRequest(allowListResultStringArray)
+ } else { // The request didn't match any filter list entry. Log it as a default request.
nestedScrollWebView.addResourceRequest(arrayOf(REQUEST_DEFAULT, requestUrlString))
}
nestedScrollWebView.resetRequestsCounters()
// Get the current page position.
- val currentPagePosition = webViewPagerAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
+ val currentPagePosition = webViewStateAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
// Update the URL text bar if the page is currently selected and the URL edit text is not currently being edited.
if ((tabLayout.selectedTabPosition == currentPagePosition) && !urlEditText.hasFocus()) {
val currentDomainName = currentUri.host
// Get the IP addresses for the current domain.
- if ((currentDomainName != null) && currentDomainName.isNotEmpty())
+ if (!currentDomainName.isNullOrEmpty())
GetHostIpAddressesCoroutine.checkPinnedMismatch(currentDomainName, nestedScrollWebView, supportFragmentManager, getString(R.string.pinned_mismatch))
// Replace Refresh with Stop if the options menu has been created and the WebView is currently displayed. (The first WebView typically begins loading before the menu items are instantiated.)
}
// Get the current page position.
- val currentPagePosition = webViewPagerAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
+ val currentPagePosition = webViewStateAdapter!!.getPositionForId(nestedScrollWebView.webViewFragmentId)
// Get the current URL from the nested scroll WebView. This is more accurate than using the URL passed into the method, which is sometimes not the final one.
val currentUrl = nestedScrollWebView.url
swipeRefreshLayout.isRefreshing = false
// Get the WebView tab fragment.
- val webViewTabFragment = webViewPagerAdapter!!.getPageFragment(pageNumber)
+ val webViewTabFragment = webViewStateAdapter!!.getPageFragment(pageNumber)
// Get the fragment view.
val webViewFragmentView = webViewTabFragment.view
// Remove any background on the URL relative layout.
urlRelativeLayout.background = AppCompatResources.getDrawable(this, R.color.transparent)
}
- } else if (pageNumber == savedTabPosition) { // The app is being restored but the saved tab position fragment has not been populated yet. Try again in 100 milliseconds.
+ } else if ((pageNumber == savedTabPosition) || (pageNumber == (webViewStateAdapter!!.itemCount - 1))) { // The tab has not been populated yet.
+ // Try again in 100 milliseconds if the app is being restored or the a new tab has been added (the last tab).
// Create a handler to set the current WebView.
val setCurrentWebViewHandler = Handler(Looper.getMainLooper())