X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.java;h=0e303a2e19524285a14105592994415334df4163;hp=ed0259f21c2805179ec03f36b85c41e19d86e89c;hb=f7abc45b8d69f3f3804397428005b4ffd9a10f99;hpb=b4ad3d976ddc7902546f820df9d8e0e3172b7c69 diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index ed0259f2..0e303a2e 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -225,6 +225,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private boolean hideAppBar; private boolean scrollAppBar; + // The loading new intent tracker is set in `onNewIntent()` and used in `setCurrentWebView()`. + private boolean loadingNewIntent; + // `reapplyDomainSettingsOnRestart` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `onAddDomain()`, . private boolean reapplyDomainSettingsOnRestart; @@ -807,15 +810,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String intentAction = intent.getAction(); Uri intentUriData = intent.getData(); - // Only process the URI if it contains data. If the user pressed the desktop icon after the app was already running the URI will be null. - if (intentUriData != null) { - // Sets the new intent as the activity intent, which replaces the one that originally started the app. - setIntent(intent); + // Determine if this is a web search. + boolean isWebSearch = ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)); + // Only process the URI if it contains data or it is a web search. If the user pressed the desktop icon after the app was already running the URI will be null. + if (intentUriData != null || isWebSearch) { // Get the shared preferences. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + // Add a new tab if specified in the preferences. if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) { + // Set the loading new intent flag. + loadingNewIntent = true; + // Add a new tab. addTab(null); } @@ -824,7 +831,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String url; // If the intent action is a web search, perform the search. - if ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)) { + if (isWebSearch) { // Create an encoded URL string. String encodedUrlString; @@ -2070,20 +2077,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Run the commands that correspond to the selected menu item. switch (menuItemId) { case R.id.close_tab: - // Get a handle for the tab layout and the view pager. - TabLayout tabLayout = findViewById(R.id.tablayout); - ViewPager webViewPager = findViewById(R.id.webviewpager); - - // Get the current tab number. - int currentTabNumber = tabLayout.getSelectedTabPosition(); - - // Delete the current tab. - tabLayout.removeTabAt(currentTabNumber); - - // Delete the current page. If the selected page number did not change during the delete, it will return true, meaning that the current WebView must be reset. - if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) { - setCurrentWebView(currentTabNumber); - } + // Close the current tab. + closeCurrentTab(); break; case R.id.clear_and_exit: @@ -2493,7 +2488,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the target URL as the title of the `ContextMenu`. menu.setHeaderTitle(linkUrl); - // Add a Load URL entry. + // Add an Open in New Tab entry. menu.add(R.string.open_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> { // Add a new tab. addTab(null); @@ -2601,89 +2596,26 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook menu.add(R.string.cancel); break; - // `IMAGE_TYPE` is an image. + // `IMAGE_TYPE` is an image. `SRC_IMAGE_ANCHOR_TYPE` is an image that is also a link. Privacy Browser processes them the same. case WebView.HitTestResult.IMAGE_TYPE: + case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: // Get the image URL. imageUrl = hitTestResult.getExtra(); - // Set the image URL as the title of the `ContextMenu`. + // Set the image URL as the title of the context menu. menu.setHeaderTitle(imageUrl); - // Add a View Image entry. - menu.add(R.string.view_image).setOnMenuItemClickListener(item -> { - loadUrl(imageUrl); - return false; - }); - - // Add a Download Image entry. - menu.add(R.string.download_image).setOnMenuItemClickListener((MenuItem item) -> { - // Check if the download should be processed by an external app. - if (sharedPreferences.getBoolean("download_with_external_app", false)) { // Download with an external app. - openUrlWithExternalApp(imageUrl); - } else { // Download with Android's download manager. - // Check to see if the storage permission has already been granted. - if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { // The storage permission needs to be requested. - // Store the image URL for use by `onRequestPermissionResult()`. - downloadImageUrl = imageUrl; - - // Show a dialog if the user has previously denied the permission. - if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show a dialog explaining the request first. - // Instantiate the download location permission alert dialog and set the download type to DOWNLOAD_IMAGE. - DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE); - - // Show the download location permission alert dialog. The permission will be requested when the dialog is closed. - downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location)); - } else { // Show the permission request directly. - // Request the permission. The download dialog will be launched by `onRequestPermissionResult(). - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_IMAGE_REQUEST_CODE); - } - } else { // The storage permission has already been granted. - // Get a handle for the download image alert dialog. - DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl); - - // Show the download image alert dialog. - downloadImageDialogFragment.show(fragmentManager, getString(R.string.download)); - } - } - return false; - }); - - // Add a Copy URL entry. - menu.add(R.string.copy_url).setOnMenuItemClickListener(item -> { - // Save the image URL in a `ClipData`. - ClipData srcImageTypeClipData = ClipData.newPlainText(getString(R.string.url), imageUrl); - - // Set the `ClipData` as the clipboard's primary clip. - clipboardManager.setPrimaryClip(srcImageTypeClipData); - return false; - }); - - // Add an Open with App entry. - menu.add(R.string.open_with_app).setOnMenuItemClickListener((MenuItem item) -> { - openWithApp(imageUrl); - return false; - }); + // Add an Open in New Tab entry. + menu.add(R.string.open_in_new_tab).setOnMenuItemClickListener((MenuItem item) -> { + // Add a new tab. + addTab(null); - // Add an Open with Browser entry. - menu.add(R.string.open_with_browser).setOnMenuItemClickListener((MenuItem item) -> { - openWithBrowser(imageUrl); + // Load the URL. + loadUrl(imageUrl); return false; }); - // Add a `Cancel` entry, which by default closes the `ContextMenu`. - menu.add(R.string.cancel); - break; - - - // `SRC_IMAGE_ANCHOR_TYPE` is an image that is also a link. - case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: - // Get the image URL. - imageUrl = hitTestResult.getExtra(); - - // Set the image URL as the title of the `ContextMenu`. - menu.setHeaderTitle(imageUrl); - - // Add a `View Image` entry. + // Add a View Image entry. menu.add(R.string.view_image).setOnMenuItemClickListener(item -> { loadUrl(imageUrl); return false; @@ -3132,8 +3064,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Override `onBackPressed` to handle the navigation drawer and and the WebView. @Override public void onBackPressed() { - // Get a handle for the drawer layout. + // Get a handle for the drawer layout and the tab layout. DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + TabLayout tabLayout = findViewById(R.id.tablayout); if (drawerLayout.isDrawerVisible(GravityCompat.START)) { // The navigation drawer is open. // Close the navigation drawer. @@ -3158,9 +3091,15 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Go back. currentWebView.goBack(); - } else { // There is nothing else to do. - // Load a blank website. - loadUrl(""); + } else if (tabLayout.getTabCount() > 1) { // There are at least two tabs. + // Close the current tab. + closeCurrentTab(); + } else { // There isn't anything to do in Privacy Browser. + // Run the default commands. + super.onBackPressed(); + + // Manually kill Privacy Browser. Otherwise, it is glitchy when restarted. + System.exit(0); } } @@ -3271,8 +3210,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Delete the contents of `find_on_page_edittext`. findOnPageEditText.setText(null); - // Clear the highlighted phrases. - currentWebView.clearMatches(); + // Clear the highlighted phrases if the WebView is not null. + if (currentWebView != null) { + currentWebView.clearMatches(); + } // Hide the find on page linear layout. findOnPageLinearLayout.setVisibility(View.GONE); @@ -3306,6 +3247,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout); AppBarLayout appBarLayout = findViewById(R.id.appbar_layout); ActionBar actionBar = getSupportActionBar(); + Toolbar toolbar = findViewById(R.id.toolbar); + LinearLayout findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout); LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout); SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); @@ -3322,23 +3265,35 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook customHeaders.remove("DNT"); } - // Get the current layout parameters. Using coordinator layout parameters allows the `setBehavior()` command. - CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams(); + // Get the current layout parameters. Using coordinator layout parameters allows the `setBehavior()` command and using app bar layout parameters allows the `setScrollFlags()` command. + CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams(); + AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) toolbar.getLayoutParams(); + AppBarLayout.LayoutParams findOnPageLayoutParams = (AppBarLayout.LayoutParams) findOnPageLinearLayout.getLayoutParams(); + AppBarLayout.LayoutParams tabsLayoutParams = (AppBarLayout.LayoutParams) tabsLinearLayout.getLayoutParams(); // Add the scrolling behavior to the layout parameters. if (scrollAppBar) { // Enable scrolling of the app bar. - layoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior()); + swipeRefreshLayoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior()); + toolbarLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP); + findOnPageLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP); + tabsLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP); } else { // Disable scrolling of the app bar. - layoutParams.setBehavior(null); + swipeRefreshLayoutParams.setBehavior(null); + toolbarLayoutParams.setScrollFlags(0); + findOnPageLayoutParams.setScrollFlags(0); + tabsLayoutParams.setScrollFlags(0); // Expand the app bar if it is currently collapsed. appBarLayout.setExpanded(true); } - // Apply the modified layout parameters to the swipe refresh layout. - swipeRefreshLayout.setLayoutParams(layoutParams); + // Apply the modified layout parameters. + swipeRefreshLayout.setLayoutParams(swipeRefreshLayoutParams); + toolbar.setLayoutParams(toolbarLayoutParams); + findOnPageLinearLayout.setLayoutParams(findOnPageLayoutParams); + tabsLinearLayout.setLayoutParams(tabsLayoutParams); // Set the app bar scrolling for each WebView. for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { @@ -3459,24 +3414,24 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the corresponding tab. TabLayout.Tab tab = tabLayout.getTabAt(currentPagePosition); - // Remove the warning below that the tab might be null. - assert tab != null; - - // Get the tab custom view. - View tabCustomView = tab.getCustomView(); + // Update the tab if it isn't null, which sometimes happens when restarting from the background. + if (tab != null) { + // Get the tab custom view. + View tabCustomView = tab.getCustomView(); - // Remove the warning below that the tab custom view might be null. - assert tabCustomView != null; + // Remove the warning below that the tab custom view might be null. + assert tabCustomView != null; - // Get the tab views. - ImageView tabFavoriteIconImageView = tabCustomView.findViewById(R.id.favorite_icon_imageview); - TextView tabTitleTextView = tabCustomView.findViewById(R.id.title_textview); + // Get the tab views. + ImageView tabFavoriteIconImageView = tabCustomView.findViewById(R.id.favorite_icon_imageview); + TextView tabTitleTextView = tabCustomView.findViewById(R.id.title_textview); - // Set the default favorite icon as the favorite icon for this tab. - tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true)); + // Set the default favorite icon as the favorite icon for this tab. + tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true)); - // Set the loading title text. - tabTitleTextView.setText(R.string.loading); + // Set the loading title text. + tabTitleTextView.setText(R.string.loading); + } } // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. @@ -3880,11 +3835,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String searchCustomUrlString = sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)); boolean darkTheme = sharedPreferences.getBoolean("dark_theme", false); - // Get a handle for the action bar. `getSupportActionBar()` must be used until the minimum API >= 21. - ActionBar actionBar = getSupportActionBar(); - - // Remove the incorrect lint warning later that the action bar might be null. - assert actionBar != null; + // Get a handle for the app bar layout. + AppBarLayout appBarLayout = findViewById(R.id.appbar_layout); // Set the homepage, search, and proxy options. if (proxyThroughOrbot) { // Set the Tor options. @@ -3898,11 +3850,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); - // Set the `appBar` background to indicate proxying through Orbot is enabled. + // Set the app bar background to indicate proxying through Orbot is enabled. if (darkTheme) { - actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.dark_blue_30)); + appBarLayout.setBackgroundResource(R.color.dark_blue_30); } else { - actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.blue_50)); + appBarLayout.setBackgroundResource(R.color.blue_50); } // Check to see if Orbot is ready. @@ -3930,11 +3882,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reset the proxy to default. The host is `""` and the port is `"0"`. OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); - // Set the default `appBar` background. + // Set the default app bar layout background. if (darkTheme) { - actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_900)); + appBarLayout.setBackgroundResource(R.color.gray_900); } else { - actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_100)); + appBarLayout.setBackgroundResource(R.color.gray_100); } // Reset `waitingForOrbot. @@ -4216,6 +4168,27 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook webViewPagerAdapter.addPage(newTabNumber, webViewPager); } + private void closeCurrentTab() { + // Get handles for the views. + AppBarLayout appBarLayout = findViewById(R.id.appbar_layout); + TabLayout tabLayout = findViewById(R.id.tablayout); + ViewPager webViewPager = findViewById(R.id.webviewpager); + + // Get the current tab number. + int currentTabNumber = tabLayout.getSelectedTabPosition(); + + // Delete the current tab. + tabLayout.removeTabAt(currentTabNumber); + + // Delete the current page. If the selected page number did not change during the delete, it will return true, meaning that the current WebView must be reset. + if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) { + setCurrentWebView(currentTabNumber); + } + + // Expand the app bar if it is currently collapsed. + appBarLayout.setExpanded(true); + } + private void setCurrentWebView(int pageNumber) { // Get a handle for the shared preferences. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); @@ -4274,27 +4247,33 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the current URL. String url = currentWebView.getUrl(); - if ((url == null) || url.equals("about:blank")) { // The WebView is blank. - // Display the hint in the URL edit text. - urlEditText.setText(""); + // Update the URL edit text if not loading a new intent. Otherwise, this will be handled by `onPageStarted()` (if called) and `onPageFinished()`. + if (!loadingNewIntent) { // A new intent is not being loaded. + if ((url == null) || url.equals("about:blank")) { // The WebView is blank. + // Display the hint in the URL edit text. + urlEditText.setText(""); - // Request focus for the URL text box. - urlEditText.requestFocus(); + // Request focus for the URL text box. + urlEditText.requestFocus(); - // Display the keyboard. - inputMethodManager.showSoftInput(urlEditText, 0); - } else { // The WebView has a loaded URL. - // Clear the focus from the URL text box. - urlEditText.clearFocus(); + // Display the keyboard. + inputMethodManager.showSoftInput(urlEditText, 0); + } else { // The WebView has a loaded URL. + // Clear the focus from the URL text box. + urlEditText.clearFocus(); - // Hide the soft keyboard. - inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); + // Hide the soft keyboard. + inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); - // Display the current URL in the URL text box. - urlEditText.setText(url); + // Display the current URL in the URL text box. + urlEditText.setText(url); - // Highlight the URL text. - highlightUrlText(); + // Highlight the URL text. + highlightUrlText(); + } + } else { // A new intent is being loaded. + // Reset the loading new intent tracker. + loadingNewIntent = false; } // Set the background to indicate the domain settings status. @@ -5208,6 +5187,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Update the URL text bar if the page is currently selected. if (tabLayout.getSelectedTabPosition() == currentPagePosition) { + // Clear the focus from the URL edit text. + urlEditText.clearFocus(); + // Display the formatted URL text. urlEditText.setText(url); @@ -5326,10 +5308,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get the current page position. int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId()); - // Update the URL text bar if the page is currently selected. - if (tabLayout.getSelectedTabPosition() == currentPagePosition) { + // Check the current website information against any pinned domain information if the current IP addresses have been loaded. + if ((nestedScrollWebView.hasPinnedSslCertificate() || nestedScrollWebView.hasPinnedIpAddresses()) && nestedScrollWebView.hasCurrentIpAddresses() && + !nestedScrollWebView.ignorePinnedDomainInformation()) { + CheckPinnedMismatchHelper.checkPinnedMismatch(getSupportFragmentManager(), nestedScrollWebView); + } + + // 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. + String currentUrl = nestedScrollWebView.getUrl(); + + // Update the URL text bar if the page is currently selected and the user is not currently typing in the URL edit text. + // Crash records show that, in some crazy way, it is possible for the current URL to be blank at this point. + // Probably some sort of race condition when Privacy Browser is being resumed. + if ((tabLayout.getSelectedTabPosition() == currentPagePosition) && !urlEditText.hasFocus() && (currentUrl != null)) { // Check to see if the URL is `about:blank`. - if (url.equals("about:blank")) { // The WebView is blank. + if (currentUrl.equals("about:blank")) { // The WebView is blank. // Display the hint in the URL edit text. urlEditText.setText(""); @@ -5345,21 +5338,30 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Apply the domain settings. This clears any settings from the previous domain. applyDomainSettings(nestedScrollWebView, "", true, false); } else { // The WebView has loaded a webpage. - // Only update the URL text box if the user is not typing in it. - if (!urlEditText.hasFocus()) { - // Display the final URL. Getting the URL from the WebView instead of using the one provided by `onPageFinished()` makes websites like YouTube function correctly. - urlEditText.setText(nestedScrollWebView.getUrl()); + // Display the final URL. Getting the URL from the WebView instead of using the one provided by `onPageFinished()` makes websites like YouTube function correctly. + urlEditText.setText(currentUrl); - // Apply text highlighting to the URL. - highlightUrlText(); - } + // Apply text highlighting to the URL. + highlightUrlText(); } } - // Check the current website information against any pinned domain information if the current IP addresses have been loaded. - if ((nestedScrollWebView.hasPinnedSslCertificate() || nestedScrollWebView.hasPinnedIpAddresses()) && nestedScrollWebView.hasCurrentIpAddresses() && - !nestedScrollWebView.ignorePinnedDomainInformation()) { - CheckPinnedMismatchHelper.checkPinnedMismatch(getSupportFragmentManager(), nestedScrollWebView); + // Get the current tab. + TabLayout.Tab tab = tabLayout.getTabAt(currentPagePosition); + + // Only populate the title text view if the tab has been fully created. + if (tab != null) { + // Get the custom view from the tab. + View tabView = tab.getCustomView(); + + // Remove the incorrect warning below that the current tab view might be null. + assert tabView != null; + + // Get the title text view from the tab. + TextView tabTitleTextView = tabView.findViewById(R.id.title_textview); + + // Set the title as the tab text. Sometimes `onReceivedTitle()` is not called, especially when navigating history. + tabTitleTextView.setText(nestedScrollWebView.getTitle()); } } }