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=657a2706a6f17d7f1a1dee55ab13fa8a0bf58d6a;hp=895f20ad7547b9120066d49b61d00820263877f0;hb=42ec2f56c3d05826454e5e0d48d9b7fbb4615e5a;hpb=c59144b04912acea0dd664cb677b4fc19effe9c2 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 895f20ad..657a2706 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -39,6 +39,7 @@ import android.content.res.Configuration; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -141,6 +142,7 @@ import com.stoutner.privacybrowser.views.NestedScrollWebView; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; @@ -301,6 +303,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Remove the warning about needing to override `performClick()` when using an `OnTouchListener` with `WebView`. @SuppressLint("ClickableViewAccessibility") protected void onCreate(Bundle savedInstanceState) { + if (Build.VERSION.SDK_INT >= 21) { + WebView.enableSlowWholeDocumentDraw(); + } + // Initialize the default preference values the first time the program is run. `false` keeps this command from resetting any current preferences back to default. PreferenceManager.setDefaultValues(this, R.xml.preferences, false); @@ -328,6 +334,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the content view. setContentView(R.layout.main_framelayout); + // Get handles for the views that need to be modified. DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); Toolbar toolbar = findViewById(R.id.toolbar); @@ -367,63 +374,69 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override protected void onNewIntent(Intent intent) { - // Get the information from the intent. - String intentAction = intent.getAction(); - Uri intentUriData = intent.getData(); + // Replace the intent that started the app with this one. + setIntent(intent); - // Determine if this is a web search. - boolean isWebSearch = ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)); + // 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) { + // Get the information from the intent. + String intentAction = intent.getAction(); + Uri intentUriData = intent.getData(); - // 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); + // Determine if this is a web search. + boolean isWebSearch = ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)); - // Create a URL string. - String url; + // 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); - // If the intent action is a web search, perform the search. - if (isWebSearch) { - // Create an encoded URL string. - String encodedUrlString; + // Create a URL string. + String url; - // Sanitize the search input and convert it to a search. - try { - encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8"); - } catch (UnsupportedEncodingException exception) { - encodedUrlString = ""; - } + // If the intent action is a web search, perform the search. + if (isWebSearch) { + // Create an encoded URL string. + String 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(); - } + // 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 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 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. - addNewTab(url); - } else { // Load the URL in the current tab. - // Make it so. - loadUrl(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; - // Get a handle for the drawer layout. - DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); + // Add a new tab. + addNewTab(url); + } else { // Load the URL in the current tab. + // Make it so. + loadUrl(url); + } - // Close the navigation drawer if it is open. - if (drawerLayout.isDrawerVisible(GravityCompat.START)) { - drawerLayout.closeDrawer(GravityCompat.START); - } + // Get a handle for the drawer layout. + DrawerLayout drawerLayout = findViewById(R.id.drawerlayout); - // Close the bookmarks drawer if it is open. - if (drawerLayout.isDrawerVisible(GravityCompat.END)) { - drawerLayout.closeDrawer(GravityCompat.END); + // Close the navigation drawer if it is open. + if (drawerLayout.isDrawerVisible(GravityCompat.START)) { + drawerLayout.closeDrawer(GravityCompat.START); + } + + // Close the bookmarks drawer if it is open. + if (drawerLayout.isDrawerVisible(GravityCompat.END)) { + drawerLayout.closeDrawer(GravityCompat.END); + } } } } @@ -1554,6 +1567,42 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook printManager.print(getString(R.string.privacy_browser_web_page), printDocumentAdapter, null); return true; + case R.id.save_as_image: + // Create a webpage bitmap. Once the Minimum API >= 26 Bitmap.Config.RBGA_F16 can be used instead of ARGB_8888. + Bitmap webpageBitmap = Bitmap.createBitmap(currentWebView.getHorizontalScrollRange(), currentWebView.getVerticalScrollRange(), Bitmap.Config.ARGB_8888); + + // Create a canvas. + Canvas webpageCanvas = new Canvas(webpageBitmap); + + // Draw the current webpage onto the bitmap. + currentWebView.draw(webpageCanvas); + + // Create a webpage PNG byte array output stream. + ByteArrayOutputStream webpageByteArrayOutputStream = new ByteArrayOutputStream(); + + // Convert the bitmap to a PNG. `0` is for lossless compression (the only option for a PNG). + webpageBitmap.compress(Bitmap.CompressFormat.PNG, 0, webpageByteArrayOutputStream); + + // Get a file for the image. + File imageFile = new File("/storage/emulated/0/webpage.png"); + + // Delete the current file if it exists. + if (imageFile.exists()) { + //noinspection ResultOfMethodCallIgnored + imageFile.delete(); + } + + try { + // Create an image file output stream. + FileOutputStream imageFileOutputStream = new FileOutputStream(imageFile); + + // Write the webpage image to the image file. + webpageByteArrayOutputStream.writeTo(imageFileOutputStream); + } catch (Exception exception) { + // Add a snackbar. + } + return true; + case R.id.add_to_homescreen: // Instantiate the create home screen shortcut dialog. DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), currentWebView.getUrl(), @@ -4942,6 +4991,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Check requests against the block lists. The deprecated `shouldInterceptRequest()` must be used until minimum API >= 21. @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { + // Wait until the blocklists have been populated. When Privacy Browser is being resumed after having the process killed in the background it will try to load the URLs immediately. + while (ultraPrivacy == null) { + // The wait must be synchronized, which only lets one thread run on it at a time, or `java.lang.IllegalMonitorStateException` is thrown. + synchronized (this) { + try { + // Check to see if the blocklists have been populated after 100 ms. + wait(100); + } catch (InterruptedException exception) { + // Do nothing. + } + } + } + // Sanitize the URL. url = sanitizeUrl(url);