import android.net.Uri;
import android.net.http.SslCertificate;
import android.net.http.SslError;
+import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklists.PopulateBlocklistsListener, SaveDialog.SaveWebpageListener, StoragePermissionDialog.StoragePermissionDialogListener,
UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener {
- // The executor service handles background tasks. It is accessed from `ViewSourceActivity`. TODO. Change the number of threads, or create a single thread executor.
+ // The executor service handles background tasks. It is accessed from `ViewSourceActivity`.
public static ExecutorService executorService = Executors.newFixedThreadPool(4);
// `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`, `onResume()`, and `applyProxy()`.
private ViewPager webViewPager;
// Define the class variables.
- private String newIntentUrl;
+ @SuppressWarnings("rawtypes")
+ AsyncTask populateBlocklists;
// The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
// `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxy()`, and `applyDomainSettings()`.
applyAppSettings();
// Populate the blocklists.
- new PopulateBlocklists(this, this).execute();
+ populateBlocklists = new PopulateBlocklists(this, this).execute();
}
@Override
// Replace the intent that started the app with this one.
setIntent(intent);
- // Process the intent here if Privacy Browser is fully initialized. If the process has been killed by the system while sitting in the background, this will be handled in `initializeWebView()`.
- if (ultraPrivacy != null) {
+ // Check to see if the app is being restarted.
+ if (savedStateArrayList == null || savedStateArrayList.size() == 0) { // The activity is running for the first time.
// Get the information from the intent.
String intentAction = intent.getAction();
Uri intentUriData = intent.getData();
String url;
// If the intent action is a web search, perform the search.
- if (isWebSearch) {
+ if (isWebSearch) { // The intent is a web search.
// Create an encoded URL string.
String encodedUrlString;
url = intentUriData.toString();
}
- // Check to see if the app is in the process of restarting
- if (savedStateArrayList == null) { // The app is not in the process of being restarted. Process the new intent.
- // Add a new tab if specified in the preferences.
- if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) { // Load the URL in a new tab.
- // Set the loading new intent flag.
- loadingNewIntent = true;
-
- // Add a new tab.
- addNewTab(url, true);
- } else { // Load the URL in the current tab.
- // Make it so.
- loadUrl(currentWebView, url);
- }
- } else { // The app is being restarted. Store the URL, which will be processed in `finishedPopulatingBlocklists()`.
- newIntentUrl = url;
+ // Add a new tab if specified in the preferences.
+ if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) { // Load the URL in a new tab.
+ // Set the loading new intent flag.
+ loadingNewIntent = true;
+
+ // Add a new tab.
+ addNewTab(url, true);
+ } else { // Load the URL in the current tab.
+ // Make it so.
+ loadUrl(currentWebView, url);
}
// Get a handle for the drawer layout.
bookmarksDatabaseHelper.close();
}
+ // Stop populating the blocklists if the AsyncTask is running in the background.
+ if (populateBlocklists != null) {
+ populateBlocklists.cancel(true);
+ }
+
// Run the default commands.
super.onDestroy();
}
tab.select();
};
- // Select the tab layout after 150 milliseconds, which leaves enough time for a new tab to be inflated. TODO. Switch to a post command.
+ // Select the tab layout after 150 milliseconds, which leaves enough time for a new tab to be inflated. TODO.
selectTabHandler.postDelayed(selectTabRunnable, 150);
}
}
String defaultFontSizeString = sharedPreferences.getString("font_size", getString(R.string.font_size_default_value));
String defaultUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
boolean defaultSwipeToRefresh = sharedPreferences.getBoolean("swipe_to_refresh", true);
+ String webViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
boolean wideViewport = sharedPreferences.getBoolean("wide_viewport", true);
boolean displayWebpageImages = sharedPreferences.getBoolean("display_webpage_images", true);
+ // Get the WebView theme entry values string array.
+ String[] webViewThemeEntryValuesStringArray = getResources().getStringArray(R.array.webview_theme_entry_values);
+
// Get a handle for the cookie manager.
CookieManager cookieManager = CookieManager.getInstance();
// Set the WebView theme.
switch (webViewThemeInt) {
case DomainsDatabaseHelper.SYSTEM_DEFAULT:
- // // Ge the current system theme status.
- int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
- // Set the WebView theme according to the current system theme status.
- if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { // The system is in day mode.
+ // Set the WebView theme. A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
+ if (webViewTheme.equals(webViewThemeEntryValuesStringArray[1])) { // The light theme is selected.
// Turn off the WebView dark mode.
WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
- } else { // The system is in night mode.
+ } else if (webViewTheme.equals(webViewThemeEntryValuesStringArray[2])) { // The dark theme is selected.
// Turn on the WebView dark mode.
WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
+ } else { // The system default theme is selected.
+ // Get the current system theme status.
+ int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+
+ // Set the WebView theme according to the current system theme status.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { // The system is in day mode.
+ // Turn off the WebView dark mode.
+ WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF);
+ } else { // The system is in night mode.
+ // Turn on the WebView dark mode.
+ WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
+ }
}
break;
nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRALIST, sharedPreferences.getBoolean("ultralist", true));
nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRAPRIVACY, sharedPreferences.getBoolean("ultraprivacy", true));
nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, sharedPreferences.getBoolean("block_all_third_party_requests", false));
- String webViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
// Apply the default first-party cookie setting.
cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptFirstPartyCookies());
nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[userAgentArrayPosition]);
}
- // Get the WebView theme entry values string array.
- String[] webViewThemeEntryValuesStringArray = getResources().getStringArray(R.array.webview_theme_entry_values);
-
// Apply the WebView theme if supported by the installed WebView.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
// Set the WebView theme. A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
webViewPager.setCurrentItem(savedTabPosition);
}
- // Process the new intent if it exists.
- if (newIntentUrl != null) {
+ // Get the intent that started the app.
+ Intent intent = getIntent();
+
+ // Get the information from the intent.
+ String intentAction = intent.getAction();
+ Uri intentUriData = intent.getData();
+
+ // 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);
+ // Create a URL string.
+ String url;
+
+ // If the intent action is a web search, perform the search.
+ if (isWebSearch) { // The intent is a web search.
+ // Create an encoded URL string.
+ String encodedUrlString;
+
+ // Sanitize the search input and convert it to a search.
+ try {
+ encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
+ } catch (UnsupportedEncodingException exception) {
+ encodedUrlString = "";
+ }
+
+ // Add the base search URL.
+ url = searchURL + encodedUrlString;
+ } else { // The intent should contain a URL.
+ // Set the intent data as the url.
+ url = intentUriData.toString();
+ }
+
// Add a new tab if specified in the preferences.
if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) { // Load the URL in a new tab.
// Set the loading new intent flag.
loadingNewIntent = true;
// Add a new tab.
- addNewTab(newIntentUrl, true);
+ addNewTab(url, true);
} else { // Load the URL in the current tab.
// Make it so.
- loadUrl(currentWebView, newIntentUrl);
+ loadUrl(currentWebView, url);
}
-
- // Reset the new intent URL.
- newIntentUrl = null;
}
}
}
} else {
urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.color.transparent, null));
}
- } else { // The fragment has not been populated. Try again in 100 milliseconds. //TODO try to replace this with a post command.
+ } else { // The fragment has not been populated. Try again in 100 milliseconds.
// Create a handler to set the current WebView.
Handler setCurrentWebViewHandler = new Handler();
// 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;
+ // Only populate the title text view if the tab view has been fully populated.
+ if (tabView != null) {
+ // Get the title text view from the tab.
+ TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
- // Get the title text view from the tab.
- TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
-
- // Set the title according to the URL.
- if (title.equals("about:blank")) {
- // Set the title to indicate a new tab.
- tabTitleTextView.setText(R.string.new_tab);
- } else {
- // Set the title as the tab text.
- tabTitleTextView.setText(title);
+ // Set the title according to the URL.
+ if (title.equals("about:blank")) {
+ // Set the title to indicate a new tab.
+ tabTitleTextView.setText(R.string.new_tab);
+ } else {
+ // Set the title as the tab text.
+ tabTitleTextView.setText(title);
+ }
}
}
}