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=a758fedebb87bc0b883af47524c6efb283404bb0;hp=76542cb8d3ebc0d6020ac9ebcf1ec376cffc049f;hb=6fa2fbb5a767bbe036daae06b0da883c4bafb798;hpb=d420aa6be32a78b27905074edc3881a6e71d2263 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 76542cb8..a758fede 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -25,6 +25,7 @@ import android.Manifest; import android.annotation.SuppressLint; import android.app.DialogFragment; import android.app.DownloadManager; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ClipData; import android.content.ClipboardManager; @@ -108,7 +109,6 @@ import android.widget.TextView; import com.stoutner.privacybrowser.BannerAd; import com.stoutner.privacybrowser.BuildConfig; import com.stoutner.privacybrowser.R; -import com.stoutner.privacybrowser.dialogs.AddDomainDialog; import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog; import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog; import com.stoutner.privacybrowser.dialogs.CreateHomeScreenShortcutDialog; @@ -145,11 +145,11 @@ import java.util.Map; import java.util.Set; // 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 AddDomainDialog.AddDomainListener, CreateBookmarkDialog.CreateBookmarkListener, - CreateBookmarkFolderDialog.CreateBookmarkFolderListener, CreateHomeScreenShortcutDialog.CreateHomeScreenSchortcutListener, DownloadFileDialog.DownloadFileListener, - DownloadImageDialog.DownloadImageListener, DownloadLocationPermissionDialog.DownloadLocationPermissionDialogListener, EditBookmarkDialog.EditBookmarkListener, - EditBookmarkFolderDialog.EditBookmarkFolderListener, HttpAuthenticationDialog.HttpAuthenticationListener, NavigationView.OnNavigationItemSelectedListener, - PinnedSslCertificateMismatchDialog.PinnedSslCertificateMismatchListener, SslCertificateErrorDialog.SslCertificateErrorListener, UrlHistoryDialog.UrlHistoryListener { +public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, + CreateHomeScreenShortcutDialog.CreateHomeScreenSchortcutListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener, + DownloadLocationPermissionDialog.DownloadLocationPermissionDialogListener, EditBookmarkDialog.EditBookmarkListener, EditBookmarkFolderDialog.EditBookmarkFolderListener, + HttpAuthenticationDialog.HttpAuthenticationListener, NavigationView.OnNavigationItemSelectedListener, PinnedSslCertificateMismatchDialog.PinnedSslCertificateMismatchListener, + SslCertificateErrorDialog.SslCertificateErrorListener, UrlHistoryDialog.UrlHistoryListener { // `darkTheme` is public static so it can be accessed from `AboutActivity`, `GuideActivity`, `AddDomainDialog`, `SettingsActivity`, `DomainsActivity`, `DomainsListFragment`, `BookmarksActivity`, // `BookmarksDatabaseViewActivity`, `CreateBookmarkDialog`, `CreateBookmarkFolderDialog`, `DownloadFileDialog`, `DownloadImageDialog`, `EditBookmarkDialog`, `EditBookmarkFolderDialog`, @@ -282,12 +282,15 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD // The block list variables are used in `onCreate()` and `applyAppSettings()`. private boolean easyListEnabled; private boolean easyPrivacyEnabled; - private boolean fanboyAnnoyanceListEnabled; - private boolean fanboySocialBlockingListEnabled; + private boolean fanboysAnnoyanceListEnabled; + private boolean fanboysSocialBlockingListEnabled; // `privacyBrowserRuntime` is used in `onCreate()`, `onOptionsItemSelected()`, and `applyAppSettings()`. private Runtime privacyBrowserRuntime; + // `proxyThroughOrbot` is used in `onRestart()` and `applyAppSettings()`. + boolean proxyThroughOrbot; + // `incognitoModeEnabled` is used in `onCreate()` and `applyAppSettings()`. private boolean incognitoModeEnabled; @@ -1078,46 +1081,68 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD mainWebView.setWebViewClient(new WebViewClient() { // `shouldOverrideUrlLoading` makes this `WebView` the default handler for URLs inside the app, so that links are not kicked out to other apps. - // We have to use the deprecated `shouldOverrideUrlLoading` until API >= 24. + // The deprecated `shouldOverrideUrlLoading` must be used until API >= 24. @SuppressWarnings("deprecation") @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (url.startsWith("mailto:")) { // Load the email address in an external email program. + if (url.startsWith("http")) { // Load the URL in Privacy Browser. + // Apply the domain settings for the new URL. + applyDomainSettings(url, true); + + // Returning false causes the current `WebView` to handle the URL and prevents it from adding redirects to the history list. + return false; + } else if (url.startsWith("mailto:")) { // Load the email address in an external email program. // Use `ACTION_SENDTO` instead of `ACTION_SEND` so that only email programs are launched. Intent emailIntent = new Intent(Intent.ACTION_SENDTO); - // Parse the url and set it as the data for the `Intent`. + // Parse the url and set it as the data for the intent. emailIntent.setData(Uri.parse(url)); - // `FLAG_ACTIVITY_NEW_TASK` opens the email program in a new task instead as part of Privacy Browser. + // Open the email program in a new task instead of as part of Privacy Browser. emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Make it so. startActivity(emailIntent); - // Returning `true` indicates the application is handling the URL. + // Returning true indicates Privacy Browser is handling the URL by creating an intent. return true; } else if (url.startsWith("tel:")) { // Load the phone number in the dialer. - // `ACTION_DIAL` open the dialer and loads the phone number, but waits for the user to place the call. + // Open the dialer and load the phone number, but wait for the user to place the call. Intent dialIntent = new Intent(Intent.ACTION_DIAL); // Add the phone number to the intent. dialIntent.setData(Uri.parse(url)); - // `FLAG_ACTIVITY_NEW_TASK` opens the dialer in a new task instead as part of Privacy Browser. + // Open the dialer in a new task instead of as part of Privacy Browser. dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Make it so. startActivity(dialIntent); - // Returning `true` indicates the application is handling the URL. + // Returning true indicates Privacy Browser is handling the URL by creating an intent. return true; - } else { // Load the URL in Privacy Browser. - // Apply the domain settings for the new URL. - applyDomainSettings(url, true); + } else { // Load a system chooser to select an app that can handle the URL. + // Open an app that can handle the URL. + Intent genericIntent = new Intent(Intent.ACTION_VIEW); - // Returning `false` causes the current `WebView` to handle the URL and prevents it from adding redirects to the history list. - return false; + // Add the URL to the intent. + genericIntent.setData(Uri.parse(url)); + + // List all apps that can handle the URL instead of just opening the first one. + genericIntent.addCategory(Intent.CATEGORY_BROWSABLE); + + // Open the app in a new task instead of as part of Privacy Browser. + genericIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // Start the app or display a snackbar if no app is available to handle the URL. + try { + startActivity(genericIntent); + } catch (ActivityNotFoundException exception) { + Snackbar.make(mainWebView, getString(R.string.unrecognized_url) + " " + url, Snackbar.LENGTH_SHORT).show(); + } + + // Returning true indicates Privacy Browser is handling the URL by creating an intent. + return true; } } @@ -1145,12 +1170,12 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD } // Check Fanboy’s Annoyance List if it is enabled. - if (fanboyAnnoyanceListEnabled) { + if (fanboysAnnoyanceListEnabled) { if (blockListHelper.isBlocked(formattedUrlString, url, fanboyAnnoyance)) { // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; } - } else if (fanboySocialBlockingListEnabled){ // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled. + } else if (fanboysSocialBlockingListEnabled){ // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled. if (blockListHelper.isBlocked(formattedUrlString, url, fanboySocial)) { // The resource request was blocked. Return an empty web resource response. return emptyWebResourceResponse; @@ -1224,11 +1249,12 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD // Manually delete cache folders. try { - // Delete the main `cache` folder. + // Delete the main cache directory. privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/cache"); - // Delete the `app_webview` folder, which contains an additional `WebView` cache. See `https://code.google.com/p/android/issues/detail?id=233826&thanks=233826&ts=1486670530`. - privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview"); + // Delete the secondary `Service Worker` cache directory. + // A `String[]` must be used because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise. + privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"}); } catch (IOException e) { // Do nothing if an error is thrown. } @@ -1391,6 +1417,11 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD drawerLayout.closeDrawer(GravityCompat.START); } + // Close the bookmarks drawer if it is open. + if (drawerLayout.isDrawerVisible(GravityCompat.END)) { + drawerLayout.closeDrawer(GravityCompat.END); + } + // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it. mainWebView.requestFocus(); } @@ -1401,6 +1432,18 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD // Run the default commands. super.onRestart(); + // Make sure Orbot is running if Privacy Browser is proxying through Orbot. + if (proxyThroughOrbot) { + // Request Orbot to start. If Orbot is already running no hard will be caused by this request. + Intent orbotIntent = new Intent("org.torproject.android.intent.action.START"); + + // Send the intent to the Orbot package. + orbotIntent.setPackage("org.torproject.android"); + + // Make it so. + sendBroadcast(orbotIntent); + } + // Apply the app settings if returning from the Settings activity.. if (reapplyAppSettingsOnRestart) { // Apply the app settings. @@ -1680,9 +1723,28 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD // Make it so. startActivity(domainsIntent); } else { // Add a new domain. - // Show the add domain `AlertDialog`. - AppCompatDialogFragment addDomainDialog = new AddDomainDialog(); - addDomainDialog.show(getSupportFragmentManager(), getResources().getString(R.string.add_domain)); + // Apply the new domain settings on returning to `MainWebViewActivity`. + reapplyDomainSettingsOnRestart = true; + currentDomainName = ""; + + // Get the current domain + Uri currentUri = Uri.parse(formattedUrlString); + String currentDomain = currentUri.getHost(); + + // Initialize the database handler. The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. + DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0); + + // Create the domain and store the database ID. + int newDomainDatabaseId = domainsDatabaseHelper.addDomain(currentDomain); + + // Create an intent to launch the domains activity. + Intent domainsIntent = new Intent(this, DomainsActivity.class); + + // Put extra information instructing the domains activity to directly load the new domain. + domainsIntent.putExtra("LoadDomain", newDomainDatabaseId); + + // Make it so. + startActivity(domainsIntent); } return true; @@ -2168,8 +2230,9 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD try { // Delete the main cache directory. privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/cache"); + // Delete the secondary `Service Worker` cache directory. - // We have to use a `String[]` because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise. + // A `String[]` must be used because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise. privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"}); } catch (IOException e) { // Do nothing if an error is thrown. @@ -2447,33 +2510,6 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD } } - @Override - public void onAddDomain(AppCompatDialogFragment dialogFragment) { - // Reapply the domain settings on returning to `MainWebViewActivity`. - reapplyDomainSettingsOnRestart = true; - currentDomainName = ""; - - // Get the new domain name `String` from `dialogFragment`. - EditText domainNameEditText = dialogFragment.getDialog().findViewById(R.id.domain_name_edittext); - String domainNameString = domainNameEditText.getText().toString(); - - // Initialize the database handler. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. - // The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. - DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0); - - // Create the domain and store the database ID in `currentDomainDatabaseId`. - int newDomainDatabaseId = domainsDatabaseHelper.addDomain(domainNameString); - - // Create an intent to launch the domains activity. - Intent domainsIntent = new Intent(this, DomainsActivity.class); - - // Put extra information instructing the domains activity to directly load the current domain. - domainsIntent.putExtra("LoadDomain", newDomainDatabaseId); - - // Make it so. - startActivity(domainsIntent); - } - @Override public void onCreateBookmark(AppCompatDialogFragment dialogFragment) { // Get the `EditTexts` from the `dialogFragment`. @@ -3020,13 +3056,9 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD String torSearchCustomURLString = sharedPreferences.getString("tor_search_custom_url", ""); String searchString = sharedPreferences.getString("search", "https://duckduckgo.com/html/?q="); String searchCustomURLString = sharedPreferences.getString("search_custom_url", ""); - easyListEnabled = sharedPreferences.getBoolean("easylist", true); - easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true); - fanboyAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true); - fanboySocialBlockingListEnabled = sharedPreferences.getBoolean("fanboy_social_blocking_list", true); incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false); boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false); - boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); + proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false); hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false); translucentNavigationBarOnFullscreen = sharedPreferences.getBoolean("translucent_navigation_bar", true); @@ -3277,6 +3309,10 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD thirdPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1); domStorageEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1); saveFormDataEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1); + easyListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYLIST)) == 1); + easyPrivacyEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY)) == 1); + fanboysAnnoyanceListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST)) == 1); + fanboysSocialBlockingListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST)) == 1); String userAgentString = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT)); int fontSize = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE)); displayWebpageImagesInt = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES)); @@ -3390,6 +3426,10 @@ public class MainWebViewActivity extends AppCompatActivity implements AddDomainD thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false); domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false); saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false); + easyListEnabled = sharedPreferences.getBoolean("easylist", true); + easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true); + fanboysAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboy_annoyance_list", true); + fanboysSocialBlockingListEnabled = sharedPreferences.getBoolean("fanboy_social_blocking_list", true); // Set `javaScriptEnabled` to be `true` if `night_mode` is `true`. if (nightMode) {