import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
-import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog;
import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDialog;
import com.stoutner.privacybrowser.dialogs.HttpAuthenticationDialog;
-import com.stoutner.privacybrowser.dialogs.PinnedMismatchDialog;
import com.stoutner.privacybrowser.dialogs.SslCertificateErrorDialog;
import com.stoutner.privacybrowser.dialogs.UrlHistoryDialog;
import com.stoutner.privacybrowser.dialogs.ViewSslCertificateDialog;
import java.util.Map;
import java.util.Set;
-// TODO. Store up reloads for tabs that are not visible.
-// TODO. New tabs are white in dark mode.
-// TODO. Hide the tabs in full screen mode.
-// TODO. Find on page.
-// TODO. Use TabLayout.setScrollPosition to scroll to new tabs.
-
// AppCompatActivity from android.support.v7.app.AppCompatActivity must be used to have access to the SupportActionBar until the minimum API is >= 21.
public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener,
DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener, DownloadLocationPermissionDialog.DownloadLocationPermissionDialogListener, EditBookmarkDialog.EditBookmarkListener,
- EditBookmarkFolderDialog.EditBookmarkFolderListener, NavigationView.OnNavigationItemSelectedListener, WebViewTabFragment.NewTabListener, PinnedMismatchDialog.PinnedMismatchListener,
- UrlHistoryDialog.UrlHistoryListener {
+ EditBookmarkFolderDialog.EditBookmarkFolderListener, NavigationView.OnNavigationItemSelectedListener, WebViewTabFragment.NewTabListener {
// `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`, `onResume()`, and `applyProxyThroughOrbot()`.
public static String orbotStatus;
// The WebView pager adapter is accessed from `HttpAuthenticationDialog`, `PinnedMismatchDialog`, and `SslCertificateErrorDialog`. It is also used in `onCreate()`, `onResume()`, and `addTab()`.
public static WebViewPagerAdapter webViewPagerAdapter;
- // `reloadOnRestart` is public static so it can be accessed from `SettingsFragment`. It is used in `onRestart()`
- public static boolean reloadOnRestart;
-
// The load URL on restart variables are public static so they can be accessed from `BookmarksActivity`. They are used in `onRestart()`.
public static boolean loadUrlOnRestart;
public static String urlToLoadOnRestart;
// `inFullScreenBrowsingMode` is used in `onCreate()`, `onConfigurationChanged()`, and `applyAppSettings()`.
private boolean inFullScreenBrowsingMode;
- // Hide app bar is used in `applyAppSettings()` and `initializeWebView()`.
+ // The hide app bar tracker is used in `applyAppSettings()` and `initializeWebView()`.
private boolean hideAppBar;
// `reapplyDomainSettingsOnRestart` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `onAddDomain()`, .
@Override
public void onPageSelected(int position) {
+ // Close the find on page bar if it is open.
+ closeFindOnPage(null);
+
// Set the current WebView.
setCurrentWebView(position);
- // Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled via swiping in the view pager.
+ // Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled via swiping in the view pager or by creating a new tab.
if (tabLayout.getSelectedTabPosition() != position) {
- // Get a handle for the corresponding tab.
- TabLayout.Tab correspondingTab = tabLayout.getTabAt(position);
+ // Create a handler to select the tab.
+ Handler selectTabHandler = new Handler();
+
+ // Create a runnable select the new tab.
+ Runnable selectTabRunnable = () -> {
+ // Get a handle for the tab.
+ TabLayout.Tab tab = tabLayout.getTabAt(position);
- // Assert that the corresponding tab is not null.
- assert correspondingTab != null;
+ // Assert that the tab is not null.
+ assert tab != null;
- // Select the corresponding tab.
- correspondingTab.select();
+ // Select the tab.
+ tab.select();
+ };
+
+ // Select the tab layout after 100 milliseconds, which leaves enough time for a new tab to be created.
+ selectTabHandler.postDelayed(selectTabRunnable, 100);
}
}
@Override
public void afterTextChanged(Editable s) {
- // Search for the text in `mainWebView`.
- currentWebView.findAllAsync(findOnPageEditText.getText().toString());
+ // Search for the text in the WebView if it is not null. Sometimes on resume after a period of non-use the WebView will be null.
+ if (currentWebView != null) {
+ currentWebView.findAllAsync(findOnPageEditText.getText().toString());
+ }
}
});
// Apply the app settings if returning from the Settings activity.
if (reapplyAppSettingsOnRestart) {
+ // Reset the reapply app settings on restart tracker.
+ reapplyAppSettingsOnRestart = false;
+
// Apply the app settings.
applyAppSettings();
+ }
- // Reload the webpage to handle changes to night mode and displaying of images.
- if (reloadOnRestart) {
- // Reload the WebViews.
- for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
- // Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
+ // Apply the domain settings if returning from the settings or domains activity.
+ if (reapplyDomainSettingsOnRestart) {
+ // Reset the reapply domain settings on restart tracker.
+ reapplyDomainSettingsOnRestart = false;
- // Get the fragment view.
- View fragmentView = webViewTabFragment.getView();
+ // Reapply the domain settings for each tab.
+ for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
+ // Get the WebView tab fragment.
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
- // Only reload the WebViews if they exist.
- if (fragmentView != null) {
- // Get the nested scroll WebView from the tab fragment.
- NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+ // Get the fragment view.
+ View fragmentView = webViewTabFragment.getView();
- // Reload the WebView. This doesn't seem to work if for WebViews that aren't visible.
- nestedScrollWebView.reload();
+ // Only reload the WebViews if they exist.
+ if (fragmentView != null) {
+ // Get the nested scroll WebView from the tab fragment.
+ NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+
+ // Reset the current domain name so the domain settings will be reapplied.
+ nestedScrollWebView.resetCurrentDomainName();
+
+ // Reapply the domain settings if the URL is not null, which can happen if an empty tab is active when returning from settings.
+ if (nestedScrollWebView.getUrl() != null) {
+ applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true);
}
}
-
- // Reset `reloadOnRestartBoolean`.
- reloadOnRestart = false;
}
-
- // Reset the return from settings flag.
- reapplyAppSettingsOnRestart = false;
}
- // TODO apply to all the tabs.
- // Apply the domain settings if returning from the Domains activity.
- if (reapplyDomainSettingsOnRestart) {
- // Reset the current domain name so the domain settings will be reapplied.
- currentWebView.resetCurrentDomainName();
-
- // Reapply the domain settings.
- applyDomainSettings(currentWebView, currentWebView.getUrl(), false, true); // TODO.
-
- // Reset the reapply domain settings on restart tracker.
- reapplyDomainSettingsOnRestart = false;
- }
-
- // Load the URL on restart (used when loading a bookmark.
+ // Load the URL on restart (used when loading a bookmark).
if (loadUrlOnRestart) {
// Load the specified URL.
loadUrl(urlToLoadOnRestart);
// Reapply the domain settings on returning to `MainWebViewActivity`.
reapplyDomainSettingsOnRestart = true;
- // TODO. Move these to `putExtra`. The certificate can be stored as strings.
- // Store the current SSL certificate and IP addresses in the domains activity.
- DomainsActivity.currentSslCertificate = currentWebView.getCertificate();
- DomainsActivity.currentIpAddresses = currentWebView.getCurrentIpAddresses();
-
// Create an intent to launch the domains activity.
Intent domainsIntent = new Intent(this, DomainsActivity.class);
domainsIntent.putExtra("close_on_back", true);
domainsIntent.putExtra("current_url", currentWebView.getUrl());
+ // Get the current certificate.
+ SslCertificate sslCertificate = currentWebView.getCertificate();
+
+ // Check to see if the SSL certificate is populated.
+ if (sslCertificate != null) {
+ // Extract the certificate to strings.
+ String issuedToCName = sslCertificate.getIssuedTo().getCName();
+ String issuedToOName = sslCertificate.getIssuedTo().getOName();
+ String issuedToUName = sslCertificate.getIssuedTo().getUName();
+ String issuedByCName = sslCertificate.getIssuedBy().getCName();
+ String issuedByOName = sslCertificate.getIssuedBy().getOName();
+ String issuedByUName = sslCertificate.getIssuedBy().getUName();
+ long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
+ long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
+
+ // Add the certificate to the intent.
+ domainsIntent.putExtra("ssl_issued_to_cname", issuedToCName);
+ domainsIntent.putExtra("ssl_issued_to_oname", issuedToOName);
+ domainsIntent.putExtra("ssl_issued_to_uname", issuedToUName);
+ domainsIntent.putExtra("ssl_issued_by_cname", issuedByCName);
+ domainsIntent.putExtra("ssl_issued_by_oname", issuedByOName);
+ domainsIntent.putExtra("ssl_issued_by_uname", issuedByUName);
+ domainsIntent.putExtra("ssl_start_date", startDateLong);
+ domainsIntent.putExtra("ssl_end_date", endDateLong);
+ }
+
+ // Check to see if the current IP addresses have been received.
+ if (currentWebView.hasCurrentIpAddresses()) {
+ // Add the current IP addresses to the intent.
+ domainsIntent.putExtra("current_ip_addresses", currentWebView.getCurrentIpAddresses());
+ }
+
// Make it so.
startActivity(domainsIntent);
} else { // Add a new domain.
// Create the domain and store the database ID.
int newDomainDatabaseId = domainsDatabaseHelper.addDomain(currentDomain);
- // TODO. Move these to `putExtra`. The certificate can be stored as strings.
- // Store the current SSL certificate and IP addresses in the domains activity.
- DomainsActivity.currentSslCertificate = currentWebView.getCertificate();
- DomainsActivity.currentIpAddresses = currentWebView.getCurrentIpAddresses();
-
// Create an intent to launch the domains activity.
Intent domainsIntent = new Intent(this, DomainsActivity.class);
domainsIntent.putExtra("close_on_back", true);
domainsIntent.putExtra("current_url", currentWebView.getUrl());
+ // Get the current certificate.
+ SslCertificate sslCertificate = currentWebView.getCertificate();
+
+ // Check to see if the SSL certificate is populated.
+ if (sslCertificate != null) {
+ // Extract the certificate to strings.
+ String issuedToCName = sslCertificate.getIssuedTo().getCName();
+ String issuedToOName = sslCertificate.getIssuedTo().getOName();
+ String issuedToUName = sslCertificate.getIssuedTo().getUName();
+ String issuedByCName = sslCertificate.getIssuedBy().getCName();
+ String issuedByOName = sslCertificate.getIssuedBy().getOName();
+ String issuedByUName = sslCertificate.getIssuedBy().getUName();
+ long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
+ long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
+
+ // Add the certificate to the intent.
+ domainsIntent.putExtra("ssl_issued_to_cname", issuedToCName);
+ domainsIntent.putExtra("ssl_issued_to_oname", issuedToOName);
+ domainsIntent.putExtra("ssl_issued_to_uname", issuedToUName);
+ domainsIntent.putExtra("ssl_issued_by_cname", issuedByCName);
+ domainsIntent.putExtra("ssl_issued_by_oname", issuedByOName);
+ domainsIntent.putExtra("ssl_issued_by_uname", issuedByUName);
+ domainsIntent.putExtra("ssl_start_date", startDateLong);
+ domainsIntent.putExtra("ssl_end_date", endDateLong);
+ }
+
+ // Check to see if the current IP addresses have been received.
+ if (currentWebView.hasCurrentIpAddresses()) {
+ // Add the current IP addresses to the intent.
+ domainsIntent.putExtra("current_ip_addresses", currentWebView.getCurrentIpAddresses());
+ }
+
// Make it so.
startActivity(domainsIntent);
}
LinearLayout findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
EditText findOnPageEditText = findViewById(R.id.find_on_page_edittext);
+ // Set the minimum height of the find on page linear layout to match the toolbar.
+ findOnPageLinearLayout.setMinimumHeight(toolbar.getHeight());
+
// Hide the toolbar.
toolbar.setVisibility(View.GONE);
break;
case R.id.history:
- // Get the `WebBackForwardList`.
- WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList();
+ // Instantiate the URL history dialog.
+ DialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(currentWebView.getWebViewFragmentId());
- // Show the URL history dialog and name this instance `R.string.history`.
- DialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(this, webBackForwardList);
+ // Show the URL history dialog.
urlHistoryDialogFragment.show(getSupportFragmentManager(), getString(R.string.history));
break;
// Set the flag to reapply the domain settings on restart when returning from Domain Settings.
reapplyDomainSettingsOnRestart = true;
- // TODO. Move these to `putExtra`. The certificate can be stored as strings.
- // Store the current SSL certificate and IP addresses in the domains activity.
- DomainsActivity.currentSslCertificate = currentWebView.getCertificate();
- DomainsActivity.currentIpAddresses = currentWebView.getCurrentIpAddresses();
-
// Launch the domains activity.
Intent domainsIntent = new Intent(this, DomainsActivity.class);
// Add the extra information to the intent.
domainsIntent.putExtra("current_url", currentWebView.getUrl());
+ // Get the current certificate.
+ SslCertificate sslCertificate = currentWebView.getCertificate();
+
+ // Check to see if the SSL certificate is populated.
+ if (sslCertificate != null) {
+ // Extract the certificate to strings.
+ String issuedToCName = sslCertificate.getIssuedTo().getCName();
+ String issuedToOName = sslCertificate.getIssuedTo().getOName();
+ String issuedToUName = sslCertificate.getIssuedTo().getUName();
+ String issuedByCName = sslCertificate.getIssuedBy().getCName();
+ String issuedByOName = sslCertificate.getIssuedBy().getOName();
+ String issuedByUName = sslCertificate.getIssuedBy().getUName();
+ long startDateLong = sslCertificate.getValidNotBeforeDate().getTime();
+ long endDateLong = sslCertificate.getValidNotAfterDate().getTime();
+
+ // Add the certificate to the intent.
+ domainsIntent.putExtra("ssl_issued_to_cname", issuedToCName);
+ domainsIntent.putExtra("ssl_issued_to_oname", issuedToOName);
+ domainsIntent.putExtra("ssl_issued_to_uname", issuedToUName);
+ domainsIntent.putExtra("ssl_issued_by_cname", issuedByCName);
+ domainsIntent.putExtra("ssl_issued_by_oname", issuedByOName);
+ domainsIntent.putExtra("ssl_issued_by_uname", issuedByUName);
+ domainsIntent.putExtra("ssl_start_date", startDateLong);
+ domainsIntent.putExtra("ssl_end_date", endDateLong);
+ }
+
+ // Check to see if the current IP addresses have been received.
+ if (currentWebView.hasCurrentIpAddresses()) {
+ // Add the current IP addresses to the intent.
+ domainsIntent.putExtra("current_ip_addresses", currentWebView.getCurrentIpAddresses());
+ }
+
// Make it so.
startActivity(domainsIntent);
break;
}
}
- @Override
- public void onPinnedMismatchBack() { // TODO. Move this logic to the dialog.
- if (currentWebView.canGoBack()) { // There is a back page in the history.
- // Reset the current domain name so that navigation works if third-party requests are blocked.
- currentWebView.resetCurrentDomainName();
-
- // Set navigating history so that the domain settings are applied when the new URL is loaded.
- currentWebView.setNavigatingHistory(true);
-
- // Go back.
- currentWebView.goBack();
- } else { // There are no pages to go back to.
- // Load a blank page
- loadUrl("");
- }
- }
-
- @Override
- public void onPinnedMismatchProceed() { // TODO. Move this logic to the dialog.
- // Do not check the pinned information for this domain again until the domain changes.
- currentWebView.setIgnorePinnedDomainInformation(true);
- }
-
- @Override
- public void onUrlHistoryEntrySelected(int moveBackOrForwardSteps) { // TODO. Move this logic to the dialog.
- // Reset the current domain name so that navigation works if third-party requests are blocked.
- currentWebView.resetCurrentDomainName();
-
- // Set navigating history so that the domain settings are applied when the new URL is loaded.
- currentWebView.setNavigatingHistory(true);
-
- // Load the history entry.
- currentWebView.goBackOrForward(moveBackOrForwardSteps);
- }
-
- @Override
- public void onClearHistory() { // TODO. Move this logic to the dialog.
- // Clear the history.
- currentWebView.clearHistory();
- }
-
// Override `onBackPressed` to handle the navigation drawer and and the WebView.
@Override
public void onBackPressed() {
// Go back.
currentWebView.goBack();
- } else { // There isn't anything to do in Privacy Browser.
- // Pass `onBackPressed()` to the system.
- super.onBackPressed();
+ } else { // There is nothing else to do.
+ // Load a blank website.
+ loadUrl("");
}
}
fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false);
hideAppBar = sharedPreferences.getBoolean("hide_app_bar", true);
- // Get handles for the views that need to be modified. `getSupportActionBar()` must be used until the minimum API >= 21.
+ // Get handles for the views that need to be modified.
FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
ActionBar actionBar = getSupportActionBar();
+ LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout);
- // Remove the incorrect lint warnings below that the action bar might be null.
+ // Remove the incorrect lint warning below that the action bar might be null.
assert actionBar != null;
// Apply the proxy through Orbot settings.
if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { // Privacy Browser is currently in full screen browsing mode.
// Update the visibility of the app bar, which might have changed in the settings.
if (hideAppBar) {
+ // Hide the tab linear layout.
+ tabsLinearLayout.setVisibility(View.GONE);
+
+ // Hide the action bar.
actionBar.hide();
} else {
+ // Show the tab linear layout.
+ tabsLinearLayout.setVisibility(View.VISIBLE);
+
+ // Show the action bar.
actionBar.show();
}
// Reset the full screen tracker, which could be true if Privacy Browser was in full screen mode before entering settings and full screen browsing was disabled.
inFullScreenBrowsingMode = false;
- // Show the app bar.
+ // Show the tab linear layout.
+ tabsLinearLayout.setVisibility(View.VISIBLE);
+
+ // Show the action bar.
actionBar.show();
// Show the banner ad in the free flavor.
// `reloadWebsite` is used if returning from the Domains activity. Otherwise JavaScript might not function correctly if it is newly enabled.
@SuppressLint("SetJavaScriptEnabled")
- private boolean applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetFavoriteIcon, boolean reloadWebsite) {
+ private boolean applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetTab, boolean reloadWebsite) {
// Store a copy of the current user agent to track changes for the return boolean.
String initialUserAgent = nestedScrollWebView.getSettings().getUserAgentString();
nestedScrollWebView.clearPinnedIpAddresses();
// Reset the favorite icon if specified.
- if (resetFavoriteIcon) {
+ if (resetTab) {
// Initialize the favorite icon.
nestedScrollWebView.initializeFavoriteIcon();
+ // Get the current page position.
+ int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
+
// Get a handle for the tab layout.
TabLayout tabLayout = findViewById(R.id.tablayout);
- // Get the current tab.
- TabLayout.Tab currentTab = tabLayout.getTabAt(tabLayout.getSelectedTabPosition()); // TODO. We need to get the tab for this WebView, which might not be the current tab.
+ // Get the corresponding tab.
+ TabLayout.Tab tab = tabLayout.getTabAt(currentPagePosition);
- // Remove the warning below that the current tab might be null.
- assert currentTab != null;
+ // Remove the warning below that the tab might be null.
+ assert tab != null;
- // Get the current tab custom view.
- View currentTabCustomView = currentTab.getCustomView();
+ // Get the tab custom view.
+ View tabCustomView = tab.getCustomView();
- // Remove the warning below that the current tab custom view might be null.
- assert currentTabCustomView != null;
+ // Remove the warning below that the tab custom view might be null.
+ assert tabCustomView != null;
- // Get the current tab favorite icon image view.
- ImageView currentTabFavoriteIconImageView = currentTabCustomView.findViewById(R.id.favorite_icon_imageview);
+ // 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.
- currentTabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true));
+ tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true));
+
+ // 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`.
assert newTab != null;
// Set a custom view on the new tab.
- newTab.setCustomView(R.layout.custom_tab_view);
+ newTab.setCustomView(R.layout.tab_custom_view);
// Add the new WebView page.
webViewPagerAdapter.addPage(newTabNumber, webViewPager);
// Update the privacy icons. `true` redraws the icons in the app bar.
updatePrivacyIcons(true);
- // Clear the focus from the URL text box.
- urlEditText.clearFocus();
-
// Get a handle for the input method manager.
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// Remove the lint warning below that the input method manager might be null.
assert inputMethodManager != null;
- // Hide the soft keyboard.
- inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
+ // 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("");
+
+ // 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();
+
+ // Hide the soft keyboard.
+ inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
- // Display the current URL in the URL text box.
- urlEditText.setText(currentWebView.getUrl());
+ // Display the current URL in the URL text box.
+ urlEditText.setText(url);
- // Highlight the URL text.
- highlightUrlText();
+ // Highlight the URL text.
+ highlightUrlText();
+ }
// Set the background to indicate the domain settings status.
if (currentWebView.getDomainSettingsApplied()) {
DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
ActionBar actionBar = getSupportActionBar();
+ LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout);
EditText urlEditText = findViewById(R.id.url_edittext);
TabLayout tabLayout = findViewById(R.id.tablayout);
SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
- // Remove the incorrect lint warnings below that the some of the views might be null.
+ // Remove the incorrect lint warning below that the action bar might be null.
assert actionBar != null;
// Get a handle for the activity
if (inFullScreenBrowsingMode) { // Switch to full screen mode.
// Hide the app bar if specified.
if (hideAppBar) {
+ // Close the find on page bar if it is visible.
+ closeFindOnPage(null);
+
+ // Hide the tab linear layout.
+ tabsLinearLayout.setVisibility(View.GONE);
+
+ // Hide the action bar.
actionBar.hide();
}
rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} else { // Switch to normal viewing mode.
- // Show the app bar.
+ // Show the tab linear layout.
+ tabsLinearLayout.setVisibility(View.VISIBLE);
+
+ // Show the action bar.
actionBar.show();
// Show the banner ad in the free flavor.
@Override
public void onProgressChanged(WebView view, int progress) {
// Inject the night mode CSS if night mode is enabled.
- if (nestedScrollWebView.getNightMode()) {
+ if (nestedScrollWebView.getNightMode()) { // Night mode is enabled.
// `background-color: #212121` sets the background to be dark gray. `color: #BDBDBD` sets the text color to be light gray. `box-shadow: none` removes a lower underline on links
// used by WordPress. `text-decoration: none` removes all text underlines. `text-shadow: none` removes text shadows, which usually have a hard coded color.
// `border: none` removes all borders, which can also be used to underline text. `a {color: #1565C0}` sets links to be a dark blue.
}
};
- // Displaying of `mainWebView` after 500 milliseconds.
+ // Display the WebView after 500 milliseconds.
displayWebViewHandler.postDelayed(displayWebViewRunnable, 500);
});
+ } else { // Night mode is disabled.
+ // Display the nested scroll WebView if night mode is disabled.
+ // Because of a race condition between `applyDomainSettings` and `onPageStarted`,
+ // when night mode is set by domain settings the WebView may be hidden even if night mode is not currently enabled.
+ nestedScrollWebView.setVisibility(View.VISIBLE);
}
// Update the progress bar.
// Hide the progress bar.
progressBar.setVisibility(View.GONE);
- // Display the nested scroll WebView if night mode is disabled.
- // Because of a race condition between `applyDomainSettings` and `onPageStarted`,
- // when night mode is set by domain settings the WebView may be hidden even if night mode is not currently enabled.
- if (!nestedScrollWebView.getNightMode()) {
- nestedScrollWebView.setVisibility(View.VISIBLE);
- }
-
//Stop the swipe to refresh indicator if it is running
swipeRefreshLayout.setRefreshing(false);
}
if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { // Privacy Browser is currently in full screen browsing mode.
// Hide the app bar if specified.
if (hideAppBar) {
+ // Hide the tab linear layout.
+ tabsLinearLayout.setVisibility(View.GONE);
+
+ // Hide the action bar.
actionBar.hide();
}
// If night mode is enabled, hide `mainWebView` until after the night mode CSS is applied.
if (nestedScrollWebView.getNightMode()) {
nestedScrollWebView.setVisibility(View.INVISIBLE);
+ } else {
+ nestedScrollWebView.setVisibility(View.VISIBLE);
}
// Hide the keyboard.
// Check to see if Privacy Browser is waiting on Orbot.
if (!waitingForOrbot) { // Process the URL.
- // Display the formatted URL text.
- urlEditText.setText(url);
+ // Get the current page position.
+ int currentPagePosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
- // Apply text highlighting to `urlTextBox`.
- highlightUrlText();
+ // Update the URL text bar if the page is currently selected.
+ if (tabLayout.getSelectedTabPosition() == currentPagePosition) {
+ // Display the formatted URL text.
+ urlEditText.setText(url);
+
+ // Apply text highlighting to `urlTextBox`.
+ highlightUrlText();
+ }
// Reset the list of host IP addresses.
nestedScrollWebView.clearCurrentIpAddresses();
// Update the URL text box and apply domain settings if not waiting on Orbot.
if (!waitingForOrbot) {
- // Check to see if `WebView` has set `url` to be `about:blank`.
- if (url.equals("about:blank")) { // The WebView is blank.
- // Display the hint in the URL edit text.
- urlEditText.setText("");
-
- // Request focus for `urlTextBox`.
- urlEditText.requestFocus();
-
- // Display the keyboard.
- inputMethodManager.showSoftInput(urlEditText, 0);
-
- // Hide the WebView, which causes the default background color to be displayed according to the theme.
- nestedScrollWebView.setVisibility(View.GONE);
-
- // 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());
-
- // Apply text highlighting to `urlTextBox`.
- highlightUrlText();
+ // 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 to see if the URL is `about:blank`.
+ if (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();
+
+ // Display the keyboard.
+ inputMethodManager.showSoftInput(urlEditText, 0);
+
+ // Hide the WebView, which causes the default background color to be displayed according to the theme.
+ nestedScrollWebView.setVisibility(View.INVISIBLE);
+
+ // 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());
+
+ // Apply text highlighting to the URL.
+ highlightUrlText();
+ }
}
}