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=4193364de5c0041abc3b31948a7272f19b0ef80c;hp=4050a01faca5283b636b76d9be83c0137594b9bb;hb=fd2c21ea8241dce9c86a3213b9b9e325d5e7ce4a;hpb=fa3b8b382eb5ed86c598e3b126d1ef5dd117c5be 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 4050a01f..4193364d 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -71,7 +71,6 @@ import android.webkit.CookieManager; 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; @@ -124,7 +123,6 @@ import com.stoutner.privacybrowser.dialogs.DownloadLocationPermissionDialog; 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; @@ -154,17 +152,13 @@ import java.util.List; 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; @@ -172,9 +166,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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; @@ -231,7 +222,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `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()`, . @@ -491,16 +482,25 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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); } } @@ -864,51 +864,41 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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); - - // Get the fragment view. - View fragmentView = webViewTabFragment.getView(); - - // 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); - - // Reload the WebView. This doesn't seem to work if for WebViews that aren't visible. - nestedScrollWebView.reload(); - } - } + // Apply the domain settings if returning from the settings or domains activity. + if (reapplyDomainSettingsOnRestart) { + // Reset the reapply domain settings on restart tracker. + reapplyDomainSettingsOnRestart = false; - // Reset `reloadOnRestartBoolean`. - reloadOnRestart = false; - } + // 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); - // Reset the return from settings flag. - reapplyAppSettingsOnRestart = false; - } + // Get the fragment view. + View fragmentView = webViewTabFragment.getView(); - // 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(); + // 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); - // Reapply the domain settings. - applyDomainSettings(currentWebView, currentWebView.getUrl(), false, true); // TODO. + // Reset the current domain name so the domain settings will be reapplied. + nestedScrollWebView.resetCurrentDomainName(); - // Reset the reapply domain settings on restart tracker. - reapplyDomainSettingsOnRestart = false; + // Reapply the domain settings. + applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true); + } + } } - // 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); @@ -1379,11 +1369,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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); @@ -1392,6 +1377,38 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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. @@ -1408,11 +1425,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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); @@ -1421,6 +1433,38 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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); } @@ -2231,11 +2275,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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; @@ -2267,17 +2310,44 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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; @@ -3036,47 +3106,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } - @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() { @@ -3106,9 +3135,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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(""); } } @@ -3249,11 +3278,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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. @@ -3288,8 +3318,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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(); } @@ -3313,7 +3351,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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. @@ -3333,7 +3374,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `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(); @@ -3361,30 +3402,37 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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`. @@ -4118,7 +4166,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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); @@ -4212,11 +4260,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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 @@ -4276,6 +4325,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook if (inFullScreenBrowsingMode) { // Switch to full screen mode. // Hide the app bar if specified. if (hideAppBar) { + // Hide the tab linear layout. + tabsLinearLayout.setVisibility(View.GONE); + + // Hide the action bar. actionBar.hide(); } @@ -4296,7 +4349,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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. @@ -4436,7 +4492,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } }; - // Displaying of `mainWebView` after 500 milliseconds. + // Display the WebView after 500 milliseconds. displayWebViewHandler.postDelayed(displayWebViewRunnable, 500); }); } @@ -4591,6 +4647,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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(); } @@ -4730,15 +4790,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Get a handle for the navigation requests menu item. The menu is 0 based. MenuItem navigationRequestsMenuItem = navigationMenu.getItem(6); - // Get handles for the options menu items. - MenuItem blocklistsMenuItem = optionsMenu.findItem(R.id.blocklists); - MenuItem easyListMenuItem = optionsMenu.findItem(R.id.easylist); - MenuItem easyPrivacyMenuItem = optionsMenu.findItem(R.id.easyprivacy); - MenuItem fanboysAnnoyanceListMenuItem = optionsMenu.findItem(R.id.fanboys_annoyance_list); - MenuItem fanboysSocialBlockingListMenuItem = optionsMenu.findItem(R.id.fanboys_social_blocking_list); - MenuItem ultraPrivacyMenuItem = optionsMenu.findItem(R.id.ultraprivacy); - MenuItem blockAllThirdPartyRequestsMenuItem = optionsMenu.findItem(R.id.block_all_third_party_requests); - // Create an empty web resource response to be used if the resource request is blocked. WebResourceResponse emptyWebResourceResponse = new WebResourceResponse("text/plain", "utf8", new ByteArrayInputStream("".getBytes())); @@ -4802,9 +4853,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook activity.runOnUiThread(() -> { // Update the menu item titles. navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blockAllThirdPartyRequestsMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " + - getString(R.string.block_all_third_party_requests)); + + // Update the options menu if it has been populated. + if (optionsMenu != null) { + optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + optionsMenu.findItem(R.id.block_all_third_party_requests).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " + + getString(R.string.block_all_third_party_requests)); + } }); } @@ -4833,8 +4888,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook activity.runOnUiThread(() -> { // Update the menu item titles. navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - ultraPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY) + " - " + getString(R.string.ultraprivacy)); + + // Update the options menu if it has been populated. + if (optionsMenu != null) { + optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + optionsMenu.findItem(R.id.ultraprivacy).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY) + " - " + getString(R.string.ultraprivacy)); + } }); } @@ -4870,8 +4929,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook activity.runOnUiThread(() -> { // Update the menu item titles. navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - easyListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_LIST) + " - " + getString(R.string.easylist)); + + // Update the options menu if it has been populated. + if (optionsMenu != null) { + optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + optionsMenu.findItem(R.id.easylist).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_LIST) + " - " + getString(R.string.easylist)); + } }); } @@ -4904,8 +4967,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook activity.runOnUiThread(() -> { // Update the menu item titles. navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - easyPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY) + " - " + getString(R.string.easyprivacy)); + + // Update the options menu if it has been populated. + if (optionsMenu != null) { + optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + optionsMenu.findItem(R.id.easyprivacy).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY) + " - " + getString(R.string.easyprivacy)); + } }); } @@ -4938,9 +5005,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook activity.runOnUiThread(() -> { // Update the menu item titles. navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - fanboysAnnoyanceListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST) + " - " + - getString(R.string.fanboys_annoyance_list)); + + // Update the options menu if it has been populated. + if (optionsMenu != null) { + optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + optionsMenu.findItem(R.id.fanboys_annoyance_list).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST) + " - " + + getString(R.string.fanboys_annoyance_list)); + } }); } @@ -4971,9 +5042,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook activity.runOnUiThread(() -> { // Update the menu item titles. navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); - fanboysSocialBlockingListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST) + " - " + - getString(R.string.fanboys_social_blocking_list)); + + // Update the options menu if it has been populated. + if (optionsMenu != null) { + optionsMenu.findItem(R.id.blocklists).setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS)); + optionsMenu.findItem(R.id.fanboys_social_blocking_list).setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST) + " - " + + getString(R.string.fanboys_social_blocking_list)); + } }); } @@ -5031,11 +5106,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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()); + + // 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(); + // Apply text highlighting to `urlTextBox`. + highlightUrlText(); + } // Reset the list of host IP addresses. nestedScrollWebView.clearCurrentIpAddresses(); @@ -5145,30 +5226,36 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // 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. // TODO + 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 the URL. + highlightUrlText(); + } } }