applicationId "com.stoutner.privacybrowser.free"
}
}
- // `return true` removes the lint error: `Not all execution paths return a value`.
- return true
+
+ // `return void` removes the lint error: `Not all execution paths return a value`.
+ return void
}
dependencies {
+++ /dev/null
-package com.stoutner.privacybrowser;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
- */
-public class ApplicationTest extends ApplicationTestCase<Application> {
- public ApplicationTest() {
- super(Application.class);
- }
-}
\ No newline at end of file
import com.google.android.gms.ads.AdView;
class BannerAd extends AppCompatActivity{
- public static void requestAd(View view) {
+ static void requestAd(View view) {
// Cast view to an AdView.
AdView adView = (AdView) view;
adView.loadAd(adRequest);
}
- public static void reloadAfterRotate (View view, Context applicationContext, String ad_id) {
+ static void reloadAfterRotate (View view, Context applicationContext, String ad_id) {
// Cast view to an AdView.
AdView adView = (AdView) view;
adView.loadAd(adRequest);
}
- public static void hideAd(View view) {
+ static void hideAd(View view) {
// Cast view to an AdView.
AdView adView = (AdView) view;
adView.setVisibility(View.GONE);
}
- public static void showAd(View view) {
+ static void showAd(View view) {
// Cast view to an AdView.
AdView adView = (AdView) view;
adView.setVisibility(View.VISIBLE);
}
- public static void pauseAd(View view) {
+ static void pauseAd(View view) {
// Cast view to an AdView.
AdView adView = (AdView) view;
adView.pause();
}
- public static void resumeAd(View view) {
+ static void resumeAd(View view) {
// Cast view to an AdView.
AdView adView = (AdView) view;
// Setup the ViewPager.
ViewPager aboutViewPager = (ViewPager) findViewById(R.id.about_viewpager);
- assert aboutViewPager != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutViewPager might be null.
aboutViewPager.setAdapter(new aboutPagerAdapter(getSupportFragmentManager()));
// Setup the TabLayout and connect it to the ViewPager.
TabLayout aboutTabLayout = (TabLayout) findViewById(R.id.about_tablayout);
- assert aboutTabLayout != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutTabLayout might be null.
aboutTabLayout.setupWithViewPager(aboutViewPager);
}
public class aboutPagerAdapter extends FragmentPagerAdapter {
- public aboutPagerAdapter(FragmentManager fm) {
+ private aboutPagerAdapter(FragmentManager fm) {
super(fm);
}
String webKitLabel = getString(R.string.webkit) + " ";
String chromeLabel = getString(R.string.chrome) + " ";
- // `webViewLayout` is only used to get the default user agent from `about_tab_webview`. It is not used to render content on the screen.
- View webViewLayout = inflater.inflate(R.layout.about_tab_webview, container, false);
- WebView tabLayoutWebView = (WebView) webViewLayout.findViewById(R.id.about_tab_webview);
+ // `webViewLayout` is only used to get the default user agent from `bare_webview`. It is not used to render content on the screen.
+ View webViewLayout = inflater.inflate(R.layout.bare_webview, container, false);
+ WebView tabLayoutWebView = (WebView) webViewLayout.findViewById(R.id.bare_webview);
String userAgentString = tabLayoutWebView.getSettings().getUserAgentString();
// Get the device's information and store it in strings.
SpannableStringBuilder chromeStringBuilder = new SpannableStringBuilder(chromeLabel + chrome);
// Create a blue `ForegroundColorSpan`. We have to use the deprecated `getColor` until API >= 23.
- ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700));
+ @SuppressWarnings("deprecation") ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700));
// Setup the spans to display the device information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
brandStringBuilder.setSpan(blueColorSpan, brandLabel.length(), brandStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
} else { // load a WebView for all the other tabs. Tab numbers start at 0.
// Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container.
// The fragment will take care of attaching the root automatically.
- tabLayout = inflater.inflate(R.layout.about_tab_webview, container, false);
+ tabLayout = inflater.inflate(R.layout.bare_webview, container, false);
WebView tabWebView = (WebView) tabLayout;
switch (tabNumber) {
public class BookmarksActivity extends AppCompatActivity implements CreateBookmark.CreateBookmarkListener,
CreateBookmarkFolder.CreateBookmarkFolderListener, EditBookmark.EditBookmarkListener,
EditBookmarkFolder.EditBookmarkFolderListener, MoveToFolder.MoveToFolderListener {
+
// `bookmarksDatabaseHandler` is public static so it can be accessed from `EditBookmark` and `MoveToFolder`. It is also used in `onCreate()`,
// `onCreateBookmarkCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`.
public static BookmarksDatabaseHandler bookmarksDatabaseHandler;
- // `bookmarksListView` is public static so it can be accessed from `EditBookmark`.
- // It is also used in `onCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`.
- public static ListView bookmarksListView;
-
// `currentFolder` is public static so it can be accessed from `MoveToFolder`.
// It is used in `onCreate`, `onOptionsItemSelected()`, `onCreateBookmarkCreate`, `onCreateBookmarkFolderCreate`, and `onEditBookmarkSave`.
public static String currentFolder;
+ // `checkedItemIds` is public static so it can be accessed from `EditBookmark`, `EditBookmarkFolder`, and `MoveToFolder`.
+ // It is also used in `onActionItemClicked`.
+ public static long[] checkedItemIds;
+
+
+ // `bookmarksListView` is used in `onCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`.
+ private ListView bookmarksListView;
+
// `contextualActionMode` is used in `onCreate()` and `onEditBookmarkSave()`.
private ActionMode contextualActionMode;
- // `selectedBookmarkPosition` is used in `onCreate()` and `onEditBookarkSave()`.
+ // `selectedBookmarkPosition` is used in `onCreate()` and `onEditBookmarkSave()`.
private int selectedBookmarkPosition;
// `appBar` is used in `onCreate()` and `updateBookmarksListView()`.
// Reload the ListView with `currentFolder`.
updateBookmarksListView(currentFolder);
} else { // Load the URL into `mainWebView`.
- // Get the bookmark URL and assign it to formattedUrlString.
+ // Get the bookmark URL and assign it to formattedUrlString. `mainWebView` will automatically reload when `BookmarksActivity` closes.
MainWebViewActivity.formattedUrlString = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_URL));
- // Load formattedUrlString and return to the main activity.
- MainWebViewActivity.mainWebView.loadUrl(MainWebViewActivity.formattedUrlString, MainWebViewActivity.customHeaders);
NavUtils.navigateUpFromSameTask(bookmarksActivity);
}
break;
case R.id.move_to_folder:
+ // Store `checkedItemIds` for use by the `AlertDialog`.
+ checkedItemIds = bookmarksListView.getCheckedItemIds();
+
// Show the `MoveToFolder` `AlertDialog` and name the instance `@string/move_to_folder
DialogFragment moveToFolderDialog = new MoveToFolder();
moveToFolderDialog.show(getFragmentManager(), getResources().getString(R.string.move_to_folder));
bookmarksCursor.moveToPosition(selectedBookmarkPosition);
boolean isFolder = (bookmarksCursor.getInt(bookmarksCursor.getColumnIndex(BookmarksDatabaseHandler.IS_FOLDER)) == 1);
+ // Store `checkedItemIds` for use by the `AlertDialog`.
+ checkedItemIds = bookmarksListView.getCheckedItemIds();
+
if (isFolder) {
// Save the current folder name.
oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_NAME));
.setCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar snackbar, int event) {
+ // Android Studio wants to see entries for every possible `Snackbar.Callback` even if they aren't used.
switch (event) {
// The user pushed the "Undo" button.
case Snackbar.Callback.DISMISS_EVENT_ACTION:
break;
+ case Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE:
+ // Do nothing and let the default behavior run.
+
+ case Snackbar.Callback.DISMISS_EVENT_MANUAL:
+ // Do nothing and let the default behavior run.
+
+ case Snackbar.Callback.DISMISS_EVENT_SWIPE:
+ // Do nothing and let the default behavior run.
+
+ case Snackbar.Callback.DISMISS_EVENT_TIMEOUT:
+ // Do nothing and let the default behavior run.
+
// The Snackbar was dismissed without the "Undo" button being pushed.
default:
// Delete each selected row.
// Set a FloatingActionButton for creating new bookmarks.
FloatingActionButton createBookmarkFAB = (FloatingActionButton) findViewById(R.id.create_bookmark_fab);
- assert createBookmarkFAB != null;
createBookmarkFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Make the font bold for folders.
if (cursor.getInt(cursor.getColumnIndex(BookmarksDatabaseHandler.IS_FOLDER)) == 1) {
- // The first argument is `null` because we don't want to chage the font.
+ // The first argument is `null` because we don't want to change the font.
bookmarkNameTextView.setTypeface(null, Typeface.BOLD);
} else { // Reset the font to default.
bookmarkNameTextView.setTypeface(Typeface.DEFAULT);
// Make the font bold for folders.
if (cursor.getInt(cursor.getColumnIndex(BookmarksDatabaseHandler.IS_FOLDER)) == 1) {
- // The first argument is `null` because we don't want to chage the font.
+ // The first argument is `null` because we don't want to change the font.
bookmarkNameTextView.setTypeface(null, Typeface.BOLD);
} else { // Reset the font to default.
bookmarkNameTextView.setTypeface(Typeface.DEFAULT);
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
-public class BookmarksDatabaseHandler extends SQLiteOpenHelper {
+class BookmarksDatabaseHandler extends SQLiteOpenHelper {
private static final int SCHEMA_VERSION = 1;
private static final String BOOKMARKS_DATABASE = "bookmarks.db";
private static final String BOOKMARKS_TABLE = "bookmarks";
- public static final String _ID = "_id";
- public static final String DISPLAY_ORDER = "displayorder";
- public static final String BOOKMARK_NAME = "bookmarkname";
- public static final String BOOKMARK_URL = "bookmarkurl";
- public static final String PARENT_FOLDER = "parentfolder";
- public static final String IS_FOLDER = "isfolder";
- public static final String FAVORITE_ICON = "favoriteicon";
+ static final String _ID = "_id";
+ static final String DISPLAY_ORDER = "displayorder";
+ static final String BOOKMARK_NAME = "bookmarkname";
+ static final String BOOKMARK_URL = "bookmarkurl";
+ static final String PARENT_FOLDER = "parentfolder";
+ static final String IS_FOLDER = "isfolder";
+ static final String FAVORITE_ICON = "favoriteicon";
- public BookmarksDatabaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
+ // Initialize the database. The lint warnings for the unused parameters are suppressed.
+ BookmarksDatabaseHandler(Context context, @SuppressWarnings("UnusedParameters") String name, SQLiteDatabase.CursorFactory factory, @SuppressWarnings("UnusedParameters") int version) {
super(context, BOOKMARKS_DATABASE, factory, SCHEMA_VERSION);
}
// Code for upgrading the database will be added here when the schema version > 1.
}
- public void createBookmark(String bookmarkName, String bookmarkURL, int displayOrder, String parentFolder, byte[] favoriteIcon) {
+ void createBookmark(String bookmarkName, String bookmarkURL, int displayOrder, String parentFolder, byte[] favoriteIcon) {
ContentValues bookmarkContentValues = new ContentValues();
// ID is created automatically.
bookmarksDatabase.close();
}
- public void createFolder(String folderName, int displayOrder, String parentFolder, byte[] favoriteIcon) {
+ void createFolder(String folderName, int displayOrder, String parentFolder, byte[] favoriteIcon) {
ContentValues bookmarkContentValues = new ContentValues();
// ID is created automatically.
bookmarksDatabase.close();
}
- public Cursor getBookmarkCursor(int databaseId) {
+ Cursor getBookmarkCursor(int databaseId) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_ONE_BOOKMARK, null);
}
- public String getFolderName (int databaseId) {
+ String getFolderName (int databaseId) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return folderName;
}
- public Cursor getFolderCursor(String folderName) {
+ Cursor getFolderCursor(String folderName) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_FOLDER, null);
}
- public Cursor getFoldersCursorExcept(String exceptFolders) {
+ Cursor getFoldersCursorExcept(String exceptFolders) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_FOLDERS_EXCEPT, null);
}
- public Cursor getSubfoldersCursor(String currentFolder) {
+ Cursor getSubfoldersCursor(String currentFolder) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_SUBFOLDERS, null);
}
- public String getParentFolder(String currentFolder) {
+ String getParentFolder(String currentFolder) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return parentFolder;
}
- public Cursor getAllBookmarksCursor() {
+ Cursor getAllBookmarksCursor() {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null);
}
- public Cursor getAllBookmarksCursorByDisplayOrder(String folderName) {
+ Cursor getAllBookmarksCursorByDisplayOrder(String folderName) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null);
}
- public Cursor getBookmarksCursorExcept(long[] exceptIdLongArray, String folderName) {
+ Cursor getBookmarksCursorExcept(long[] exceptIdLongArray, String folderName) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return bookmarksDatabase.rawQuery(GET_All_BOOKMARKS_EXCEPT_SPECIFIED, null);
}
- public boolean isFolder(int databaseId) {
+ boolean isFolder(int databaseId) {
// Get a readable database handle.
SQLiteDatabase bookmarksDatabase = this.getReadableDatabase();
return isFolder;
}
- public void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl) {
+ void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl) {
// Store the updated values in `bookmarkContentValues`.
ContentValues bookmarkContentValues = new ContentValues();
bookmarksDatabase.close();
}
- public void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl, byte[] favoriteIcon) {
+ void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl, byte[] favoriteIcon) {
// Store the updated values in `bookmarkContentValues`.
ContentValues bookmarkContentValues = new ContentValues();
bookmarksDatabase.close();
}
- public void updateFolder(int databaseId, String oldFolderName, String newFolderName) {
+ void updateFolder(int databaseId, String oldFolderName, String newFolderName) {
// Get a writable database handle.
SQLiteDatabase bookmarksDatabase = this.getWritableDatabase();
bookmarksDatabase.close();
}
- public void updateFolder(int databaseId, String oldFolderName, String newFolderName, byte[] folderIcon) {
+ void updateFolder(int databaseId, String oldFolderName, String newFolderName, byte[] folderIcon) {
// Get a writable database handle.
SQLiteDatabase bookmarksDatabase = this.getWritableDatabase();
bookmarksDatabase.close();
}
- public void updateBookmarkDisplayOrder(int databaseId, int displayOrder) {
+ void updateBookmarkDisplayOrder(int databaseId, int displayOrder) {
// Get a writable database handle.
SQLiteDatabase bookmarksDatabase = this.getWritableDatabase();
bookmarksDatabase.close();
}
- public void moveToFolder(int databaseId, String newFolder) {
+ void moveToFolder(int databaseId, String newFolder) {
// Get a writable database handle.
SQLiteDatabase bookmarksDatabase = this.getWritableDatabase();
bookmarksDatabase.close();
}
- public void deleteBookmark(int databaseId) {
+ void deleteBookmark(int databaseId) {
// Get a writable database handle.
SQLiteDatabase bookmarksDatabase = this.getWritableDatabase();
bookmarkNameTextView.setText(bookmarkNameString);
// Make the font bold for folders.
if (isFolder) {
- // The first argument is `null` because we don't want to chage the font.
+ // The first argument is `null` because we don't want to change the font.
bookmarkNameTextView.setTypeface(null, Typeface.BOLD);
} else { // Reset the font to default.
bookmarkNameTextView.setTypeface(Typeface.DEFAULT);
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
private CreateBookmarkListener createBookmarkListener;
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
- // Get a handle for `CreateBookmarkListener` from `parentActivity`.
+ // Get a handle for `CreateBookmarkListener` from `context`.
try {
- createBookmarkListener = (CreateBookmarkListener) parentActivity;
+ createBookmarkListener = (CreateBookmarkListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement CreateBookmarkListener.");
+ throw new ClassCastException(context.toString() + " must implement CreateBookmarkListener.");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Create a drawable version of the favorite icon.
// Create an `AlertDialog` from the `AlertDialog.Builder`.
final AlertDialog alertDialog = dialogBuilder.create();
+ // Remove the warning below that `setSoftInputMode` might produce `java.lang.NullPointerException`.
+ assert alertDialog.getWindow() != null;
+
// Show the keyboard when the `Dialog` is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
// If we don't use `android.support.v7.app.AlertDialog` instead of `android.app.AlertDialog` then the dialog will be covered by the keyboard.
// `createBookmarkFolderListener` is used in `onAttach()` and `onCreateDialog`.
private CreateBookmarkFolderListener createBookmarkFolderListener;
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
- // Get a handle for `createBookmarkFolderListener` from `parentActivity`.
+ // Get a handle for `createBookmarkFolderListener` from `context`.
try {
- createBookmarkFolderListener = (CreateBookmarkFolderListener) parentActivity;
+ createBookmarkFolderListener = (CreateBookmarkFolderListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement CreateBookmarkFolderListener.");
+ throw new ClassCastException(context.toString() + " must implement CreateBookmarkFolderListener.");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use `AlertDialog.Builder` to create the `AlertDialog`. The style formats the color of the button text.
// Create an `AlertDialog` from the `AlertDialog.Builder`.
final AlertDialog alertDialog = dialogBuilder.create();
+ // Remove the warning below that `setSoftInputMode` might produce `java.lang.NullPointerException`.
+ assert alertDialog.getWindow() != null;
+
// Show the keyboard when the `Dialog` is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
private CreateHomeScreenSchortcutListener createHomeScreenShortcutListener;
// Check to make sure that the parent activity implements the listener.
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
try {
- createHomeScreenShortcutListener = (CreateHomeScreenSchortcutListener) parentActivity;
+ createHomeScreenShortcutListener = (CreateHomeScreenSchortcutListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement CreateHomeScreenShortcutListener.");
+ throw new ClassCastException(context.toString() + " must implement CreateHomeScreenShortcutListener.");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the activity's layout inflater.
// Create an `AlertDialog` from the `AlertDialog.Builder`.
final AlertDialog alertDialog = dialogBuilder.create();
+ // Remove the warning below that `setSoftInputMode` might produce `java.lang.NullPointerException`.
+ assert alertDialog.getWindow() != null;
+
// Show the keyboard when the Dialog is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
Bundle argumentsBundle = new Bundle();
String fileNameString;
- if (contentDisposition.isEmpty()) { // If `contentDisposition` is empty, use the last path segment of the URL as the file name.
+ if (!contentDisposition.isEmpty()) { // Extract `fileNameString` from `contentDisposition` using the substring beginning after `filename="` and ending one character before the end of `contentDisposition`.
+ fileNameString = contentDisposition.substring(contentDisposition.indexOf("filename=\"") + 10, contentDisposition.length() - 1);
+ } else { // `contentDisposition` is empty, so use the last path segment of the URL as the file name.
Uri downloadUri = Uri.parse(urlString);
fileNameString = downloadUri.getLastPathSegment();
- } else { // Extract `fileNameString` from `contentDisposition` using the substring beginning after `filename="` and ending one character before the end of `contentDisposition`.
- fileNameString = contentDisposition.substring(contentDisposition.indexOf("filename=\"") + 10, contentDisposition.length() - 1);
}
// Convert `contentLength` to MB and store it in `fileSizeString`. `%.3g` displays the three most significant digits.
private DownloadFileListener downloadFileListener;
// Check to make sure tha the parent activity implements the listener.
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
try {
- downloadFileListener = (DownloadFileListener) parentActivity;
+ downloadFileListener = (DownloadFileListener) context;
} catch (ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement DownloadFileListener.");
+ throw new ClassCastException(context.toString() + " must implement DownloadFileListener.");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the activity's layout inflater.
// Create an `AlertDialog` from the `AlertDialog.Builder`.
final AlertDialog alertDialog = dialogBuilder.create();
+ // Remove the warning below that `setSoftInputMode` might produce `java.lang.NullPointerException`.
+ assert alertDialog.getWindow() != null;
+
// Show the keyboard when `alertDialog` is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
// Set the text for `downloadFileSizeTextView`.
TextView downloadFileSizeTextView = (TextView) alertDialog.findViewById(R.id.download_file_size);
- assert downloadFileSizeTextView != null; // Remove the warning of the following line that `downloadFileSizeTextView` might be null.
+ assert downloadFileSizeTextView != null; // Remove the warning on the following line that `downloadFileSizeTextView` might be `null`.
downloadFileSizeTextView.setText(fileSize);
// Set the text for `downloadFileNameTextView`.
EditText downloadFileNameTextView = (EditText) alertDialog.findViewById(R.id.download_file_name);
- assert downloadFileNameTextView != null; // Remove the warning on the following line that `downloadFileNameTextView` might be null.
+ assert downloadFileNameTextView != null; // Remove the warning on the following line that `downloadFileNameTextView` might be `null`.
downloadFileNameTextView.setText(downloadFileName);
// Allow the `enter` key on the keyboard to save the file from `downloadFileNameTextView`.
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
// `editBookmarkListener` is used in `onAttach()` and `onCreateDialog()`
private EditBookmarkListener editBookmarkListener;
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
- // Get a handle for `EditBookmarkListener` from `parentActivity`.
+ // Get a handle for `EditBookmarkListener` from `context`.
try {
- editBookmarkListener = (EditBookmarkListener) parentActivity;
+ editBookmarkListener = (EditBookmarkListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement EditBookmarkListener.");
+ throw new ClassCastException(context.toString() + " must implement EditBookmarkListener.");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get a long array with the the databaseId of the selected bookmark and convert it to an `int`.
- long[] selectedBookmarkLongArray = BookmarksActivity.bookmarksListView.getCheckedItemIds();
+ long[] selectedBookmarkLongArray = BookmarksActivity.checkedItemIds;
int selectedBookmarkDatabaseId = (int) selectedBookmarkLongArray[0];
// Get a `Cursor` with the specified bookmark and move it to the first position.
// Create an `AlertDialog` from the `AlertDialog.Builder`.
final AlertDialog alertDialog = dialogBuilder.create();
+ // Remove the warning below that `setSoftInputMode` might produce `java.lang.NullPointerException`.
+ assert alertDialog.getWindow() != null;
+
// Show the keyboard when `alertDialog` is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
// `editFolderListener` is used in `onAttach()` and `onCreateDialog`.
private EditBookmarkFolderListener editBookmarkFolderListener;
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
// Get a handle for `EditFolderListener` from `parentActivity`.
try {
- editBookmarkFolderListener = (EditBookmarkFolderListener) parentActivity;
+ editBookmarkFolderListener = (EditBookmarkFolderListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement EditBookmarkFolderListener.");
+ throw new ClassCastException(context.toString() + " must implement EditBookmarkFolderListener.");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get a long array with the the databaseId of the selected bookmark and convert it to an `int`.
- long[] selectedBookmarkLongArray = BookmarksActivity.bookmarksListView.getCheckedItemIds();
+ long[] selectedBookmarkLongArray = BookmarksActivity.checkedItemIds;
int selectedBookmarkDatabaseId = (int) selectedBookmarkLongArray[0];
// Get a `Cursor` with the specified bookmark and move it to the first position.
// Create an `AlertDialog` from the `AlertDialog.Builder`.
final AlertDialog alertDialog = dialogBuilder.create();
+ // Remove the warning below that `setSoftInputMode` might produce `java.lang.NullPointerException`.
+ assert alertDialog.getWindow() != null;
+
// Show the keyboard when the `Dialog` is displayed on the screen.
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
public class guidePagerAdapter extends FragmentPagerAdapter {
- public guidePagerAdapter(FragmentManager fm) {
+ private guidePagerAdapter(FragmentManager fm) {
super(fm);
}
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.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.net.http.SslCertificate;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
// We need to use AppCompatActivity from android.support.v7.app.AppCompatActivity to have access to the SupportActionBar until the minimum API is >= 21.
public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcut.CreateHomeScreenSchortcutListener,
SslCertificateError.SslCertificateErrorListener, DownloadFile.DownloadFileListener {
- // `privacyBrowserContext` is public static so it can be accessed from `SettingsFragment`.
- // It is also used in `onCreate()` and `onConfigurationChanged()`.
- public static Context privacyBrowserContext;
// `appBar` is public static so it can be accessed from `OrbotProxyHelper`.
// It is also used in `onCreate()`.
// It is also used in `onCreate()` and `onCreateHomeScreenShortcutCreate()`.
public static Bitmap favoriteIcon;
- // `privacyBrowserActivity` is public static so it can be accessed from `SettingsFragment`.
- // It is also used in `onCreate()`, `onCreateOptionsMenu()`, and `onOptionsItemSelected()`,
- public static Activity privacyBrowserActivity;
-
- // `mainWebView` is public static so it can be accessed from `SettingsFragment`.
- // It is also used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, and `loadUrlFromTextBox()`.
- public static WebView mainWebView;
-
// `formattedUrlString` is public static so it can be accessed from `BookmarksActivity`.
// It is also used in `onCreate()`, `onOptionsItemSelected()`, `onCreateHomeScreenShortcutCreate()`, and `loadUrlFromTextBox()`.
public static String formattedUrlString;
- // `mainMenu` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreateOptionsMenu()` and `onOptionsItemSelected()`.
- public static Menu mainMenu;
+ // `customHeader` is public static so it can be accessed from `BookmarksActivity`. It is also used in `onCreate()`, `onOptionsItemSelected()`, and `loadUrlFromTextBox()`.
+ public static Map<String, String> customHeaders = new HashMap<>();
- // `cookieManager` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`.
- public static CookieManager cookieManager;
+ // `sslCertificate` is public static so it can be accessed from `ViewSslCertificate`. It is also used in `onCreate()`.
+ public static SslCertificate sslCertificate;
- // `javaScriptEnabled` is public static so it can be accessed from `SettingsFragment`.
- // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `onOptionsItemSelected()`, and `loadUrlFromTextBox()`.
- public static boolean javaScriptEnabled;
- // `firstPartyCookiesEnabled` is public static so it can be accessed from `SettingsFragment`.
- // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `onOptionsItemSelected()`.
- public static boolean firstPartyCookiesEnabled;
+ // 'mainWebView' is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `loadUrlFromTextBox()`.
+ private WebView mainWebView;
- // `thirdPartyCookiesEnables` is public static so it can be accessed from `SettingsFragment`.
- // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `onOptionsItemSelected()`.
- public static boolean thirdPartyCookiesEnabled;
+ // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu`, and `onRestart()`.
+ private SwipeRefreshLayout swipeRefreshLayout;
- // `domStorageEnabled` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()`, `onCreateOptionsMenu()`, and `onOptionsItemSelected()`.
- public static boolean domStorageEnabled;
+ // `cookieManager` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`, and `onRestart()`.
+ private CookieManager cookieManager;
- // `saveFormDataEnabled` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()`, `onCreateOptionsMenu()`, and `onOptionsItemSelected()`.
- public static boolean saveFormDataEnabled;
+ // `javaScriptEnabled` is also used in `onCreate()`, `onCreateOptionsMenu()`, `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `applySettings()`.
+ // It is `Boolean` instead of `boolean` because `applySettings()` needs to know if it is `null`.
+ private Boolean javaScriptEnabled;
- // `javaScriptDisabledSearchURL` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()` and `loadURLFromTextBox()`.
- public static String javaScriptDisabledSearchURL;
+ // `firstPartyCookiesEnabled` is used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applySettings()`.
+ private boolean firstPartyCookiesEnabled;
- // `javaScriptEnabledSearchURL` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()` and `loadURLFromTextBox()`.
- public static String javaScriptEnabledSearchURL;
+ // `thirdPartyCookiesEnabled` used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applySettings()`.
+ private boolean thirdPartyCookiesEnabled;
- // `homepage` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()` and `onOptionsItemSelected()`.
- public static String homepage;
+ // `domStorageEnabled` is used in `onCreate()`, `onCreateOptionsMenu()`, `onOptionsItemSelected()`, and `applySettings()`.
+ private boolean domStorageEnabled;
- // `swipeToRefresh` is public static so it can be accessed from SettingsFragment. It is also used in onCreate().
- public static SwipeRefreshLayout swipeToRefresh;
+ // `saveFormDataEnabled` is used in `onCreate()`, `onCreateOptionsMenu()`, `onOptionsItemSelected()`, and `applySettings()`.
+ private boolean saveFormDataEnabled;
- // `swipeToRefreshEnabled` is public static so it can be accessed from `SettingsFragment`. It is also used in `onCreate()`.
- public static boolean swipeToRefreshEnabled;
+ // `swipeToRefreshEnabled` is used in `onPrepareOptionsMenu()` and `applySettings()`.
+ private boolean swipeToRefreshEnabled;
- // `customHeader` is public static so it can be accessed from `BookmarksActivity`. It is also used in `onCreate()`, `onOptionsItemSelected()`, and `loadUrlFromTextBox()`.
- public static Map<String, String> customHeaders = new HashMap<String, String>();
+ // 'homepage' is used in `onCreate()`, `onNavigationItemSelected()`, and `applySettings()`.
+ private String homepage;
+
+ // `javaScriptDisabledSearchURL` is used in `loadURLFromTextBox()` and `applySettings()`.
+ private String javaScriptDisabledSearchURL;
+ // `javaScriptEnabledSearchURL` is used in `loadURLFromTextBox()` and `applySettings()`.
+ private String javaScriptEnabledSearchURL;
+ // `mainMenu` is used in `onCreateOptionsMenu()` and `updatePrivacyIcons()`.
+ private Menu mainMenu;
// `drawerToggle` is used in `onCreate()`, `onPostCreate()`, `onConfigurationChanged()`, `onNewIntent()`, and `onNavigationItemSelected()`.
private ActionBarDrawerToggle drawerToggle;
// `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`.
private SslErrorHandler sslErrorHandler;
- // `sharedPreferences` is used in `onCreate()` and `onCreateOptionsMenu()`.
- SharedPreferences sharedPreferences;
-
@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")
super.onCreate(savedInstanceState);
setContentView(R.layout.main_coordinatorlayout);
- // We need a handle for the activity, which is accessed from `SettingsFragment` and fed into `updatePrivacyIcons()`.
- privacyBrowserActivity = this;
-
- // Get a handle for the application context.
- privacyBrowserContext = getApplicationContext();
-
// We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21.
Toolbar supportAppBar = (Toolbar) findViewById(R.id.appBar);
setSupportActionBar(supportAppBar);
final FrameLayout fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.fullScreenVideoFrameLayout);
// Implement swipe to refresh
- swipeToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
- assert swipeToRefresh != null; //This assert removes the incorrect warning on the following line that swipeToRefresh might be null.
- swipeToRefresh.setColorSchemeResources(R.color.blue_700);
- swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
+ swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
+ swipeRefreshLayout.setColorSchemeResources(R.color.blue_700);
+ swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mainWebView.reload();
// Listen for touches on the navigation menu.
final NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView);
- assert navigationView != null; // This assert removes the incorrect warning on the following line that navigationView might be null.
navigationView.setNavigationItemSelectedListener(this);
// drawerToggle creates the hamburger icon at the start of the AppBar.
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, supportAppBar, R.string.open_navigation, R.string.close_navigation);
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.
+ // `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.
+ @SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Use an external email program if the link begins with "mailto:".
// Update the URL in urlTextBox when the page starts to load.
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ // We need to update `formattedUrlString` at the beginning of the load, so that if the user toggles JavaScript during the load the new website is reloaded.
+ formattedUrlString = url;
+
+ // Display the loading URL is the URL text box.
urlTextBox.setText(url);
}
if (!urlTextBox.hasFocus()) {
urlTextBox.setText(formattedUrlString);
}
+
+ // Store the SSL certificate so it can be accessed from `ViewSslCertificate`.
+ sslCertificate = mainWebView.getCertificate();
}
// Handle SSL Certificate errors.
} else {
progressBar.setVisibility(View.GONE);
- //Stop the SwipeToRefresh indicator if it is running
- swipeToRefresh.setRefreshing(false);
+ //Stop the `SwipeToRefresh` indicator if it is running
+ swipeRefreshLayout.setRefreshing(false);
}
}
appBar.hide();
// Show the fullScreenVideoFrameLayout.
- assert fullScreenVideoFrameLayout != null; //This assert removes the incorrect warning on the following line that fullScreenVideoFrameLayout might be null.
fullScreenVideoFrameLayout.addView(view);
fullScreenVideoFrameLayout.setVisibility(View.VISIBLE);
BannerAd.showAd(adView);
// Hide the fullScreenVideoFrameLayout.
- assert fullScreenVideoFrameLayout != null; //This assert removes the incorrect warning on the following line that fullScreenVideoFrameLayout might be null.
fullScreenVideoFrameLayout.removeAllViews();
fullScreenVideoFrameLayout.setVisibility(View.GONE);
}
// Hide zoom controls.
mainWebView.getSettings().setDisplayZoomControls(false);
-
- // Initialize the default preference values the first time the program is run.
- PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
-
- // Get the shared preference values.
- sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
- // Set JavaScript initial status. The default value is false.
- javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
- mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
-
// Initialize cookieManager.
cookieManager = CookieManager.getInstance();
- // Set cookies initial status. The default value is false.
- firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
- cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
-
- // Set third-party cookies initial status if API >= 21. The default value is false.
- if (Build.VERSION.SDK_INT >= 21) {
- thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
- cookieManager.setAcceptThirdPartyCookies(mainWebView, thirdPartyCookiesEnabled);
- }
-
- // Set DOM storage initial status. The default value is false.
- domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
- mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
-
- // Set the saved form data initial status. The default is false.
- saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);
- mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
-
- // Set the user agent initial status.
- String userAgentString = sharedPreferences.getString("user_agent", "Default user agent");
- switch (userAgentString) {
- case "Default user agent":
- // Do nothing.
- break;
-
- case "Custom user agent":
- // Set the custom user agent on mainWebView, The default is "PrivacyBrowser/1.0".
- mainWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
- break;
-
- default:
- // Set the selected user agent on mainWebView. The default is "PrivacyBrowser/1.0".
- mainWebView.getSettings().setUserAgentString(sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
- break;
- }
-
- // Set the initial string for JavaScript disabled search.
- if (sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=").equals("Custom URL")) {
- // Get the custom URL string. The default is "".
- javaScriptDisabledSearchURL = sharedPreferences.getString("javascript_disabled_search_custom_url", "");
- } else {
- // Use the string from javascript_disabled_search.
- javaScriptDisabledSearchURL = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=");
- }
-
- // Set the initial string for JavaScript enabled search.
- if (sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=").equals("Custom URL")) {
- // Get the custom URL string. The default is "".
- javaScriptEnabledSearchURL = sharedPreferences.getString("javascript_enabled_search_custom_url", "");
- } else {
- // Use the string from javascript_enabled_search.
- javaScriptEnabledSearchURL = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=");
- }
-
-
- // Set the homepage initial status. The default value is `https://www.duckduckgo.com`.
- homepage = sharedPreferences.getString("homepage", "https://www.duckduckgo.com");
-
- // Set the font size initial status. the default value is `100`.
- String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
- mainWebView.getSettings().setTextZoom(Integer.valueOf(defaultFontSizeString));
-
- // Set the swipe to refresh initial status. The default is `true`.
- swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", true);
- swipeToRefresh.setEnabled(swipeToRefreshEnabled);
-
-
// Replace the header that `WebView` creates for `X-Requested-With` with a null value. The default value is the application ID (com.stoutner.privacybrowser.standard).
customHeaders.put("X-Requested-With", "");
- // Set Do Not Track. The default is true.
- if (sharedPreferences.getBoolean("do_not_track", true)) {
- customHeaders.put("DNT", "1");
- }
+ // Initialize the default preference values the first time the program is run.
+ PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
- // Set Orbot proxy status. The default is `false`.
- if (sharedPreferences.getBoolean("proxy_through_orbot", false)) {
- OrbotProxyHelper.setProxy(privacyBrowserContext, privacyBrowserActivity, "localhost", "8118");
- }
+ // Apply the settings from the shared preferences.
+ applySettings();
// Get the intent information that started the app.
final Intent intent = getIntent();
// If the favorite icon is null, load the default.
if (favoriteIcon == null) {
// We have to use `ContextCompat` until API >= 21.
- Drawable favoriteIconDrawable = ContextCompat.getDrawable(privacyBrowserContext, R.drawable.world);
+ Drawable favoriteIconDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.world);
BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable;
favoriteIcon = favoriteIconBitmapDrawable.getBitmap();
}
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.webview_options_menu, menu);
- // Set mainMenu so it can be used by onOptionsItemSelected.
+ // Set mainMenu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons`.
mainMenu = menu;
- // Set the initial status of the privacy icon.
- updatePrivacyIcons(privacyBrowserActivity);
+ // Set the initial status of the privacy icons.
+ updatePrivacyIcons();
// Get handles for the menu items.
MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies);
MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData);
- // Set the initial status of the menu item checkboxes.
- toggleFirstPartyCookies.setChecked(firstPartyCookiesEnabled);
- toggleThirdPartyCookies.setChecked(thirdPartyCookiesEnabled);
- toggleDomStorage.setChecked(domStorageEnabled);
- toggleSaveFormData.setChecked(saveFormDataEnabled);
+ // Only display third-Party Cookies if SDK >= 21
+ toggleThirdPartyCookies.setVisible(Build.VERSION.SDK_INT >= 21);
+
+ // Get the shared preference values. `this` references the current context.
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Set the status of the additional app bar icons. The default is `false`.
if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- // Only enable Third-Party Cookies if SDK >= 21 and First-Party Cookies are enabled.
+ // Get handles for the menu items.
+ MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies);
MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies);
- if ((Build.VERSION.SDK_INT >= 21) && firstPartyCookiesEnabled) {
- toggleThirdPartyCookies.setEnabled(true);
- } else {
- toggleThirdPartyCookies.setEnabled(false);
- }
+ MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
+ MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData);
+ MenuItem clearCookies = menu.findItem(R.id.clearCookies);
+ MenuItem clearFormData = menu.findItem(R.id.clearFormData);
+ MenuItem refreshMenuItem = menu.findItem(R.id.refresh);
+
+ // Set the status of the menu item checkboxes.
+ toggleFirstPartyCookies.setChecked(firstPartyCookiesEnabled);
+ toggleThirdPartyCookies.setChecked(thirdPartyCookiesEnabled);
+ toggleDomStorage.setChecked(domStorageEnabled);
+ toggleSaveFormData.setChecked(saveFormDataEnabled);
+
+ // Enable third-party cookies if first-party cookies are enabled.
+ toggleThirdPartyCookies.setEnabled(firstPartyCookiesEnabled);
// Enable DOM Storage if JavaScript is enabled.
- MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
toggleDomStorage.setEnabled(javaScriptEnabled);
// Enable Clear Cookies if there are any.
- MenuItem clearCookies = menu.findItem(R.id.clearCookies);
clearCookies.setEnabled(cookieManager.hasCookies());
// Enable Clear Form Data is there is any.
- MenuItem clearFormData = menu.findItem(R.id.clearFormData);
WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
clearFormData.setEnabled(mainWebViewDatabase.hasFormData());
+ // Only show `Refresh` if `swipeToRefresh` is disabled.
+ refreshMenuItem.setVisible(!swipeToRefreshEnabled);
+
// Initialize font size variables.
int fontSize = mainWebView.getSettings().getTextZoom();
String fontSizeTitle;
fontSizeMenuItem.setTitle(fontSizeTitle);
selectedFontSizeMenuItem.setChecked(true);
- // Only show `Refresh` if `swipeToRefresh` is disabled.
- MenuItem refreshMenuItem = menu.findItem(R.id.refresh);
- refreshMenuItem.setVisible(!swipeToRefreshEnabled);
-
// Run all the other default commands.
super.onPrepareOptionsMenu(menu);
mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
// Update the privacy icon.
- updatePrivacyIcons(privacyBrowserActivity);
+ updatePrivacyIcons();
// Display a `Snackbar`.
- if (javaScriptEnabled) {
+ if (javaScriptEnabled) { // JavaScrip is enabled.
Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
- } else {
- if (firstPartyCookiesEnabled) {
- Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
- } else {
- Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
- }
+ } else if (firstPartyCookiesEnabled) { // JavaScript is disabled, but first-party cookies are enabled.
+ Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
+ } else { // Privacy mode.
+ Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
}
// Reload the WebView.
cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
// Update the privacy icon.
- updatePrivacyIcons(privacyBrowserActivity);
+ updatePrivacyIcons();
// Display a `Snackbar`.
- if (firstPartyCookiesEnabled) {
+ if (firstPartyCookiesEnabled) { // First-party cookies are enabled.
Snackbar.make(findViewById(R.id.mainWebView), R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
- } else {
- if (javaScriptEnabled) {
- Snackbar.make(findViewById(R.id.mainWebView), R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
- } else {
- Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
- }
+ } else if (javaScriptEnabled){ // JavaScript is still enabled.
+ Snackbar.make(findViewById(R.id.mainWebView), R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
+ } else { // Privacy mode.
+ Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
}
// Reload the WebView.
}
}
- @Override
// removeAllCookies is deprecated, but it is required for API < 21.
@SuppressWarnings("deprecation")
- public boolean onNavigationItemSelected(MenuItem menuItem) {
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
int menuItemId = menuItem.getItemId();
switch (menuItemId) {
mainWebView.clearHistory();
// Clear any SSL certificate preferences.
- MainWebViewActivity.mainWebView.clearSslPreferences();
+ mainWebView.clearSslPreferences();
// Clear `formattedUrlString`.
formattedUrlString = null;
super.onConfigurationChanged(newConfig);
// Reload the ad if this is the free flavor.
- BannerAd.reloadAfterRotate(adView, privacyBrowserContext, getString(R.string.ad_id));
+ BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
// Reinitialize the adView variable, as the View will have been removed and re-added in the free flavor by BannerAd.reloadAfterRotate().
adView = findViewById(R.id.adView);
drawerLayout.closeDrawer(GravityCompat.START);
} else {
// Load the previous URL if available.
- assert mainWebView != null; //This assert removes the incorrect warning in Android Studio on the following line that mainWebView might be null.
if (mainWebView.canGoBack()) {
mainWebView.goBack();
} else {
BannerAd.resumeAd(adView);
}
+ @Override
+ public void onRestart() {
+ super.onRestart();
+
+ // Apply the settings from shared preferences, which might have been changed in `SettingsActivity`.
+ applySettings();
+
+ // Update the privacy icons.
+ updatePrivacyIcons();
+
+ }
+
private void loadUrlFromTextBox() throws UnsupportedEncodingException {
// Get the text from urlTextBox and convert it to a string. trim() removes white spaces from the beginning and end of the string.
String unformattedUrlString = urlTextBox.getText().toString().trim();
// Sanitize the search input and convert it to a DuckDuckGo search.
final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
- // Use the correct search URL based on javaScriptEnabled.
- if (javaScriptEnabled) {
+ // Use the correct search URL.
+ if (javaScriptEnabled) { // JavaScript is enabled.
formattedUrlString = javaScriptEnabledSearchURL + encodedUrlString;
} else { // JavaScript is disabled.
formattedUrlString = javaScriptDisabledSearchURL + encodedUrlString;
inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
}
- public static void updatePrivacyIcons(Activity activity) {
+ private void applySettings() {
+ // Get the shared preference values. `this` references the current context.
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+ // Store the values from `sharedPreferences` in variables.
+ String userAgentString = sharedPreferences.getString("user_agent", "Default user agent");
+ String customUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0");
+ String javaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=");
+ String javaScriptDisabledCustomSearchString = sharedPreferences.getString("javascript_disabled_search_custom_url", "");
+ String javaScriptEnabledSearchString = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=");
+ String javaScriptEnabledCustomSearchString = sharedPreferences.getString("javascript_enabled_search_custom_url", "");
+ String homepageString = sharedPreferences.getString("homepage", "https://www.duckduckgo.com");
+ String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
+ swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", false);
+ boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", true);
+ boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
+
+ // Because they can be modified on-the-fly by the user, these default settings are only applied when the program first runs.
+ if (javaScriptEnabled == null) { // If `javaScriptEnabled` is null the program is just starting.
+ // Get the values from `sharedPreferences`.
+ javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
+ firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
+ thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
+ domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
+ saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);
+
+ // Apply the default settings.
+ mainWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
+ cookieManager.setAcceptCookie(firstPartyCookiesEnabled);
+ mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+
+ // Set third-party cookies status if API >= 21.
+ if (Build.VERSION.SDK_INT >= 21) {
+ cookieManager.setAcceptThirdPartyCookies(mainWebView, thirdPartyCookiesEnabled);
+ }
+ }
+
+ // Apply the settings from `sharedPreferences`.
+ homepage = homepageString;
+ mainWebView.getSettings().setTextZoom(Integer.valueOf(defaultFontSizeString));
+ swipeRefreshLayout.setEnabled(swipeToRefreshEnabled);
+
+ // Set the user agent initial status.
+ switch (userAgentString) {
+ case "Default user agent":
+ // Set the user agent to `""`, which uses the default value.
+ mainWebView.getSettings().setUserAgentString("");
+ break;
+
+ case "Custom user agent":
+ // Set the custom user agent.
+ mainWebView.getSettings().setUserAgentString(customUserAgentString);
+ break;
+
+ default:
+ // Use the selected user agent.
+ mainWebView.getSettings().setUserAgentString(userAgentString);
+ break;
+ }
+
+ // Set JavaScript disabled search.
+ if (javaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string.
+ javaScriptDisabledSearchURL = javaScriptDisabledCustomSearchString;
+ } else { // Use the string from the pre-built list.
+ javaScriptDisabledSearchURL = javaScriptDisabledSearchString;
+ }
+
+ // Set JavaScript enabled search.
+ if (javaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string.
+ javaScriptEnabledSearchURL = javaScriptEnabledCustomSearchString;
+ } else { // Use the string from the pre-built list.
+ javaScriptEnabledSearchURL = javaScriptEnabledSearchString;
+ }
+
+ // Set Do Not Track status.
+ if (doNotTrackEnabled) {
+ customHeaders.put("DNT", "1");
+ } else {
+ customHeaders.remove("DNT");
+ }
+
+ // Set Orbot proxy status.
+ if (proxyThroughOrbot) {
+ // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed.
+ OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118");
+ } else { // Reset the proxy to default. The host is `""` and the port is `"0"`.
+ OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0");
+ }
+ }
+
+ private void updatePrivacyIcons() {
// 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 is enabled.
+ 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.
domStorageIcon.setIcon(R.drawable.dom_storage_disabled);
}
// `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`.
- ActivityCompat.invalidateOptionsMenu(activity);
+ // `this` references the current activity.
+ ActivityCompat.invalidateOptionsMenu(this);
}
}
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
// If we don't use `android.support.v7.app.AlertDialog` instead of `android.app.AlertDialog` then the dialog will be covered by the keyboard.
-import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.View;
// `moveToFolderListener` is used in `onAttach()` and `onCreateDialog`.
private MoveToFolderListener moveToFolderListener;
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
// Get a handle for `MoveToFolderListener` from `parentActivity`.
try {
- moveToFolderListener = (MoveToFolderListener) parentActivity;
+ moveToFolderListener = (MoveToFolderListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement EditBookmarkFolderListener.");
+ throw new ClassCastException(context.toString() + " must implement EditBookmarkFolderListener.");
}
}
// `exceptFolders` is used in `onCreateDialog()` and `addSubfoldersToExceptFolders()`.
private String exceptFolders;
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use `AlertDialog.Builder` to create the `AlertDialog`. The style formats the color of the button text.
exceptFolders = "";
// If a folder is selected, add it and all children to the list of folders not to display.
- long[] selectedBookmarksLongArray = BookmarksActivity.bookmarksListView.getCheckedItemIds();
+ long[] selectedBookmarksLongArray = BookmarksActivity.checkedItemIds;
for (long databaseIdLong : selectedBookmarksLongArray) {
// Get `databaseIdInt` for each selected bookmark.
int databaseIdInt = (int) databaseIdLong;
exceptFolders = DatabaseUtils.sqlEscapeString(BookmarksActivity.currentFolder);
// If a folder is selected, add it and all children to the list of folders not to display.
- long[] selectedBookmarksLongArray = BookmarksActivity.bookmarksListView.getCheckedItemIds();
+ long[] selectedBookmarksLongArray = BookmarksActivity.checkedItemIds;
for (long databaseIdLong : selectedBookmarksLongArray) {
// Get `databaseIdInt` for each selected bookmark.
int databaseIdInt = (int) databaseIdLong;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-public class OrbotProxyHelper {
- public static void setProxy(Context privacyBrowserContext, Activity parentActivity, String proxyHost, String proxyPort) {
+class OrbotProxyHelper {
+ static void setProxy(Context privacyBrowserContext, Activity parentActivity, String proxyHost, String proxyPort) {
// Set the proxy values
System.setProperty("http.proxyHost", proxyHost);
System.setProperty("http.proxyPort", proxyPort);
package com.stoutner.privacybrowser;
import android.os.Bundle;
+import android.preference.PreferenceFragment;
import android.support.v7.app.AppCompatActivity;
public class SettingsActivity extends AppCompatActivity {
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display SettingsFragment.
- getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
+ PreferenceFragment settingsFragment = new SettingsFragment();
+ getFragmentManager().beginTransaction().replace(android.R.id.content, settingsFragment).commit();
}
}
package com.stoutner.privacybrowser;
import android.annotation.SuppressLint;
-import android.app.Activity;
import android.content.SharedPreferences;
-import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
-import android.view.MenuItem;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.webkit.WebView;
public class SettingsFragment extends PreferenceFragment {
private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
thirdPartyCookiesEnabled.setEnabled(savedPreferences.getBoolean("first_party_cookies_enabled", false));
+
+ // We need an inflated `WebView` to get the default user agent.
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because we don't want to display `bare_webview` on the screen.
+ // `false` does not attach the view to the root.
+ @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
+ final WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview);
+
// Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded.
final Preference userAgentPreference = findPreference("user_agent");
switch (savedPreferences.getString("user_agent", "Default user agent")) {
case "Default user agent":
// Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
- // Once API >= 17 we can use getDefaultUserAgent() instead of getUserAgentString().
- userAgentPreference.setSummary(MainWebViewActivity.mainWebView.getSettings().getUserAgentString());
+ userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
break;
case "Custom user agent":
switch (key) {
case "javascript_enabled":
- // Set `javaScriptEnabled` to the new state. The default is `false`.
- MainWebViewActivity.javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
-
// Toggle the state of the `dom_storage_enabled` preference. The default is `false`.
final Preference domStorageEnabled = findPreference("dom_storage_enabled");
domStorageEnabled.setEnabled(sharedPreferences.getBoolean("javascript_enabled", false));
-
- // Update `mainWebView`.
- MainWebViewActivity.mainWebView.getSettings().setJavaScriptEnabled(MainWebViewActivity.javaScriptEnabled);
-
- // Update the privacy icons.
- MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
break;
case "first_party_cookies_enabled":
- // Set `firstPartyCookiesEnabled` to the new state. The default is `false`.
- MainWebViewActivity.firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
-
// Toggle the state of the `third_party_cookies_enabled` preference. The default is `false`.
final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false));
-
- // Update `mainWebView`.
- MainWebViewActivity.cookieManager.setAcceptCookie(MainWebViewActivity.firstPartyCookiesEnabled);
-
- // Update the checkbox in the options menu.
- MenuItem firstPartyCookiesMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleFirstPartyCookies);
- firstPartyCookiesMenuItem.setChecked(MainWebViewActivity.firstPartyCookiesEnabled);
-
- // Update the privacy icons.
- MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
- break;
-
- case "third_party_cookies_enabled":
- // Set `thirdPartyCookiesEnabled` to the new state. The default is `false`.
- MainWebViewActivity.thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies_enabled", false);
-
- // Update the checkbox in the options menu.
- MenuItem thirdPartyCookiesMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleThirdPartyCookies);
- thirdPartyCookiesMenuItem.setChecked(MainWebViewActivity.thirdPartyCookiesEnabled);
-
- // Update `mainWebView` if API >= 21.
- if (Build.VERSION.SDK_INT >= 21) {
- MainWebViewActivity.cookieManager.setAcceptThirdPartyCookies(MainWebViewActivity.mainWebView, MainWebViewActivity.thirdPartyCookiesEnabled);
- }
- break;
-
- case "dom_storage_enabled":
- // Set `domStorageEnabled` to the new state. The default is `false`.
- MainWebViewActivity.domStorageEnabled = sharedPreferences.getBoolean("dom_storage_enabled", false);
-
- // Update the checkbox in the options menu.
- MenuItem domStorageMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleDomStorage);
- domStorageMenuItem.setChecked(MainWebViewActivity.domStorageEnabled);
-
- // Update `mainWebView`.
- MainWebViewActivity.mainWebView.getSettings().setDomStorageEnabled(MainWebViewActivity.domStorageEnabled);
-
- // Update the privacy icons.
- MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
- break;
-
- case "save_form_data_enabled":
- // Set `saveFormDataEnabled` to the new state. The default is `false`.
- MainWebViewActivity.saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data_enabled", false);
-
- // Update the checkbox in the options menu.
- MenuItem saveFormDataMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleSaveFormData);
- saveFormDataMenuItem.setChecked(MainWebViewActivity.saveFormDataEnabled);
-
- // Update `mainWebView`.
- MainWebViewActivity.mainWebView.getSettings().setSaveFormData(MainWebViewActivity.saveFormDataEnabled);
-
- // Update the privacy icons.
- MainWebViewActivity.updatePrivacyIcons(MainWebViewActivity.privacyBrowserActivity);
break;
case "user_agent":
switch (userAgentString) {
case "Default user agent":
- // Set the default user agent on `mainWebView`, display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`.
- // Once API >= 17 we can use getDefaultUserAgent(). For now, setUserAgentString("") sets the WebView's default user agent.
- MainWebViewActivity.mainWebView.getSettings().setUserAgentString("");
- userAgentPreference.setSummary(MainWebViewActivity.mainWebView.getSettings().getUserAgentString());
+ // Display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`.
+ userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
customUserAgent.setEnabled(false);
break;
case "Custom user agent":
- // Set the custom user agent on mainWebView, display "Custom user agent" as the summary text for userAgentPreference, and enable customUserAgent.
- MainWebViewActivity.mainWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
+ // Display "Custom user agent" as the summary text for userAgentPreference, and enable customUserAgent.
userAgentPreference.setSummary(R.string.custom_user_agent);
customUserAgent.setEnabled(true);
break;
default:
- // Set the user agent on mainWebView, display the user agent as the summary text for userAgentPreference, and disable customUserAgent.
- MainWebViewActivity.mainWebView.getSettings().setUserAgentString(sharedPreferences.getString("user_agent", "Default user agent"));
- userAgentPreference.setSummary(MainWebViewActivity.mainWebView.getSettings().getUserAgentString());
+ // Display the user agent as the summary text for userAgentPreference, and disable customUserAgent.
+ userAgentPreference.setSummary(sharedPreferences.getString("user_agent", "Default user agent"));
customUserAgent.setEnabled(false);
break;
}
case "custom_user_agent":
// Set the new custom user agent as the summary text for "custom_user_agent". The default is "PrivacyBrowser/1.0".
customUserAgent.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
-
- // Update mainWebView's user agent. The default is "PrivacyBrowser/1.0".
- MainWebViewActivity.mainWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
break;
- case "proxy_through_orbot":
- // Get a handle for `settingsActivity`.
- Activity settingsActivity = getActivity();
-
- // Update the proxy. The default is `false`
- if (sharedPreferences.getBoolean("proxy_through_orbot", false)) { // Orbot proxies on localhost port 8118.
- OrbotProxyHelper.setProxy(MainWebViewActivity.privacyBrowserContext, settingsActivity, "localhost", "8118");
- } else { // Disable the proxy by setting the host to `null` and the port to `0`.
- OrbotProxyHelper.setProxy(MainWebViewActivity.privacyBrowserContext, settingsActivity, "", "0");
- }
-
case "javascript_disabled_search":
String newJavaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=");
- if (newJavaScriptDisabledSearchString.equals("Custom URL")) {
- // Set the summary text to R.string.custom_url, which will be translated.
+ if (newJavaScriptDisabledSearchString.equals("Custom URL")) { // Set the summary text to `R.string.custom_url`, which is translated.
javaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
-
- // Update the javaScriptDisabledSearchURL variable. The default is "".
- MainWebViewActivity.javaScriptDisabledSearchURL = sharedPreferences.getString("javascript_disabled_search_custom_url", "");
- } else { // javascript_disabled_search is not set to Custom.
- // Set the new search URL as the summary text for the JavaScript-disabled search preference. The default is "https://duckduckgo.com/html/?q=".
+ } else { // Set the new search URL as the summary text for the JavaScript-disabled search preference.
javaScriptDisabledSearchPreference.setSummary(newJavaScriptDisabledSearchString);
-
- // Update the javaScriptDisabledSearchURL variable. The default is "https://duckduckgo.com/html/?q=".
- MainWebViewActivity.javaScriptDisabledSearchURL = newJavaScriptDisabledSearchString;
}
// Enable or disable javaScriptDisabledSearchCustomURLPreference.
break;
case "javascript_disabled_search_custom_url":
- // Set the new custom search URL as the summary text for "javascript_disabled_search_custom_url". The default is "".
+ // Set the new custom search URL as the summary text for `javascript_disabled_search_custom_url`. The default is `""`.
javaScriptDisabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_disabled_search_custom_url", ""));
-
- // Update javaScriptDisabledSearchCustomURL. The default is "".
- MainWebViewActivity.javaScriptDisabledSearchURL = sharedPreferences.getString("javascript_disabled_search_custom_url", "");
break;
case "javascript_enabled_search":
String newJavaScriptEnabledSearchString = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=");
- if (newJavaScriptEnabledSearchString.equals("Custom URL")) {
- // Set the summary text to R.string.custom_url, which will be translated.
+ if (newJavaScriptEnabledSearchString.equals("Custom URL")) { // Set the summary text to `R.string.custom_url`, which is translated.
javaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
-
- // Update the javaScriptEnabledSearchURL variable. The default is "".
- MainWebViewActivity.javaScriptEnabledSearchURL = sharedPreferences.getString("javascript_enabled_search_custom_url", "");
- } else { // javascript_enabled_search is not set to Custom.
- // Set the new search URL as the summary text for the JavaScript-enabled search preference. The default is "https://duckduckgo.com/?q=".
+ } else { // Set the new search URL as the summary text for the JavaScript-enabled search preference..
javaScriptEnabledSearchPreference.setSummary(newJavaScriptEnabledSearchString);
-
- // Update the javaScriptEnabledSearchURL variable. The default is "https://duckduckgo.com/?q=".
- MainWebViewActivity.javaScriptEnabledSearchURL = newJavaScriptEnabledSearchString;
}
// Enable or disable javaScriptEnabledSearchCustomURLPreference.
break;
case "javascript_enabled_search_custom_url":
- // Set the new custom search URL as the summary text for `javascript_enabled_search_custom_url`. The default is ``.
+ // Set the new custom search URL as the summary text for `javascript_enabled_search_custom_url`. The default is `""`.
javaScriptEnabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_enabled_search_custom_url", ""));
-
- // Update javaScriptEnabledSearchCustomURL. The default is ``.
- MainWebViewActivity.javaScriptEnabledSearchURL = sharedPreferences.getString("javascript_enabled_search_custom_url", "");
break;
- case "do_not_track":
- // Update `customHeaders`. The default is `true`.
- if (sharedPreferences.getBoolean("do_not_track", true)) {
- MainWebViewActivity.customHeaders.put("DNT", "1");
- } else { // Remove the Do Not Track header.
- MainWebViewActivity.customHeaders.remove("DNT");
- }
-
case "homepage":
// Set the new homepage URL as the summary text for the Homepage preference. The default is `https://www.duckduckgo.com`.
homepagePreference.setSummary(sharedPreferences.getString("homepage", "https://www.duckduckgo.com"));
-
- // Update the homepage variable. The default is `https://www.duckduckgo.com`.
- MainWebViewActivity.homepage = sharedPreferences.getString("homepage", "https://www.duckduckgo.com");
break;
case "default_font_size":
// Get the default font size as a string. The default is `100`.
String newDefaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
- // Update the font size on `mainWebView`. The default is `100`.
- MainWebViewActivity.mainWebView.getSettings().setTextZoom(Integer.valueOf(newDefaultFontSizeString));
-
// Update the summary text of `default_font_size`.
defaultFontSizePreference.setSummary(newDefaultFontSizeString + "%%");
- case "swipe_to_refresh_enabled":
- // Set `swipeToRefreshEnabled` to the new state. The default is `true`.
- MainWebViewActivity.swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", true);
-
- // Update `swipeRefreshLayout` to match the new state.
- MainWebViewActivity.swipeToRefresh.setEnabled(MainWebViewActivity.swipeToRefreshEnabled);
- break;
-
default:
// If no match, do nothing.
break;
package com.stoutner.privacybrowser;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
+import android.content.Context;
import android.content.DialogInterface;
import android.net.http.SslCertificate;
import android.net.http.SslError;
import java.util.Date;
-public class SslCertificateError extends DialogFragment{
+public class SslCertificateError extends DialogFragment {
private String primaryError;
private String urlWithError;
private SslCertificateErrorListener sslCertificateErrorListener;
// Check to make sure that the parent activity implements the listener.
- public void onAttach(Activity parentActivity) {
- super.onAttach(parentActivity);
+ public void onAttach(Context context) {
+ super.onAttach(context);
try {
- sslCertificateErrorListener = (SslCertificateErrorListener) parentActivity;
+ sslCertificateErrorListener = (SslCertificateErrorListener) context;
} catch(ClassCastException exception) {
- throw new ClassCastException(parentActivity.toString() + " must implement SslCertificateErrorListener");
+ throw new ClassCastException(context.toString() + " must implement SslCertificateErrorListener");
}
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the activity's layout inflater.
SpannableStringBuilder endDateStringBuilder = new SpannableStringBuilder((endDateLabel + endDate));
// Create a blue `ForegroundColorSpan`. We have to use the deprecated `getColor` until API >= 23.
- ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700));
+ @SuppressWarnings("deprecation") ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700));
// Setup the spans to display the certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
urlStringBuilder.setSpan(blueColorSpan, urlLabel.length(), urlStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
package com.stoutner.privacybrowser;
+import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import java.util.Date;
+// `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+@SuppressLint("InflateParams")
public class ViewSslCertificate extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the activity's layout inflater.
dialogBuilder.setNegativeButton(R.string.close, null);
// Check to see if the website is encrypted.
- if (MainWebViewActivity.mainWebView.getCertificate() == null) { // The website is not encrypted.
+ if (MainWebViewActivity.sslCertificate == null) { // The website is not encrypted.
// Set the title.
dialogBuilder.setTitle(R.string.unencrypted_website);
String endDateLabel = getString(R.string.end_date) + " ";
// Get the SSL certificate.
- SslCertificate sslCertificate = MainWebViewActivity.mainWebView.getCertificate();
+ SslCertificate sslCertificate = MainWebViewActivity.sslCertificate;
// Get the strings from the SSL certificate.
String issuedToCNameString = sslCertificate.getIssuedTo().getCName();
SpannableStringBuilder endDateStringBuilder = new SpannableStringBuilder(endDateLabel + endDate.toString());
// Create a blue `ForegroundColorSpan`. We have to use the deprecated `getColor` until API >= 23.
- ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700));
+ @SuppressWarnings("deprecation") ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700));
// Setup the spans to display the certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
issuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), issuedToCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright 2016 Soren Stoutner <soren@stoutner.com>.
-
- This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
-
- Privacy Browser is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Privacy Browser is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
-
-<!-- This WebView displays inside of the tabs in AboutActivity. -->
-<WebView
- android:id="@+id/about_tab_webview"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright 2016 Soren Stoutner <soren@stoutner.com>.
+
+ This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+
+ Privacy Browser is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Privacy Browser is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
+
+<!-- This WebView displays inside of the tabs in AboutActivity. -->
+<WebView
+ android:id="@+id/bare_webview"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
\ No newline at end of file
android:key="swipe_to_refresh_enabled"
android:title="@string/swipe_to_refresh_enabled"
android:summary="@string/swipe_to_refresh_enabled_summary"
- android:defaultValue="true" />
+ android:defaultValue="false" />
<SwitchPreference
android:key="display_additional_app_bar_icons"
import android.view.View;
class BannerAd {
- public static void requestAd(View view) {
+ static void requestAd(View view) {
// Do nothing because this is the standard flavor.
}
- public static void reloadAfterRotate(View view, Context applicationContext, String ad_id) {
+ static void reloadAfterRotate(View view, Context applicationContext, String ad_id) {
// Do nothing because this is the standard flavor.
}
- public static void hideAd(View view) {
+ static void hideAd(View view) {
// Do nothing because this is the standard flavor.
}
- public static void showAd(View view) {
+ static void showAd(View view) {
// Do nothing because this is the standard flavor.
}
- public static void pauseAd(View view) {
+ static void pauseAd(View view) {
// Do nothing because this is the standard flavor.
}
- public static void resumeAd(View view) {
+ static void resumeAd(View view) {
// Do nothing because this is the standard flavor.
}
}
\ No newline at end of file