import android.app.Activity;
import android.app.DialogFragment;
import android.app.DownloadManager;
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintManager;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.app.AppCompatDialogFragment;
import android.support.v7.widget.Toolbar;
import android.util.Patterns;
import android.view.KeyEvent;
SslCertificateError.SslCertificateErrorListener, DownloadFile.DownloadFileListener {
// `appBar` is public static so it can be accessed from `OrbotProxyHelper`.
- // It is also used in `onCreate()`.
+ // It is also used in `onCreate()` and `onOptionsItemSelected()`.
public static ActionBar appBar;
// `favoriteIcon` is public static so it can be accessed from `CreateHomeScreenShortcut`, `BookmarksActivity`, `CreateBookmark`, `CreateBookmarkFolder`, and `EditBookmark`.
// `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`.
private SslErrorHandler sslErrorHandler;
+ private MenuItem toggleJavaScript;
+
@Override
// Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled. The whole premise of Privacy Browser is built around an understanding of these dangers.
@SuppressLint("SetJavaScriptEnabled")
// This is needed to get rid of the Android Studio warning that appBar might be null.
assert appBar != null;
- // Add the custom url_bar layout, which shows the favoriteIcon, urlTextBar, and progressBar.
- appBar.setCustomView(R.layout.url_bar);
+ // Add the custom url_app_bar layout, which shows the favoriteIcon, urlTextBar, and progressBar.
+ appBar.setCustomView(R.layout.url_app_bar);
appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
// Set the "go" button on the keyboard to load the URL in urlTextBox.
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
// Show the `DownloadFile` `AlertDialog` and name this instance `@string/download`.
- DialogFragment downloadFileDialogFragment = DownloadFile.fromUrl(url, contentDisposition, contentLength);
- downloadFileDialogFragment.show(getFragmentManager(), getResources().getString(R.string.download));
+ AppCompatDialogFragment downloadFileDialogFragment = DownloadFile.fromUrl(url, contentDisposition, contentLength);
+ downloadFileDialogFragment.show(getSupportFragmentManager(), getResources().getString(R.string.download));
}
});
// Set mainMenu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons`.
mainMenu = menu;
- // Set the initial status of the privacy icons.
- updatePrivacyIcons();
+ // Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(false);
// Get handles for the menu items.
+ toggleJavaScript = menu.findItem(R.id.toggleJavaScript);
MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies);
MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies);
MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
// Apply the new JavaScript status.
mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
- // Update the privacy icon.
- updatePrivacyIcons();
+ // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(true);
// Display a `Snackbar`.
if (javaScriptEnabled) { // JavaScrip is enabled.
// Apply the new cookie status.
cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
- // Update the privacy icon.
- updatePrivacyIcons();
+ // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(true);
// Display a `Snackbar`.
if (firstPartyCookiesEnabled) { // First-party cookies are enabled.
// Apply the new DOM Storage status.
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
+ // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(true);
+
// Display a `Snackbar`.
if (domStorageEnabled) {
Snackbar.make(findViewById(R.id.mainWebView), R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.mainWebView), R.string.form_data_disabled, Snackbar.LENGTH_SHORT).show();
}
+ // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(true);
+
// Reload the WebView.
mainWebView.reload();
return true;
mainWebView.getSettings().setTextZoom(200);
return true;
+ case R.id.find_on_page:
+ appBar.setCustomView(R.layout.find_on_page_app_bar);
+ toggleJavaScript.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ appBar.invalidateOptionsMenu();
+ return true;
+
case R.id.share:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
case R.id.addToHomescreen:
// Show the `CreateHomeScreenShortcut` `AlertDialog` and name this instance `@string/create_shortcut`.
- DialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcut();
- createHomeScreenShortcutDialogFragment.show(getFragmentManager(), getResources().getString(R.string.create_shortcut));
+ AppCompatDialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcut();
+ createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getResources().getString(R.string.create_shortcut));
//Everything else will be handled by `CreateHomeScreenShortcut` and the associated listener below.
return true;
+ case R.id.print:
+ // Get a `PrintManager` instance.
+ PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
+
+ // Convert `mainWebView` to `printDocumentAdapter`.
+ PrintDocumentAdapter printDocumentAdapter = mainWebView.createPrintDocumentAdapter();
+
+ // Print the document. The print attributes are `null`.
+ printManager.print(getResources().getString(R.string.privacy_browser_web_page), printDocumentAdapter, null);
+ return true;
+
case R.id.refresh:
mainWebView.reload();
return true;
adView = findViewById(R.id.adView);
// `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug: https://code.google.com/p/android/issues/detail?id=20493#c8
- invalidateOptionsMenu();
+ // ActivityCompat.invalidateOptionsMenu(this);
}
@Override
- public void onCreateHomeScreenShortcut(DialogFragment dialogFragment) {
+ public void onCreateHomeScreenShortcut(AppCompatDialogFragment dialogFragment) {
// Get shortcutNameEditText from the alert dialog.
EditText shortcutNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.shortcut_name_edittext);
}
@Override
- public void onDownloadFile(DialogFragment dialogFragment, String downloadUrl) {
+ public void onDownloadFile(AppCompatDialogFragment dialogFragment, String downloadUrl) {
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(downloadUrl));
EditText downloadFileNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.download_file_name);
String fileName = downloadFileNameEditText.getText().toString();
- // Set the download save in the the `DIRECTORY_DOWNLOADS`using `fileName`.
// Once we have `WRITE_EXTERNAL_STORAGE` permissions we can use `setDestinationInExternalPublicDir`.
- downloadRequest.setDestinationInExternalFilesDir(this, "/", fileName);
+ if (Build.VERSION.SDK_INT >= 23) { // If API >= 23, set the download save in the the `DIRECTORY_DOWNLOADS` using `fileName`.
+ downloadRequest.setDestinationInExternalFilesDir(this, "/", fileName);
+ } else { // Only set the title using `fileName`.
+ downloadRequest.setTitle(fileName);
+ }
// Allow `MediaScanner` to index the download if it is a media file.
downloadRequest.allowScanningByMediaScanner();
// Apply the settings from shared preferences, which might have been changed in `SettingsActivity`.
applySettings();
- // Update the privacy icons.
- updatePrivacyIcons();
+ // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
+ updatePrivacyIcons(true);
}
}
}
- private void updatePrivacyIcons() {
+ private void updatePrivacyIcons(boolean runInvalidateOptionsMenu) {
// Get handles for the icons.
MenuItem privacyIcon = mainMenu.findItem(R.id.toggleJavaScript);
MenuItem firstPartyCookiesIcon = mainMenu.findItem(R.id.toggleFirstPartyCookies);
// Update `domStorageIcon`.
if (javaScriptEnabled && domStorageEnabled) { // Both JavaScript and DOM storage are enabled.
domStorageIcon.setIcon(R.drawable.dom_storage_enabled);
- } else if (javaScriptEnabled){ // JavaScript is enabled but DOM storage is disabled.
+ } else if (javaScriptEnabled) { // JavaScript is enabled but DOM storage is disabled.
domStorageIcon.setIcon(R.drawable.dom_storage_disabled);
} else { // JavaScript is disabled, so DOM storage is ghosted.
domStorageIcon.setIcon(R.drawable.dom_storage_ghosted);
formDataIcon.setIcon(R.drawable.form_data_disabled);
}
- // `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`.
- // `this` references the current activity.
- ActivityCompat.invalidateOptionsMenu(this);
+ // `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`. `this` references the current activity.
+ if (runInvalidateOptionsMenu) {
+ ActivityCompat.invalidateOptionsMenu(this);
+ }
}
}