// `closeActivityAfterDismissingSnackbar` is used in `onCreate()`, `onOptionsItemSelected()`, and `onBackPressed()`.
private boolean closeActivityAfterDismissingSnackbar;
+ // The favorite icon byte array is populated in `onCreate()` and used in `onOptionsItemSelected()`.
+ private byte[] favoriteIconByteArray;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
// Disable screenshots if not allowed.
Intent launchingIntent = getIntent();
// Set the current folder variable.
- if (launchingIntent.getStringExtra("Current Folder") != null) { // Set the current folder from the intent.
- currentFolder = launchingIntent.getStringExtra("Current Folder");
+ if (launchingIntent.getStringExtra("current_folder") != null) { // Set the current folder from the intent.
+ currentFolder = launchingIntent.getStringExtra("current_folder");
} else { // Set the current folder to be `""`, which is the home folder.
currentFolder = "";
}
+ // Get the favorite icon byte array.
+ favoriteIconByteArray = launchingIntent.getByteArrayExtra("favorite_icon_byte_array");
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
+
// Set the content view.
setContentView(R.layout.bookmarks_coordinatorlayout);
oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
// Show the edit bookmark folder dialog.
- DialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
+ DialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId, favoriteIconBitmap);
editFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_folder));
} else {
// Show the edit bookmark dialog.
- DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
+ DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId, favoriteIconBitmap);
editBookmarkDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark));
}
break;
// Set the create new bookmark folder FAB to display the `AlertDialog`.
createBookmarkFolderFab.setOnClickListener(v -> {
- // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`.
- DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
- createBookmarkFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_folder));
+ // Create a create bookmark folder dialog.
+ DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(favoriteIconBitmap);
+
+ // Show the create bookmark folder dialog.
+ createBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.create_folder));
});
// Set the create new bookmark FAB to display the `AlertDialog`.
createBookmarkFab.setOnClickListener(view -> {
// Instantiate the create bookmark dialog.
- DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebViewUrl, currentWebViewTitle, MainWebViewActivity.favoriteIconBitmap);
+ DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebViewUrl, currentWebViewTitle, favoriteIconBitmap);
// Display the create bookmark dialog.
createBookmarkDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_bookmark));
break;
case R.id.bookmarks_database_view:
- // Launch `BookmarksDatabaseViewActivity`.
+ // Create an intent to launch the bookmarks database view activity.
Intent bookmarksDatabaseViewIntent = new Intent(this, BookmarksDatabaseViewActivity.class);
+
+ // Include the favorite icon byte array to the intent.
+ bookmarksDatabaseViewIntent.putExtra("favorite_icon_byte_array", favoriteIconByteArray);
+
+ // Make it so.
startActivity(bookmarksDatabaseViewIntent);
break;
}
}
@Override
- public void onCreateBookmark(DialogFragment dialogFragment) {
+ public void onCreateBookmark(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
// Get the views from the dialog fragment.
EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext);
EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext);
String bookmarkNameString = createBookmarkNameEditText.getText().toString();
String bookmarkUrlString = createBookmarkUrlEditText.getText().toString();
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIcon = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIcon.getHeight() > 256) || (favoriteIcon.getWidth() > 256)) {
- favoriteIcon = Bitmap.createScaledBitmap(favoriteIcon, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
- favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
// Convert the favorite icon byte array stream to a byte array.
byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
}
@Override
- public void onCreateBookmarkFolder(DialogFragment dialogFragment) {
+ public void onCreateBookmarkFolder(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
// Get handles for the views in the dialog fragment.
EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext);
RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton);
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the WebView favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
}
@Override
- public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+ public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from `dialogFragment`.
EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext);
// Update the bookmark.
if (currentBookmarkIconRadioButton.isChecked()) { // Update the bookmark without changing the favorite icon.
bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString);
- } else { // Update the bookmark using the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
+ } else { // Update the bookmark using the WebView favorite icon.
// Create a favorite icon byte array output stream.
ByteArrayOutputStream newFavoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
}
@Override
- public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) {
+ public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from `dialogFragment`.
RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton);
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the WebView favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the WebView favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.Intent;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
// Run the default commands.
super.onCreate(savedInstanceState);
+ // Get the intent that launched the activity.
+ Intent launchingIntent = getIntent();
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = launchingIntent.getByteArrayExtra("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap and store it in a class variable.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
+
// Set the content view.
setContentView(R.layout.bookmarks_databaseview_coordinatorlayout);
Toolbar toolbar = findViewById(R.id.bookmarks_databaseview_toolbar);
setSupportActionBar(toolbar);
- // Get a handle for the `AppBar`.
+ // Get a handle for the action bar.
ActionBar actionBar = getSupportActionBar();
// Remove the incorrect lint warning that the action bar might be null.
oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
// Show the edit bookmark folder dialog.
- DialogFragment editBookmarkFolderDatabaseViewDialog = EditBookmarkFolderDatabaseViewDialog.folderDatabaseId(databaseId);
+ DialogFragment editBookmarkFolderDatabaseViewDialog = EditBookmarkFolderDatabaseViewDialog.folderDatabaseId(databaseId, favoriteIconBitmap);
editBookmarkFolderDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_folder));
} else {
// Show the edit bookmark dialog.
- DialogFragment editBookmarkDatabaseViewDialog = EditBookmarkDatabaseViewDialog.bookmarkDatabaseId(databaseId);
+ DialogFragment editBookmarkDatabaseViewDialog = EditBookmarkDatabaseViewDialog.bookmarkDatabaseId(databaseId, favoriteIconBitmap);
editBookmarkDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark));
}
});
}
@Override
- public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+ public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from dialog fragment.
RadioButton currentBookmarkIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_current_icon_radiobutton);
EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
if (currentBookmarkIconRadioButton.isChecked()) { // Update the bookmark without changing the favorite icon.
bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString, parentFolderNameString, displayOrderInt);
} else { // Update the bookmark using the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream newFavoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
}
@Override
- public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+ public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from dialog fragment.
RadioButton currentBookmarkIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton);
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the `WebView` favorite icon.
// Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
// `allowScreenshots` is public static so it can be accessed from everywhere. It is also used in `onCreate()`.
public static boolean allowScreenshots;
- // `favoriteIconBitmap` is public static so it can be accessed from `BookmarksActivity`, `BookmarksDatabaseViewActivity`, `CreateBookmarkFolderDialog`,
- // `EditBookmarkDialog`, `EditBookmarkFolderDialog`, `EditBookmarkDatabaseViewDialog`, and `ViewSslCertificateDialog`. It is also used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`,
- // `onCreateHomeScreenShortcut()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `applyDomainSettings()`.
- public static Bitmap favoriteIconBitmap;
-
- // `favoriteIconDefaultBitmap` public static so it can be accessed from `PinnedMismatchDialog`. It is also used in `onCreate()` and `applyDomainSettings`.
- public static Bitmap favoriteIconDefaultBitmap;
-
// TODO Remove.
// `formattedUrlString` is public static so it can be accessed from `AddDomainDialog`, `BookmarksActivity`, `DomainSettingsFragment`, and `PinnedMismatchDialog`.
// It is also used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onCreateHomeScreenShortcutCreate()`, `loadUrlFromTextBox()`, and `applyProxyThroughOrbot()`.
// `navigatingHistory` is used in `onCreate()`, `onNavigationItemSelected()`, `onSslMismatchBack()`, and `applyDomainSettings()`.
- private boolean navigatingHistory;
+ private boolean navigatingHistory; // TODO.
// The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
// `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxyThroughOrbot()`, and `applyDomainSettings()`.
private NestedScrollWebView currentWebView;
- // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`.
- private FrameLayout fullScreenVideoFrameLayout;
-
- // `cookieManager` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`, `loadUrlFromTextBox()`, `onDownloadImage()`, `onDownloadFile()`, and `onRestart()`.
- private CookieManager cookieManager;
-
// `customHeader` is used in `onCreate()`, `onOptionsItemSelected()`, `onCreateContextMenu()`, and `loadUrl()`.
private final Map<String, String> customHeaders = new HashMap<>();
private boolean nightMode;
// 'homepage' is used in `onCreate()`, `onNavigationItemSelected()`, and `applyProxyThroughOrbot()`.
- private String homepage;
+ private String homepage; // TODO ?
// `searchURL` is used in `loadURLFromTextBox()` and `applyProxyThroughOrbot()`.
- private String searchURL;
+ private String searchURL; // TODO ?
// The options menu is set in `onCreateOptionsMenu()` and used in `onOptionsItemSelected()` and `updatePrivacyIcons()`.
private Menu optionsMenu;
// The refresh menu item is set in `onCreateOptionsMenu()` and accessed from `initializeWebView()`.
// It must be this way because `initializeWebView()` runs before the menu is created but doesn't actually modify the menu until later.
- private MenuItem refreshMenuItem;
-
- // The navigation requests menu item is used in `onCreate()` and accessed from `WebViewPagerAdapter`.
- private MenuItem navigationRequestsMenuItem; // TODO.
+ private MenuItem refreshMenuItem; // TODO. Create it from `optionsMenu`.
// TODO. This could probably be removed.
// The blocklist helper is used in `onCreate()` and `WebViewPagerAdapter`.
private ArrayList<List<String[]>> fanboysSocialList;
private ArrayList<List<String[]>> ultraPrivacy;
- // The blocklist menu items are used in `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `initializeWebView()`.
+ // The blocklist menu items are used in `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `initializeWebView()`. // TODO.
private MenuItem blocklistsMenuItem;
private MenuItem easyListMenuItem;
private MenuItem easyPrivacyMenuItem;
// `webViewDefaultUserAgent` is used in `onCreate()` and `onPrepareOptionsMenu()`.
private String webViewDefaultUserAgent;
- // `privacyBrowserRuntime` is used in `onCreate()`, `onOptionsItemSelected()`, and `applyAppSettings()`.
- private Runtime privacyBrowserRuntime;
-
// `proxyThroughOrbot` is used in `onRestart()`, `onOptionsItemSelected()`, `applyAppSettings()`, and `applyProxyThroughOrbot()`.
private boolean proxyThroughOrbot;
// `incognitoModeEnabled` is used in `onCreate()` and `applyAppSettings()`.
- private boolean incognitoModeEnabled;
+ private boolean incognitoModeEnabled; // TODO.
// `fullScreenBrowsingModeEnabled` is used in `onCreate()` and `applyAppSettings()`.
- private boolean fullScreenBrowsingModeEnabled;
+ private boolean fullScreenBrowsingModeEnabled; // TODO.
// `inFullScreenBrowsingMode` is used in `onCreate()`, `onConfigurationChanged()`, and `applyAppSettings()`.
private boolean inFullScreenBrowsingMode;
// Hide app bar is used in `onCreate()` and `applyAppSettings()`.
- private boolean hideAppBar;
+ private boolean hideAppBar; // TODO.
// `reapplyDomainSettingsOnRestart` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `onAddDomain()`, .
private boolean reapplyDomainSettingsOnRestart;
private boolean displayingFullScreenVideo;
// `downloadWithExternalApp` is used in `onCreate()`, `onCreateContextMenu()`, and `applyDomainSettings()`.
- private boolean downloadWithExternalApp;
+ private boolean downloadWithExternalApp; // TODO.
// `orbotStatusBroadcastReceiver` is used in `onCreate()` and `onDestroy()`.
private BroadcastReceiver orbotStatusBroadcastReceiver;
private boolean waitingForOrbot;
// `domainSettingsJavaScriptEnabled` is used in `onOptionsItemSelected()` and `applyDomainSettings()`.
- private Boolean domainSettingsJavaScriptEnabled;
+ private Boolean domainSettingsJavaScriptEnabled; // TODO.
// `waitingForOrbotHtmlString` is used in `onCreate()` and `applyProxyThroughOrbot()`.
- private String waitingForOrbotHtmlString;
+ private String waitingForOrbotHtmlString; // TODO.
// `privateDataDirectoryString` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`.
- private String privateDataDirectoryString;
+ private String privateDataDirectoryString; // TODO.
// `findOnPageEditText` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`.
- private EditText findOnPageEditText;
+ private EditText findOnPageEditText; // TODO.
// `displayAdditionalAppBarIcons` is used in `onCreate()` and `onCreateOptionsMenu()`.
- private boolean displayAdditionalAppBarIcons;
+ private boolean displayAdditionalAppBarIcons; // TODO.
// The action bar drawer toggle is initialized in `onCreate()` and used in `onResume()`.
- private ActionBarDrawerToggle actionBarDrawerToggle;
+ private ActionBarDrawerToggle actionBarDrawerToggle; // TODO.
// The color spans are used in `onCreate()` and `highlightUrlText()`.
private ForegroundColorSpan redColorSpan;
private int drawerHeaderPaddingBottom;
// `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`.
- private SslErrorHandler sslErrorHandler;
+ private SslErrorHandler sslErrorHandler; // TODO.
// `httpAuthHandler` is used in `onCreate()`, `onHttpAuthenticationCancel()`, and `onHttpAuthenticationProceed()`.
- private static HttpAuthHandler httpAuthHandler;
+ private static HttpAuthHandler httpAuthHandler; // TODO.
// `inputMethodManager` is used in `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `closeFindOnPage()`.
- private InputMethodManager inputMethodManager;
+ private InputMethodManager inputMethodManager; // TODO.
// `bookmarksDatabaseHelper` is used in `onCreate()`, `onDestroy`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`,
// and `loadBookmarksFolder()`.
- private BookmarksDatabaseHelper bookmarksDatabaseHelper;
+ private BookmarksDatabaseHelper bookmarksDatabaseHelper; // TODO.
// `bookmarksListView` is used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, and `loadBookmarksFolder()`.
- private ListView bookmarksListView;
+ private ListView bookmarksListView; // TODO.
// `bookmarksTitleTextView` is used in `onCreate()` and `loadBookmarksFolder()`.
- private TextView bookmarksTitleTextView;
+ private TextView bookmarksTitleTextView; // TODO.
// `bookmarksCursor` is used in `onDestroy()`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
private Cursor bookmarksCursor;
finalGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
// Get handles for the URL views.
- RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
EditText urlEditText = findViewById(R.id.url_edittext);
// Remove the formatting from `urlTextBar` when the user is editing the text.
// Get handles for views that need to be modified.
DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
- final NavigationView navigationView = findViewById(R.id.navigationview);
+ NavigationView navigationView = findViewById(R.id.navigationview);
TabLayout tabLayout = findViewById(R.id.tablayout);
SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
ViewPager webViewPager = findViewById(R.id.webviewpager);
FloatingActionButton createBookmarkFolderFab = findViewById(R.id.create_bookmark_folder_fab);
FloatingActionButton createBookmarkFab = findViewById(R.id.create_bookmark_fab);
findOnPageEditText = findViewById(R.id.find_on_page_edittext);
- fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
// Listen for touches on the navigation menu.
navigationView.setNavigationItemSelectedListener(this);
// Get handles for the navigation menu and the back and forward menu items. The menu is zero-based.
- final Menu navigationMenu = navigationView.getMenu();
- final MenuItem navigationCloseTabMenuItem = navigationMenu.getItem(0);
- final MenuItem navigationBackMenuItem = navigationMenu.getItem(3);
- final MenuItem navigationForwardMenuItem = navigationMenu.getItem(4);
- final MenuItem navigationHistoryMenuItem = navigationMenu.getItem(5);
- navigationRequestsMenuItem = navigationMenu.getItem(6);
+ Menu navigationMenu = navigationView.getMenu();
+ MenuItem navigationCloseTabMenuItem = navigationMenu.getItem(0);
+ MenuItem navigationBackMenuItem = navigationMenu.getItem(3);
+ MenuItem navigationForwardMenuItem = navigationMenu.getItem(4);
+ MenuItem navigationHistoryMenuItem = navigationMenu.getItem(5);
+ MenuItem navigationRequestsMenuItem = navigationMenu.getItem(6);
// Initialize the web view pager adapter.
webViewPagerAdapter = new WebViewPagerAdapter(getSupportFragmentManager());
@Override
public void onPageSelected(int position) {
- // Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(position);
-
- // Get the fragment view.
- View fragmentView = webViewTabFragment.getView();
-
- // Remove the incorrect lint warning below that the fragment view might be null.
- assert fragmentView != null;
-
- // Store the current WebView.
- currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
- // Update the privacy icons. `true` redraws the icons in the app bar.
- updatePrivacyIcons(true);
-
- // Store the current formatted URL string.
- formattedUrlString = currentWebView.getUrl();
-
- // Clear the focus from the URL text box.
- urlEditText.clearFocus();
-
- // Hide the soft keyboard.
- inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
-
- // Display the current URL in the URL text box.
- urlEditText.setText(formattedUrlString);
-
- // Highlight the URL text.
- highlightUrlText();
-
- // Set the background to indicate the domain settings status.
- if (currentWebView.getDomainSettingsApplied()) {
- // Set a green background on the URL relative layout to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
- if (darkTheme) {
- urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
- } else {
- urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
- }
- } else {
- urlRelativeLayout.setBackground(getResources().getDrawable(R.color.transparent));
- }
+ // Set the current WebView.
+ setCurrentWebView(position);
// Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled via swiping in the view pager.
if (tabLayout.getSelectedTabPosition() != position) {
@Override
public void onTabReselected(TabLayout.Tab tab) {
// Instantiate the View SSL Certificate dialog.
- DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId());
+ DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId(), currentWebView.getFavoriteOrDefaultIcon());
// Display the View SSL Certificate dialog.
viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate));
// Set the launch bookmarks activity FAB to launch the bookmarks activity.
launchBookmarksActivityFab.setOnClickListener(v -> {
- // Store the current WebView url and title in the bookmarks activity.
+ // Store the current WebView url and title in the bookmarks activity. // TODO.
BookmarksActivity.currentWebViewUrl = currentWebView.getUrl();
BookmarksActivity.currentWebViewTitle = currentWebView.getTitle();
+ // Get a copy of the favorite icon bitmap.
+ Bitmap favoriteIconBitmap = currentWebView.getFavoriteOrDefaultIcon();
+
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the favorite icon byte array stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
// Create an intent to launch the bookmarks activity.
Intent bookmarksIntent = new Intent(getApplicationContext(), BookmarksActivity.class);
- // Include the current folder with the `Intent`.
- bookmarksIntent.putExtra("Current Folder", currentBookmarksFolder);
+ // Add the extra information to the intent.
+ bookmarksIntent.putExtra("current_folder", currentBookmarksFolder);
+ bookmarksIntent.putExtra("favorite_icon_byte_array", favoriteIconByteArray);
// Make it so.
startActivity(bookmarksIntent);
// Set the create new bookmark folder FAB to display an alert dialog.
createBookmarkFolderFab.setOnClickListener(v -> {
- // Show the create bookmark folder dialog and name the instance `@string/create_folder`.
- DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
+ // Create a create bookmark folder dialog.
+ DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteOrDefaultIcon());
+
+ // Show the create bookmark folder dialog.
createBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.create_folder));
});
// Set the create new bookmark FAB to display an alert dialog.
createBookmarkFab.setOnClickListener(view -> {
// Instantiate the create bookmark dialog.
- DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), favoriteIconBitmap);
+ DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteOrDefaultIcon());
// Display the create bookmark dialog.
createBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.create_bookmark));
oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
// Show the edit bookmark folder `AlertDialog` and name the instance `@string/edit_folder`.
- DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
+ DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId, currentWebView.getFavoriteOrDefaultIcon());
editBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.edit_folder));
} else {
// Show the edit bookmark `AlertDialog` and name the instance `@string/edit_bookmark`.
- DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
+ DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId, currentWebView.getFavoriteOrDefaultIcon());
editBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.edit_bookmark));
}
// Create the hamburger icon at the start of the AppBar.
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer);
- // Initialize cookieManager.
- cookieManager = CookieManager.getInstance();
-
// 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", "");
// Initialize the default preference values the first time the program is run. `false` keeps this command from resetting any current preferences back to default.
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
- // Get a handle for the `Runtime`.
- privacyBrowserRuntime = Runtime.getRuntime();
-
// Store the application's private data directory.
privateDataDirectoryString = getApplicationInfo().dataDir;
// `dataDir` will vary, but will be something like `/data/user/0/com.stoutner.privacybrowser.standard`, which links to `/data/data/com.stoutner.privacybrowser.standard`.
// Destroy the bare WebView.
bareWebView.destroy();
- // Initialize the favorite icon bitmap. `ContextCompat` must be used until API >= 21.
- Drawable favoriteIconDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.world);
- BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable;
- assert favoriteIconBitmapDrawable != null;
- favoriteIconDefaultBitmap = favoriteIconBitmapDrawable.getBitmap();
-
- // If the favorite icon is null, load the default.
- if (favoriteIconBitmap == null) {
- favoriteIconBitmap = favoriteIconDefaultBitmap;
- }
-
// Initialize the user agent array adapter and string array.
userAgentNamesArray = ArrayAdapter.createFromResource(this, R.array.user_agent_names, R.layout.spinner_item);
userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
@Override
protected void onNewIntent(Intent intent) {
- // Add a new tab.
- addTab(null);
-
- // Sets the new intent as the activity intent, so that any future `getIntent()`s pick up this one instead of creating a new activity.
- setIntent(intent);
-
// Get the information from the intent.
String intentAction = intent.getAction();
Uri intentUriData = intent.getData();
- // If the intent action is a web search, perform the search.
- if ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)) {
- // Create an encoded URL string.
- String encodedUrlString;
+ // Only process the URI if it contains data. If the user pressed the desktop icon after the app was already running the URI will be null.
+ if (intentUriData != null) {
+ // Sets the new intent as the activity intent, which replaces the one that originally started the app.
+ setIntent(intent);
- // Sanitize the search input and convert it to a search.
- try {
- encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
- } catch (UnsupportedEncodingException exception) {
- encodedUrlString = "";
+ // Add a new tab.
+ addTab(null);
+
+ // If the intent action is a web search, perform the search.
+ if ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)) {
+ // Create an encoded URL string.
+ String encodedUrlString;
+
+ // Sanitize the search input and convert it to a search.
+ try {
+ encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
+ } catch (UnsupportedEncodingException exception) {
+ encodedUrlString = "";
+ }
+
+ // Add the base search URL.
+ formattedUrlString = searchURL + encodedUrlString;
+ } else { // The intent should contain a URL.
+ // Set the formatted URL string.
+ formattedUrlString = intentUriData.toString();
}
- // Add the base search URL.
- formattedUrlString = searchURL + encodedUrlString;
- } else if (intentUriData != null){ // Check to see if the intent contains a new URL.
- // Set the formatted URL string.
- formattedUrlString = intentUriData.toString();
- }
+ // Load the URL.
+ loadUrl(formattedUrlString);
- // Load the URL.
- loadUrl(formattedUrlString);
+ // Get a handle for the drawer layout.
+ DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
- // Get a handle for the drawer layout.
- DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+ // Close the navigation drawer if it is open.
+ if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
+ drawerLayout.closeDrawer(GravityCompat.START);
+ }
- // Close the navigation drawer if it is open.
- if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
- drawerLayout.closeDrawer(GravityCompat.START);
- }
+ // Close the bookmarks drawer if it is open.
+ if (drawerLayout.isDrawerVisible(GravityCompat.END)) {
+ drawerLayout.closeDrawer(GravityCompat.END);
+ }
- // Close the bookmarks drawer if it is open.
- if (drawerLayout.isDrawerVisible(GravityCompat.END)) {
- drawerLayout.closeDrawer(GravityCompat.END);
+ // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
+ currentWebView.requestFocus();
}
-
- // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
- currentWebView.requestFocus();
}
@Override
MenuItem nightModeMenuItem = menu.findItem(R.id.night_mode);
MenuItem proxyThroughOrbotMenuItem = menu.findItem(R.id.proxy_through_orbot);
+ // Get a handle for the cookie manager.
+ CookieManager cookieManager = CookieManager.getInstance();
+
// Initialize the current user agent string and the font size.
String currentUserAgent = getString(R.string.user_agent_privacy_browser);
int fontSize = 100;
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+ // Get a handle for the cookie manager.
+ CookieManager cookieManager = CookieManager.getInstance();
+
// Run the commands that correlate to the selected menu item.
switch (menuItemId) {
case R.id.toggle_javascript:
// Setup a runnable to manually delete the DOM storage files and directories.
Runnable deleteDomStorageRunnable = () -> {
try {
+ // Get a handle for the runtime.
+ Runtime runtime = Runtime.getRuntime();
+
// A string array must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
- Process deleteLocalStorageProcess = privacyBrowserRuntime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
+ Process deleteLocalStorageProcess = runtime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
// Multiple commands must be used because `Runtime.exec()` does not like `*`.
- Process deleteIndexProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
- Process deleteQuotaManagerProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
- Process deleteQuotaManagerJournalProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
- Process deleteDatabasesProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
+ Process deleteIndexProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
+ Process deleteQuotaManagerProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
+ Process deleteQuotaManagerJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
+ Process deleteDatabasesProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
// Wait for the processes to finish.
deleteLocalStorageProcess.waitFor();
case R.id.add_to_homescreen:
// Instantiate the create home screen shortcut dialog.
- DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), formattedUrlString, favoriteIconBitmap);
+ DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), formattedUrlString, currentWebView.getFavoriteOrDefaultIcon());
// Show the create home screen shortcut dialog.
createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut));
// Run the commands that correspond to the selected menu item.
switch (menuItemId) {
case R.id.close_tab:
- // Get a handle for the tab layout.
+ // Get a handle for the tab layout and the view pager.
TabLayout tabLayout = findViewById(R.id.tablayout);
+ ViewPager webViewPager = findViewById(R.id.webviewpager);
// Get the current tab number.
int currentTabNumber = tabLayout.getSelectedTabPosition();
// Delete the current tab.
tabLayout.removeTabAt(currentTabNumber);
- // Delete the current page.
- webViewPagerAdapter.deletePage(currentTabNumber);
+ // Delete the current page. If the selected page number did not change during the delete, it will return true, meaning that the current WebView must be reset.
+ if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) {
+ setCurrentWebView(currentTabNumber);
+ }
break;
case R.id.clear_and_exit:
// Get the status of the clear everything preference.
boolean clearEverything = sharedPreferences.getBoolean("clear_everything", true);
+ // Get a handle for the runtime.
+ Runtime runtime = Runtime.getRuntime();
+
// Clear cookies.
if (clearEverything || sharedPreferences.getBoolean("clear_cookies", true)) {
// The command to remove cookies changed slightly in API 21.
if (Build.VERSION.SDK_INT >= 21) {
- cookieManager.removeAllCookies(null);
+ CookieManager.getInstance().removeAllCookies(null);
} else {
- cookieManager.removeAllCookie();
+ CookieManager.getInstance().removeAllCookie();
}
// Manually delete the cookies database, as `CookieManager` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// Two commands must be used because `Runtime.exec()` does not like `*`.
- Process deleteCookiesProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies");
- Process deleteCookiesJournalProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies-journal");
+ Process deleteCookiesProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies");
+ Process deleteCookiesJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies-journal");
// Wait until the processes have finished.
deleteCookiesProcess.waitFor();
// Manually delete the DOM storage files and directories, as `WebStorage` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// A `String[]` must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
- Process deleteLocalStorageProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
+ Process deleteLocalStorageProcess = runtime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
// Multiple commands must be used because `Runtime.exec()` does not like `*`.
- Process deleteIndexProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
- Process deleteQuotaManagerProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
- Process deleteQuotaManagerJournalProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
- Process deleteDatabaseProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
+ Process deleteIndexProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
+ Process deleteQuotaManagerProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
+ Process deleteQuotaManagerJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
+ Process deleteDatabaseProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
// Wait until the processes have finished.
deleteLocalStorageProcess.waitFor();
// Manually delete the form data database, as `WebViewDatabase` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// A string array must be used because the database contains a space and `Runtime.exec` will not otherwise escape the string correctly.
- Process deleteWebDataProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data"});
- Process deleteWebDataJournalProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data-journal"});
+ Process deleteWebDataProcess = runtime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data"});
+ Process deleteWebDataJournalProcess = runtime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data-journal"});
// Wait until the processes have finished.
deleteWebDataProcess.waitFor();
// Manually delete the cache directories.
try {
// Delete the main cache directory.
- Process deleteCacheProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/cache");
+ Process deleteCacheProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/cache");
// Delete the secondary `Service Worker` cache directory.
// A string array must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
- Process deleteServiceWorkerProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
+ Process deleteServiceWorkerProcess = runtime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
// Wait until the processes have finished.
deleteCacheProcess.waitFor();
if (clearEverything) {
try {
// Delete the folder.
- Process deleteAppWebviewProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview");
+ Process deleteAppWebviewProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview");
// Wait until the process has finished.
deleteAppWebviewProcess.waitFor();
}
@Override
- public void onCreateBookmark(DialogFragment dialogFragment) {
+ public void onCreateBookmark(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
// Get the views from the dialog fragment.
EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext);
EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext);
String bookmarkNameString = createBookmarkNameEditText.getText().toString();
String bookmarkUrlString = createBookmarkUrlEditText.getText().toString();
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIcon = favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIcon.getHeight() > 256) || (favoriteIcon.getWidth() > 256)) {
- favoriteIcon = Bitmap.createScaledBitmap(favoriteIcon, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
- favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
// Convert the favorite icon byte array stream to a byte array.
byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
}
@Override
- public void onCreateBookmarkFolder(DialogFragment dialogFragment) {
+ public void onCreateBookmarkFolder(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
// Get handles for the views in the dialog fragment.
EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext);
RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton);
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the WebView favorite icon.
- // Get a copy of the favorite icon bitmap.
+ // Copy the favorite icon bitmap to the folder icon bitmap.
folderIconBitmap = favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
}
// Create a folder icon byte array output stream.
}
@Override
- public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+ public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from `dialogFragment`.
EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext);
if (currentBookmarkIconRadioButton.isChecked()) { // Update the bookmark without changing the favorite icon.
bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString);
} else { // Update the bookmark using the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIcon = favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIcon.getHeight() > 256) || (favoriteIcon.getWidth() > 256)) {
- favoriteIcon = Bitmap.createScaledBitmap(favoriteIcon, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream newFavoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
- favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, newFavoriteIconByteArrayOutputStream);
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, newFavoriteIconByteArrayOutputStream);
// Convert the favorite icon byte array stream to a byte array.
byte[] newFavoriteIconByteArray = newFavoriteIconByteArrayOutputStream.toByteArray();
}
@Override
- public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) {
+ public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from `dialogFragment`.
EditText editFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_folder_name_edittext);
RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
// Code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
if (firstPartyCookiesEnabled) {
// Get the cookies for `imageUrl`.
- String cookies = cookieManager.getCookie(imageUrl);
+ String cookies = CookieManager.getInstance().getCookie(imageUrl);
// Add the cookies to `downloadRequest`. In the HTTP request header, cookies are named `Cookie`.
downloadRequest.addRequestHeader("Cookie", cookies);
// Code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
if (firstPartyCookiesEnabled) {
// Get the cookies for `downloadUrl`.
- String cookies = cookieManager.getCookie(downloadUrl);
+ String cookies = CookieManager.getInstance().getCookie(downloadUrl);
// Add the cookies to `downloadRequest`. In the HTTP request header, cookies are named `Cookie`.
downloadRequest.addRequestHeader("Cookie", cookies);
// Reset the favorite icon if specified.
if (resetFavoriteIcon) {
- // Store the favorite icon bitmap.
- favoriteIconBitmap = favoriteIconDefaultBitmap; // TODO.
+ // Initialize the favorite icon.
+ currentWebView.initializeFavoriteIcon();
// Get a handle for the tab layout.
TabLayout tabLayout = findViewById(R.id.tablayout);
ImageView currentTabFavoriteIconImageView = currentTabCustomView.findViewById(R.id.favorite_icon_imageview);
// Set the default favorite icon as the favorite icon for this tab.
- currentTabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(favoriteIconBitmap, 64, 64, true));
+ currentTabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true));
}
// Get a handle for the swipe refresh layout.
nightMode = sharedPreferences.getBoolean("night_mode", false); // TODO.
boolean displayWebpageImages = sharedPreferences.getBoolean("display_webpage_images", true);
+ // Get a handle for the cookie manager.
+ CookieManager cookieManager = CookieManager.getInstance();
+
if (nestedScrollWebView.getDomainSettingsApplied()) { // The url has custom domain settings.
// Get a cursor for the current host and move it to the first position.
Cursor currentDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase);
webViewPagerAdapter.addPage(newTabNumber, webViewPager);
}
+ private void setCurrentWebView(int pageNumber) {
+ // Get handles for the URL views.
+ RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
+ EditText urlEditText = findViewById(R.id.url_edittext);
+
+ // Get the WebView tab fragment.
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(pageNumber);
+
+ // Get the fragment view.
+ View fragmentView = webViewTabFragment.getView();
+
+ // Remove the incorrect lint warning below that the fragment view might be null.
+ assert fragmentView != null;
+
+ // Store the current WebView.
+ currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+
+ // Update the privacy icons. `true` redraws the icons in the app bar.
+ updatePrivacyIcons(true);
+
+ // Store the current formatted URL string.
+ formattedUrlString = currentWebView.getUrl();
+
+ // Clear the focus from the URL text box.
+ urlEditText.clearFocus();
+
+ // Hide the soft keyboard.
+ inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
+
+ // Display the current URL in the URL text box.
+ urlEditText.setText(formattedUrlString);
+
+ // Highlight the URL text.
+ highlightUrlText();
+
+ // Set the background to indicate the domain settings status.
+ if (currentWebView.getDomainSettingsApplied()) {
+ // Set a green background on the URL relative layout to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
+ if (darkTheme) {
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
+ } else {
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
+ }
+ } else {
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.color.transparent));
+ }
+ }
+
@Override
public void initializeWebView(NestedScrollWebView nestedScrollWebView, int pageNumber, ProgressBar progressBar) {
// Get handles for the activity views.
// Get the relevant preferences.
boolean downloadWithExternalApp = sharedPreferences.getBoolean("download_with_external_app", false);
+ // Initialize the favorite icon.
+ nestedScrollWebView.initializeFavoriteIcon();
+
// Set the app bar scrolling.
nestedScrollWebView.setNestedScrollingEnabled(sharedPreferences.getBoolean("scroll_app_bar", true));
public void onReceivedIcon(WebView view, Bitmap icon) {
// Only update the favorite icon if the website has finished loading.
if (progressBar.getVisibility() == View.GONE) {
- // Save a copy of the favorite icon.
- favoriteIconBitmap = icon;
+ // Store the new favorite icon.
+ nestedScrollWebView.setFavoriteOrDefaultIcon(icon);
// Get the current page position.
int currentPosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
// Get the current tab.
TabLayout.Tab tab = tabLayout.getTabAt(currentPosition);
- // Remove the lint warning below that the current tab might be null.
- assert tab != null;
-
- // Get the custom view from the tab.
- View tabView = tab.getCustomView();
+ // Only populate the title text view if the tab has been fully created.
+ if (tab != null) {
+ // Get the custom view from the tab.
+ View tabView = tab.getCustomView();
- // Remove the incorrect warning below that the current tab view might be null.
- assert tabView != null;
+ // Remove the incorrect warning below that the current tab view might be null.
+ assert tabView != null;
- // Get the title text view from the tab.
- TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
+ // Get the title text view from the tab.
+ TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
- // Set the title as the tab text.
- tabTitleTextView.setText(title);
+ // Set the title as the tab text.
+ tabTitleTextView.setText(title);
+ }
}
// Enter full screen video.
@Override
public void onShowCustomView(View video, CustomViewCallback callback) {
+ // Get a handle for the full screen video frame layout.
+ FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
+
// Set the full screen video flag.
displayingFullScreenVideo = true;
// Exit full screen video.
@Override
public void onHideCustomView() {
+ // Get a handle for the full screen video frame layout.
+ FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
+
// Unset the full screen video flag.
displayingFullScreenVideo = false;
@SuppressWarnings("deprecation")
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
+ // Get a handle for the navigation view.
+ NavigationView navigationView = findViewById(R.id.navigationview);
+
+ // Get a handle for the navigation menu.
+ Menu navigationMenu = navigationView.getMenu();
+
+ // Get a handle for the navigation requests menu item. The menu is 0 based.
+ MenuItem navigationRequestsMenuItem = navigationMenu.getItem(6);
+
// Create an empty web resource response to be used if the resource request is blocked.
WebResourceResponse emptyWebResourceResponse = new WebResourceResponse("text/plain", "utf8", new ByteArrayInputStream("".getBytes()));
// Process the EasyPrivacy results.
if (easyPrivacyResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched EasyPrivacy's blacklist.
// Add the result to the resource requests.
- nestedScrollWebView.addResourceRequest(new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[5],
+ nestedScrollWebView.addResourceRequest(new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4],
easyPrivacyResults[5]});
// Increment the blocked requests counters.
// Flush any cookies to persistent storage. `CookieManager` has become very lazy about flushing cookies in recent versions.
if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
- cookieManager.flush();
+ CookieManager.getInstance().flush();
}
// Update the Refresh menu item if it has been created.
// Manually delete cache folders.
try {
// Delete the main cache directory.
- privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/cache");
+ Runtime.getRuntime().exec("rm -rf " + privateDataDirectoryString + "/cache");
// Delete the secondary `Service Worker` cache directory.
// A `String[]` must be used because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise.
- privacyBrowserRuntime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
+ Runtime.getRuntime().exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
} catch (IOException e) {
// Do nothing if an error is thrown.
}
}
}
- public void deletePage(int pageNumber) {
+ public boolean deletePage(int pageNumber, ViewPager webViewPager) {
// Delete the page.
webViewFragmentsList.remove(pageNumber);
// Update the view pager.
notifyDataSetChanged();
+
+ // Return true if the selected page number did not change after the delete. This will cause the calling method to reset the current WebView to the new contents of this page number.
+ return (webViewPager.getCurrentItem() == pageNumber);
}
public WebViewTabFragment getPageFragment(int pageNumber) {
import java.io.ByteArrayOutputStream;
public class CreateBookmarkDialog extends DialogFragment {
- // Create the class variables.
- String url;
- String title;
- Bitmap favoriteIconBitmap;
-
// The public interface is used to send information back to the parent activity.
public interface CreateBookmarkListener {
- void onCreateBookmark(DialogFragment dialogFragment);
+ void onCreateBookmark(DialogFragment dialogFragment, Bitmap favoriteIconBitmap);
}
// The create bookmark listener is initialized in `onAttach()` and used in `onCreateDialog()`.
}
public static CreateBookmarkDialog createBookmark(String url, String title, Bitmap favoriteIconBitmap) {
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Convert the byte array output stream to a byte array.
byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
- // Create a bundle.
- Bundle bundle = new Bundle();
+ // Create an arguments bundle.
+ Bundle argumentsBundle = new Bundle();
- // Store the variables in the bundle
- bundle.putString("url", url);
- bundle.putString("title", title);
- bundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
+ // Store the variables in the bundle.
+ argumentsBundle.putString("url", url);
+ argumentsBundle.putString("title", title);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
// Create a new instance of the dialog.
CreateBookmarkDialog createBookmarkDialog = new CreateBookmarkDialog();
// Add the bundle to the dialog.
- createBookmarkDialog.setArguments(bundle);
+ createBookmarkDialog.setArguments(argumentsBundle);
// Return the new dialog.
return createBookmarkDialog;
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
- public void onCreate(Bundle savedInstanceState) {
- // Run the default commands.
- super.onCreate(savedInstanceState);
-
+ @NonNull
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the arguments.
Bundle arguments = getArguments();
// Remove the incorrect lint warning below that the arguments might be null.
assert arguments != null;
- // Store the contents of the arguments in class variables.
- url = arguments.getString("url");
- title = arguments.getString("title");
+ // Get the strings from the arguments.
+ String url = arguments.getString("url");
+ String title = arguments.getString("title");
// Get the favorite icon byte array.
byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
// Remove the incorrect lint warning below that the favorite icon byte array might be null.
assert favoriteIconByteArray != null;
- // Convert the favorite icon byte array to a bitmap and store it in a class variable.
- favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
- }
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
- // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
- @SuppressLint("InflateParams")
- @Override
- @NonNull
- public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
// Set an `onClick()` listener for the positive button.
dialogBuilder.setPositiveButton(R.string.create, (DialogInterface dialog, int which) -> {
// Return the `DialogFragment` to the parent activity.
- createBookmarkListener.onCreateBookmark(CreateBookmarkDialog.this);
+ createBookmarkListener.onCreateBookmark(this, favoriteIconBitmap);
});
// Create an `AlertDialog` from the `AlertDialog.Builder`.
- final AlertDialog alertDialog = dialogBuilder.create();
+ AlertDialog alertDialog = dialogBuilder.create();
// Remove the warning below that `getWindow()` might be null.
assert alertDialog.getWindow() != null;
// If the event is a key-down on the `enter` key, select the `PositiveButton` `Create`.
if ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) {
// Trigger `createBookmarkListener` and return the `DialogFragment` to the parent activity.
- createBookmarkListener.onCreateBookmark(CreateBookmarkDialog.this);
+ createBookmarkListener.onCreateBookmark(this, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
// If the event is a key-down on the "enter" key, select the PositiveButton "Create".
if ((keyCode == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) {
// Trigger `createBookmarkListener` and return the DialogFragment to the parent activity.
- createBookmarkListener.onCreateBookmark(CreateBookmarkDialog.this);
+ createBookmarkListener.onCreateBookmark(this, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
+import java.io.ByteArrayOutputStream;
+
public class CreateBookmarkFolderDialog extends DialogFragment {
// The public interface is used to send information back to the parent activity.
public interface CreateBookmarkFolderListener {
- void onCreateBookmarkFolder(DialogFragment dialogFragment);
+ void onCreateBookmarkFolder(DialogFragment dialogFragment, Bitmap favoriteIconBitmap);
}
// `createBookmarkFolderListener` is used in `onAttach()` and `onCreateDialog`.
createBookmarkFolderListener = (CreateBookmarkFolderListener) context;
}
+ public static CreateBookmarkFolderDialog createBookmarkFolder(Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
+ // Create an arguments bundle.
+ Bundle argumentsBundle = new Bundle();
+
+ // Store the favorite icon in the bundle.
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
+
+ // Create a new instance of the dialog.
+ CreateBookmarkFolderDialog createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
+
+ // Add the bundle to the dialog.
+ createBookmarkFolderDialog.setArguments(argumentsBundle);
+
+ // Return the new dialog.
+ return createBookmarkFolderDialog;
+ }
+
// `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
@SuppressLint("InflateParams")
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
+ // Remove the incorrect lint warning below that the arguments might be null.
+ assert arguments != null;
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
+
// Use an alert dialog builder to create the alert dialog.
AlertDialog.Builder dialogBuilder;
// Set an `onClick()` listener fo the positive button.
dialogBuilder.setPositiveButton(R.string.create, (DialogInterface dialog, int which) -> {
// Return the `DialogFragment` to the parent activity on create.
- createBookmarkFolderListener.onCreateBookmarkFolder(CreateBookmarkFolderDialog.this);
+ createBookmarkFolderListener.onCreateBookmarkFolder(this, favoriteIconBitmap);
});
// If the event is a key-down on the `enter` key, select the `PositiveButton` `Create`.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && createButton.isEnabled()) { // The enter key was pressed and the create button is enabled.
// Trigger `createBookmarkFolderListener` and return the `DialogFragment` to the parent activity.
- createBookmarkFolderListener.onCreateBookmarkFolder(CreateBookmarkFolderDialog.this);
+ createBookmarkFolderListener.onCreateBookmarkFolder(this, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
// Consume the event.
}
});
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Display the current favorite icon.
webPageIconImageView.setImageBitmap(favoriteIconBitmap);
import java.io.ByteArrayOutputStream;
public class CreateHomeScreenShortcutDialog extends DialogFragment {
- // Create the class variables.
- private String initialShortcutName;
- private String initialUrlString;
- private Bitmap favoriteIconBitmap;
+ // Define the class variables.
private EditText shortcutNameEditText;
private EditText urlEditText;
private RadioButton openWithPrivacyBrowserRadioButton;
- private Button createButton;
public static CreateHomeScreenShortcutDialog createDialog(String shortcutName, String urlString, Bitmap favoriteIconBitmap) {
// Create a favorite icon byte array output stream.
return createHomeScreenShortcutDialog;
}
+ // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
+ @SuppressLint("InflateParams")
@Override
- public void onCreate(Bundle savedInstanceState) {
- // Run the default commands.
- super.onCreate(savedInstanceState);
-
+ @NonNull
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the arguments.
Bundle arguments = getArguments();
// Remove the incorrect lint warning below that the arguments might be null.
assert arguments != null;
- // Store the strings in class variables.
- initialShortcutName = arguments.getString("shortcut_name");
- initialUrlString = arguments.getString("url_string");
+ // Get the strings from the arguments.
+ String initialShortcutName = arguments.getString("shortcut_name");
+ String initialUrlString = arguments.getString("url_string");
// Get the favorite icon byte array.
byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
assert favoriteIconByteArray != null;
// Convert the favorite icon byte array to a bitmap and store it in a class variable.
- favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
- }
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
- // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
- @SuppressLint("InflateParams")
- @Override
- @NonNull
- public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
// Set an `onClick` listener on the create button.
dialogBuilder.setPositiveButton(R.string.create, (DialogInterface dialog, int which) -> {
// Create the home screen shortcut.
- createHomeScreenShortcut();
+ createHomeScreenShortcut(favoriteIconBitmap);
});
// Create an alert dialog from the alert dialog builder.
shortcutNameEditText = alertDialog.findViewById(R.id.shortcut_name_edittext);
urlEditText = alertDialog.findViewById(R.id.url_edittext);
openWithPrivacyBrowserRadioButton = alertDialog.findViewById(R.id.open_with_privacy_browser_radiobutton);
- createButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ Button createButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
// Populate the edit texts.
shortcutNameEditText.setText(initialShortcutName);
@Override
public void afterTextChanged(Editable s) {
// Update the create button.
- updateCreateButton();
+ updateCreateButton(createButton);
}
});
@Override
public void afterTextChanged(Editable s) {
// Update the create button.
- updateCreateButton();
+ updateCreateButton(createButton);
}
});
// Check the status of the create button.
if (createButton.isEnabled()) { // The create button is enabled.
// Create the home screen shortcut.
- createHomeScreenShortcut();
+ createHomeScreenShortcut(favoriteIconBitmap);
// Manually dismiss the alert dialog.
alertDialog.dismiss();
// Check the status of the create button.
if (createButton.isEnabled()) { // The create button is enabled.
// Create the home screen shortcut.
- createHomeScreenShortcut();
+ createHomeScreenShortcut(favoriteIconBitmap);
// Manually dismiss the alert dialog.
alertDialog.dismiss();
return alertDialog;
}
- private void updateCreateButton() {
+ private void updateCreateButton(Button createButton) {
// Get the contents of the edit texts.
String shortcutName = shortcutNameEditText.getText().toString();
String urlString = urlEditText.getText().toString();
createButton.setEnabled(!shortcutName.isEmpty() && !urlString.isEmpty());
}
- private void createHomeScreenShortcut() {
+ private void createHomeScreenShortcut(Bitmap favoriteIconBitmap) {
// Get a handle for the context.
Context context = getContext();
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
+import java.io.ByteArrayOutputStream;
+
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22.
public class EditBookmarkDatabaseViewDialog extends DialogFragment {
- // Instantiate the constants.
+ // Define the home folder database ID constant.
public static final int HOME_FOLDER_DATABASE_ID = -1;
- // Instantiate the class variables.
+ // Define the edit bookmark database view listener.
private EditBookmarkDatabaseViewListener editBookmarkDatabaseViewListener;
- private String currentBookmarkName;
- private String currentUrl;
- private int currentFolderDatabaseId;
- private String currentDisplayOrder;
- private RadioButton newIconRadioButton;
- private EditText nameEditText;
- private EditText urlEditText;
- private Spinner folderSpinner;
- private EditText displayOrderEditText;
- private Button editButton;
+
// The public interface is used to send information back to the parent activity.
public interface EditBookmarkDatabaseViewListener {
- void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId);
+ void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap);
}
@Override
editBookmarkDatabaseViewListener = (EditBookmarkDatabaseViewListener) context;
}
- // Store the database ID in the arguments bundle.
- public static EditBookmarkDatabaseViewDialog bookmarkDatabaseId(int databaseId) {
- // Create a bundle.
- Bundle bundle = new Bundle();
- // Store the bookmark database ID in the bundle.
- bundle.putInt("Database ID", databaseId);
+ public static EditBookmarkDatabaseViewDialog bookmarkDatabaseId(int databaseId, Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
- // Add the bundle to the dialog.
+ // Create an arguments bundle.
+ Bundle argumentsBundle = new Bundle();
+
+ // Store the variables in the bundle.
+ argumentsBundle.putInt("database_id", databaseId);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
+
+ // Create a new instance of the dialog.
EditBookmarkDatabaseViewDialog editBookmarkDatabaseViewDialog = new EditBookmarkDatabaseViewDialog();
- editBookmarkDatabaseViewDialog.setArguments(bundle);
+
+ // Add the arguments bundle to the dialog.
+ editBookmarkDatabaseViewDialog.setArguments(argumentsBundle);
// Return the new dialog.
return editBookmarkDatabaseViewDialog;
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
- // Remove the incorrect lint warning below that `getInt()` might be null.
- assert getArguments() != null;
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
+ // Remove the incorrect lint warning below that the arguments might be null.
+ assert arguments != null;
// Get the bookmark database ID from the bundle.
- int bookmarkDatabaseId = getArguments().getInt("Database ID");
+ int bookmarkDatabaseId = getArguments().getInt("database_id");
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
// Initialize the database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
// Do nothing. The `AlertDialog` will close automatically.
});
- // Set the listener fo the positive button.
+ // Set the listener for the positive button.
dialogBuilder.setPositiveButton(R.string.save, (DialogInterface dialog, int which) -> {
// Return the `DialogFragment` to the parent activity on save.
- editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId);
+ editBookmarkDatabaseViewListener.onSaveBookmark(this, bookmarkDatabaseId, favoriteIconBitmap);
});
// Create an alert dialog from the alert dialog builder`.
RadioGroup iconRadioGroup = alertDialog.findViewById(R.id.edit_bookmark_icon_radiogroup);
ImageView currentIconImageView = alertDialog.findViewById(R.id.edit_bookmark_current_icon);
ImageView newFavoriteIconImageView = alertDialog.findViewById(R.id.edit_bookmark_webpage_favorite_icon);
- newIconRadioButton = alertDialog.findViewById(R.id.edit_bookmark_webpage_favorite_icon_radiobutton);
- nameEditText = alertDialog.findViewById(R.id.edit_bookmark_name_edittext);
- urlEditText = alertDialog.findViewById(R.id.edit_bookmark_url_edittext);
- folderSpinner = alertDialog.findViewById(R.id.edit_bookmark_folder_spinner);
- displayOrderEditText = alertDialog.findViewById(R.id.edit_bookmark_display_order_edittext);
- editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ RadioButton newIconRadioButton = alertDialog.findViewById(R.id.edit_bookmark_webpage_favorite_icon_radiobutton);
+ EditText nameEditText = alertDialog.findViewById(R.id.edit_bookmark_name_edittext);
+ EditText urlEditText = alertDialog.findViewById(R.id.edit_bookmark_url_edittext);
+ Spinner folderSpinner = alertDialog.findViewById(R.id.edit_bookmark_folder_spinner);
+ EditText displayOrderEditText = alertDialog.findViewById(R.id.edit_bookmark_display_order_edittext);
+ Button editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
// Store the current bookmark values.
- currentBookmarkName = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
- currentUrl = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_URL));
- currentDisplayOrder = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER));
+ String currentBookmarkName = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
+ String currentUrl = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_URL));
+ int currentDisplayOrder = bookmarkCursor.getInt(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER));
// Set the database ID.
databaseIdTextView.setText(String.valueOf(bookmarkCursor.getInt(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper._ID))));
// Display `currentIconBitmap` in `edit_bookmark_current_icon`.
currentIconImageView.setImageBitmap(currentIconBitmap);
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Set the new favorite icon bitmap.
newFavoriteIconImageView.setImageBitmap(favoriteIconBitmap);
}
// Store the current folder database ID.
- currentFolderDatabaseId = (int) folderSpinner.getSelectedItemId();
+ int currentFolderDatabaseId = (int) folderSpinner.getSelectedItemId();
// Populate the display order `EditText`.
displayOrderEditText.setText(String.valueOf(bookmarkCursor.getInt(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER))));
// Update the edit button if the icon selection changes.
iconRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {
// Update the edit button.
- updateEditButton();
+ updateEditButton(nameEditText, urlEditText, displayOrderEditText, folderSpinner, newIconRadioButton, editButton, currentBookmarkName, currentUrl, currentFolderDatabaseId, currentDisplayOrder);
});
// Update the edit button if the bookmark name changes.
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(nameEditText, urlEditText, displayOrderEditText, folderSpinner, newIconRadioButton, editButton, currentBookmarkName, currentUrl, currentFolderDatabaseId, currentDisplayOrder);
}
});
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(nameEditText, urlEditText, displayOrderEditText, folderSpinner, newIconRadioButton, editButton, currentBookmarkName, currentUrl, currentFolderDatabaseId, currentDisplayOrder);
}
});
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(nameEditText, urlEditText, displayOrderEditText, folderSpinner, newIconRadioButton, editButton, currentBookmarkName, currentUrl, currentFolderDatabaseId, currentDisplayOrder);
}
@Override
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(nameEditText, urlEditText, displayOrderEditText, folderSpinner, newIconRadioButton, editButton, currentBookmarkName, currentUrl, currentFolderDatabaseId, currentDisplayOrder);
}
});
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the `DialogFragment` to the parent activity.
- editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId);
+ editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId, favoriteIconBitmap);
// Manually dismiss `alertDialog`.
alertDialog.dismiss();
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the `DialogFragment` to the parent activity.
- editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId);
+ editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the `DialogFragment` to the parent activity.
- editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId);
+ editBookmarkDatabaseViewListener.onSaveBookmark(EditBookmarkDatabaseViewDialog.this, bookmarkDatabaseId, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
return alertDialog;
}
- private void updateEditButton() {
+ private void updateEditButton(EditText nameEditText, EditText urlEditText, EditText displayOrderEditText, Spinner folderSpinner, RadioButton newIconRadioButton, Button editButton,
+ String currentBookmarkName, String currentUrl, int currentFolderDatabaseId, int currentDisplayOrder) {
// Get the values from the dialog.
String newName = nameEditText.getText().toString();
String newUrl = urlEditText.getText().toString();
boolean folderChanged = newFolderDatabaseId != currentFolderDatabaseId;
// Has the display order changed?
- boolean displayOrderChanged = !newDisplayOrder.equals(currentDisplayOrder);
+ boolean displayOrderChanged = !newDisplayOrder.equals(String.valueOf(currentDisplayOrder));
// Is the display order empty?
boolean displayOrderNotEmpty = !newDisplayOrder.isEmpty();
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
+import java.io.ByteArrayOutputStream;
+
public class EditBookmarkDialog extends DialogFragment {
- // Instantiate the class variables.
+ // Define the edit bookmark listener.
private EditBookmarkListener editBookmarkListener;
- private EditText nameEditText;
- private EditText urlEditText;
- private RadioButton newIconRadioButton;
- private Button editButton;
- private String currentName;
- private String currentUrl;
// The public interface is used to send information back to the parent activity.
public interface EditBookmarkListener {
- void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId);
+ void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap);
}
public void onAttach(Context context) {
}
// Store the database ID in the arguments bundle.
- public static EditBookmarkDialog bookmarkDatabaseId(int databaseId) {
- // Create a bundle.
- Bundle bundle = new Bundle();
+ public static EditBookmarkDialog bookmarkDatabaseId(int databaseId, Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
+ // Create an arguments bundle.
+ Bundle argumentsBundle = new Bundle();
- // Store the bookmark database ID in the bundle.
- bundle.putInt("Database ID", databaseId);
+ // Store the variables in the bundle.
+ argumentsBundle.putInt("database_id", databaseId);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
- // Add the bundle to the dialog.
+ // Create a new instance of the dialog.
EditBookmarkDialog editBookmarkDialog = new EditBookmarkDialog();
- editBookmarkDialog.setArguments(bundle);
+
+ // Add the arguments bundle to the dialog.
+ editBookmarkDialog.setArguments(argumentsBundle);
// Return the new dialog.
return editBookmarkDialog;
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
- // Remove the incorrect lint warning that `getInt()` might be null.
- assert getArguments() != null;
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
+ // Remove the incorrect lint warning below that the arguments might be null.
+ assert arguments != null;
// Store the bookmark database ID in the class variable.
- int selectedBookmarkDatabaseId = getArguments().getInt("Database ID");
+ int selectedBookmarkDatabaseId = arguments.getInt("database_id");
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
// Initialize the database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
// Set the save button listener.
dialogBuilder.setPositiveButton(R.string.save, (DialogInterface dialog, int which) -> {
// Return the dialog fragment to the parent activity.
- editBookmarkListener.onSaveBookmark(EditBookmarkDialog.this, selectedBookmarkDatabaseId);
+ editBookmarkListener.onSaveBookmark(this, selectedBookmarkDatabaseId, favoriteIconBitmap);
});
// Create an alert dialog from the builder.
RadioGroup iconRadioGroup = alertDialog.findViewById(R.id.edit_bookmark_icon_radiogroup);
ImageView currentIconImageView = alertDialog.findViewById(R.id.edit_bookmark_current_icon);
ImageView newFavoriteIconImageView = alertDialog.findViewById(R.id.edit_bookmark_webpage_favorite_icon);
- newIconRadioButton = alertDialog.findViewById(R.id.edit_bookmark_webpage_favorite_icon_radiobutton);
- nameEditText = alertDialog.findViewById(R.id.edit_bookmark_name_edittext);
- urlEditText = alertDialog.findViewById(R.id.edit_bookmark_url_edittext);
- editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ EditText nameEditText = alertDialog.findViewById(R.id.edit_bookmark_name_edittext);
+ EditText urlEditText = alertDialog.findViewById(R.id.edit_bookmark_url_edittext);
+ Button editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
// Get the current favorite icon byte array from the cursor.
byte[] currentIconByteArray = bookmarkCursor.getBlob(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.FAVORITE_ICON));
// Display the current icon bitmap.
currentIconImageView.setImageBitmap(currentIconBitmap);
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Set the new favorite icon bitmap.
newFavoriteIconImageView.setImageBitmap(favoriteIconBitmap);
// Store the current bookmark name and URL.
- currentName = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
- currentUrl = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_URL));
+ String currentName = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
+ String currentUrl = bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_URL));
// Populate the edit texts.
nameEditText.setText(currentName);
// Update the edit button if the icon selection changes.
iconRadioGroup.setOnCheckedChangeListener((RadioGroup group, int checkedId) -> {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, currentName, currentUrl);
});
// Update the edit button if the bookmark name changes.
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, currentName, currentUrl);
}
});
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, currentName, currentUrl);
}
});
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the `DialogFragment` to the parent activity.
- editBookmarkListener.onSaveBookmark(EditBookmarkDialog.this, selectedBookmarkDatabaseId);
+ editBookmarkListener.onSaveBookmark(this, selectedBookmarkDatabaseId, favoriteIconBitmap);
// Manually dismiss `alertDialog`.
alertDialog.dismiss();
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the DialogFragment to the parent activity.
- editBookmarkListener.onSaveBookmark(EditBookmarkDialog.this, selectedBookmarkDatabaseId);
+ editBookmarkListener.onSaveBookmark(this, selectedBookmarkDatabaseId, favoriteIconBitmap);
// Manually dismiss the alert dialog.
alertDialog.dismiss();
return alertDialog;
}
- private void updateEditButton() {
- // Get the text from the `EditTexts`.
+ private void updateEditButton(AlertDialog alertdialog, String currentName, String currentUrl) {
+ // Get handles for the views.
+ EditText nameEditText = alertdialog.findViewById(R.id.edit_bookmark_name_edittext);
+ EditText urlEditText = alertdialog.findViewById(R.id.edit_bookmark_url_edittext);
+ RadioButton newIconRadioButton = alertdialog.findViewById(R.id.edit_bookmark_webpage_favorite_icon_radiobutton);
+ Button editButton = alertdialog.getButton(AlertDialog.BUTTON_POSITIVE);
+
+ // Get the text from the edit texts.
String newName = nameEditText.getText().toString();
String newUrl = urlEditText.getText().toString();
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
+import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
+import java.io.ByteArrayOutputStream;
+
public class EditBookmarkFolderDatabaseViewDialog extends DialogFragment {
- // Instantiate the constants.
+ // Define the home folder database ID constant.
public static final int HOME_FOLDER_DATABASE_ID = -1;
- // Instantiate the class variables.
+ // Define the edit bookmark folder database view listener.
private EditBookmarkFolderDatabaseViewListener editBookmarkFolderDatabaseViewListener;
- private BookmarksDatabaseHelper bookmarksDatabaseHelper;
- private StringBuilder exceptFolders;
- private String currentFolderName;
- private int currentParentFolderDatabaseId;
- private String currentDisplayOrder;
- private RadioButton currentIconRadioButton;
- private EditText nameEditText;
- private Spinner folderSpinner;
- private EditText displayOrderEditText;
- private Button editButton;
+
// The public interface is used to send information back to the parent activity.
public interface EditBookmarkFolderDatabaseViewListener {
- void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId);
+ void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap);
}
public void onAttach(Context context) {
editBookmarkFolderDatabaseViewListener = (EditBookmarkFolderDatabaseViewListener) context;
}
- // Store the database ID in the arguments bundle.
- public static EditBookmarkFolderDatabaseViewDialog folderDatabaseId(int databaseId) {
- // Create a bundle.
- Bundle bundle = new Bundle();
- // Store the bookmark database ID in the bundle.
- bundle.putInt("Database ID", databaseId);
+ public static EditBookmarkFolderDatabaseViewDialog folderDatabaseId(int databaseId, Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
+ // Create an arguments bundle.
+ Bundle argumentsBundle = new Bundle();
+
+ // Store the variables in the bundle.
+ argumentsBundle.putInt("database_id", databaseId);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
- // Add the bundle to the dialog.
+ // Create a new instance of the dialog.
EditBookmarkFolderDatabaseViewDialog editBookmarkFolderDatabaseViewDialog = new EditBookmarkFolderDatabaseViewDialog();
- editBookmarkFolderDatabaseViewDialog.setArguments(bundle);
+
+ // Add the arguments bundle to the dialog.
+ editBookmarkFolderDatabaseViewDialog.setArguments(argumentsBundle);
// Return the new dialog.
return editBookmarkFolderDatabaseViewDialog;
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
- // Remove the incorrect lint warning that `getInt()` might be null.
- assert getArguments() != null;
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
+ // Remove the incorrect lint warning below that the arguments might be null.
+ assert arguments != null;
// Get the bookmark database ID from the bundle.
- int folderDatabaseId = getArguments().getInt("Database ID");
+ int folderDatabaseId = getArguments().getInt("database_id");
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
- // Initialize the database helper. The two `nulls` do not specify the database name or a `CursorFactory`. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
- bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
+ // Initialize the database helper. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
+ BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
// Get a `Cursor` with the selected bookmark and move it to the first position.
Cursor folderCursor = bookmarksDatabaseHelper.getBookmark(folderDatabaseId);
// Set the listener fo the positive button.
dialogBuilder.setPositiveButton(R.string.save, (DialogInterface dialog, int which) -> {
// Return the `DialogFragment` to the parent activity on save.
- editBookmarkFolderDatabaseViewListener.onSaveBookmarkFolder(EditBookmarkFolderDatabaseViewDialog.this, folderDatabaseId);
+ editBookmarkFolderDatabaseViewListener.onSaveBookmarkFolder(this, folderDatabaseId, favoriteIconBitmap);
});
// Create an alert dialog from the alert dialog builder.
RadioGroup iconRadioGroup = alertDialog.findViewById(R.id.edit_folder_icon_radiogroup);
ImageView currentIconImageView = alertDialog.findViewById(R.id.edit_folder_current_icon_imageview);
ImageView newFavoriteIconImageView = alertDialog.findViewById(R.id.edit_folder_webpage_favorite_icon_imageview);
- currentIconRadioButton = alertDialog.findViewById(R.id.edit_folder_current_icon_radiobutton);
- nameEditText = alertDialog.findViewById(R.id.edit_folder_name_edittext);
- folderSpinner = alertDialog.findViewById(R.id.edit_folder_parent_folder_spinner);
- displayOrderEditText = alertDialog.findViewById(R.id.edit_folder_display_order_edittext);
- editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ EditText nameEditText = alertDialog.findViewById(R.id.edit_folder_name_edittext);
+ Spinner folderSpinner = alertDialog.findViewById(R.id.edit_folder_parent_folder_spinner);
+ EditText displayOrderEditText = alertDialog.findViewById(R.id.edit_folder_display_order_edittext);
+ Button editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
// Store the current folder values.
- currentFolderName = folderCursor.getString(folderCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
- currentDisplayOrder = folderCursor.getString(folderCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER));
+ String currentFolderName = folderCursor.getString(folderCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
+ int currentDisplayOrder = folderCursor.getInt(folderCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER));
String parentFolder = folderCursor.getString(folderCursor.getColumnIndex(BookmarksDatabaseHelper.PARENT_FOLDER));
// Set the database ID.
// Display the current icon bitmap in `edit_bookmark_current_icon`.
currentIconImageView.setImageBitmap(currentIconBitmap);
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Set the new favorite icon bitmap.
newFavoriteIconImageView.setImageBitmap(favoriteIconBitmap);
MatrixCursor matrixCursor = new MatrixCursor(matrixCursorColumnNames);
matrixCursor.addRow(new Object[]{HOME_FOLDER_DATABASE_ID, getString(R.string.home_folder)});
- // Initialize a string builder to track the folders not to display in the spinner and populate it with the current folder.
- exceptFolders = new StringBuilder(DatabaseUtils.sqlEscapeString(currentFolderName));
-
// Add all subfolders of the current folder to the list of folders not to display.
- addSubfoldersToExceptFolders(currentFolderName);
+ String exceptFolders = getStringOfSubfolders(currentFolderName, bookmarksDatabaseHelper);
+
+ Log.i("Folders", "String of Folders Not To Display: " + exceptFolders);
// Get a cursor with the list of all the folders.
- Cursor foldersCursor = bookmarksDatabaseHelper.getFoldersExcept(exceptFolders.toString());
+ Cursor foldersCursor = bookmarksDatabaseHelper.getFoldersExcept(exceptFolders);
// Combine the matrix cursor and the folders cursor.
MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor});
}
// Store the current folder database ID.
- currentParentFolderDatabaseId = (int) folderSpinner.getSelectedItemId();
+ int currentParentFolderDatabaseId = (int) folderSpinner.getSelectedItemId();
// Populate the display order `EditText`.
displayOrderEditText.setText(String.valueOf(folderCursor.getInt(folderCursor.getColumnIndex(BookmarksDatabaseHelper.DISPLAY_ORDER))));
// Update the edit button if the icon selection changes.
iconRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, bookmarksDatabaseHelper, currentFolderName, currentParentFolderDatabaseId, currentDisplayOrder);
});
// Update the edit button if the bookmark name changes.
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, bookmarksDatabaseHelper, currentFolderName, currentParentFolderDatabaseId, currentDisplayOrder);
}
});
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, bookmarksDatabaseHelper, currentFolderName, currentParentFolderDatabaseId, currentDisplayOrder);
}
@Override
@Override
public void afterTextChanged(Editable s) {
// Update the edit button.
- updateEditButton();
+ updateEditButton(alertDialog, bookmarksDatabaseHelper, currentFolderName, currentParentFolderDatabaseId, currentDisplayOrder);
}
});
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the `DialogFragment` to the parent activity.
- editBookmarkFolderDatabaseViewListener.onSaveBookmarkFolder(EditBookmarkFolderDatabaseViewDialog.this, folderDatabaseId);
+ editBookmarkFolderDatabaseViewListener.onSaveBookmarkFolder(this, folderDatabaseId, favoriteIconBitmap);
// Manually dismiss `alertDialog`.
alertDialog.dismiss();
// Save the bookmark if the event is a key-down on the "enter" button.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger the `Listener` and return the `DialogFragment` to the parent activity.
- editBookmarkFolderDatabaseViewListener.onSaveBookmarkFolder(EditBookmarkFolderDatabaseViewDialog.this, folderDatabaseId);
+ editBookmarkFolderDatabaseViewListener.onSaveBookmarkFolder(this, folderDatabaseId, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
return alertDialog;
}
- private void updateEditButton() {
+ private void updateEditButton(AlertDialog alertDialog, BookmarksDatabaseHelper bookmarksDatabaseHelper, String currentFolderName, int currentParentFolderDatabaseId, int currentDisplayOrder) {
+ // Get handles for the views.
+ EditText nameEditText = alertDialog.findViewById(R.id.edit_folder_name_edittext);
+ Spinner folderSpinner = alertDialog.findViewById(R.id.edit_folder_parent_folder_spinner);
+ EditText displayOrderEditText = alertDialog.findViewById(R.id.edit_folder_display_order_edittext);
+ RadioButton currentIconRadioButton = alertDialog.findViewById(R.id.edit_folder_current_icon_radiobutton);
+ Button editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+
// Get the values from the dialog.
String newFolderName = nameEditText.getText().toString();
int newParentFolderDatabaseId = (int) folderSpinner.getSelectedItemId();
boolean parentFolderChanged = newParentFolderDatabaseId != currentParentFolderDatabaseId;
// Has the display order changed?
- boolean displayOrderChanged = !newDisplayOrder.equals(currentDisplayOrder);
+ boolean displayOrderChanged = !newDisplayOrder.equals(String.valueOf(currentDisplayOrder));
// Is the display order empty?
boolean displayOrderNotEmpty = !newDisplayOrder.isEmpty();
editButton.setEnabled((iconChanged || folderRenamed || parentFolderChanged || displayOrderChanged) && folderNameNotEmpty && displayOrderNotEmpty);
}
- private void addSubfoldersToExceptFolders(String folderName) {
- // Get a `Cursor` will all the immediate subfolders.
+ private String getStringOfSubfolders(String folderName, BookmarksDatabaseHelper bookmarksDatabaseHelper) {
+ // Get a cursor will all the immediate subfolders.
Cursor subfoldersCursor = bookmarksDatabaseHelper.getSubfolders(folderName);
+ // Initialize a string builder to track the folders not to display in the spinner and populate it with the current folder.
+ StringBuilder exceptFoldersStringBuilder = new StringBuilder(DatabaseUtils.sqlEscapeString(folderName));
+
for (int i = 0; i < subfoldersCursor.getCount(); i++) {
- // Move `subfolderCursor` to the current item.
+ // Move the subfolder cursor to the current item.
subfoldersCursor.moveToPosition(i);
// Get the name of the subfolder.
String subfolderName = subfoldersCursor.getString(subfoldersCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
- // Add the subfolder to `exceptFolders`.
- exceptFolders.append(",");
- exceptFolders.append(DatabaseUtils.sqlEscapeString(subfolderName));
+ // Add a comma to the end of the existing string.
+ exceptFoldersStringBuilder.append(",");
- // Run the same tasks for any subfolders of the subfolder.
- addSubfoldersToExceptFolders(subfolderName);
+ // Get the folder name and run the task for any subfolders.
+ String subfolderString = getStringOfSubfolders(subfolderName, bookmarksDatabaseHelper);
+
+ // Add the folder name to the string builder.
+ exceptFoldersStringBuilder.append(subfolderString);
}
+
+ // Return the string of folders.
+ return exceptFoldersStringBuilder.toString();
}
}
\ No newline at end of file
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
+import java.io.ByteArrayOutputStream;
+
public class EditBookmarkFolderDialog extends DialogFragment {
// Instantiate the class variable.
private EditBookmarkFolderListener editBookmarkFolderListener;
// The public interface is used to send information back to the parent activity.
public interface EditBookmarkFolderListener {
- void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId);
+ void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap);
}
public void onAttach(Context context) {
}
// Store the database ID in the arguments bundle.
- public static EditBookmarkFolderDialog folderDatabaseId(int databaseId) {
- // Create a bundle
- Bundle bundle = new Bundle();
+ public static EditBookmarkFolderDialog folderDatabaseId(int databaseId, Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
- // Store the folder database ID in the bundle.
- bundle.putInt("Database ID", databaseId);
+ // Create an arguments bundle
+ Bundle argumentsBundle = new Bundle();
- // Add the bundle to the dialog.
+ // Store the variables in the bundle.
+ argumentsBundle.putInt("database_id", databaseId);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
+
+ // Create a new instance of the dialog.
EditBookmarkFolderDialog editBookmarkFolderDialog = new EditBookmarkFolderDialog();
- editBookmarkFolderDialog.setArguments(bundle);
+
+ // Add the arguments bundle to the dialog.
+ editBookmarkFolderDialog.setArguments(argumentsBundle);
// Return the new dialog.
return editBookmarkFolderDialog;
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
- // Remove the incorrect lint warning that `getInt()` might be null.
- assert getArguments() != null;
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
+ // Remove the incorrect lint warning below that the arguments might be null.
+ assert arguments != null;
// Store the folder database ID in the class variable.
- int selectedFolderDatabaseId = getArguments().getInt("Database ID");
+ int selectedFolderDatabaseId = arguments.getInt("database_id");
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
// Initialize the database helper. The two `nulls` do not specify the database name or a `CursorFactory`. The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
- final BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
+ BookmarksDatabaseHelper bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
// Get a cursor with the selected folder and move it to the first position.
Cursor folderCursor = bookmarksDatabaseHelper.getBookmark(selectedFolderDatabaseId);
// Set the listener fo the positive button.
dialogBuilder.setPositiveButton(R.string.save, (DialogInterface dialog, int which) -> {
// Return the `DialogFragment` to the parent activity on save.
- editBookmarkFolderListener.onSaveBookmarkFolder(EditBookmarkFolderDialog.this, selectedFolderDatabaseId);
+ editBookmarkFolderListener.onSaveBookmarkFolder(this, selectedFolderDatabaseId, favoriteIconBitmap);
});
// Create an alert dialog from the alert dialog builder.
- final AlertDialog alertDialog = dialogBuilder.create();
+ AlertDialog alertDialog = dialogBuilder.create();
// Remove the warning below that `getWindow()` might be null.
assert alertDialog.getWindow() != null;
// Get handles for the views in the alert dialog.
RadioGroup iconRadioGroup = alertDialog.findViewById(R.id.edit_folder_icon_radio_group);
- final RadioButton currentIconRadioButton = alertDialog.findViewById(R.id.edit_folder_current_icon_radiobutton);
+ RadioButton currentIconRadioButton = alertDialog.findViewById(R.id.edit_folder_current_icon_radiobutton);
ImageView currentIconImageView = alertDialog.findViewById(R.id.edit_folder_current_icon_imageview);
ImageView webPageFavoriteIconImageView = alertDialog.findViewById(R.id.edit_folder_web_page_favorite_icon_imageview);
- final EditText folderNameEditText = alertDialog.findViewById(R.id.edit_folder_name_edittext);
- final Button editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ EditText folderNameEditText = alertDialog.findViewById(R.id.edit_folder_name_edittext);
+ Button editButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
// Initially disable the edit button.
editButton.setEnabled(false);
// Display the current icon bitmap.
currentIconImageView.setImageBitmap(currentIconBitmap);
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIconBitmap.getHeight() > 256) || (favoriteIconBitmap.getWidth() > 256)) {
- favoriteIconBitmap = Bitmap.createScaledBitmap(favoriteIconBitmap, 256, 256, true);
- }
-
// Set the new favorite icon bitmap.
webPageFavoriteIconImageView.setImageBitmap(favoriteIconBitmap);
// Get the current folder name.
- final String currentFolderName = folderCursor.getString(folderCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
+ String currentFolderName = folderCursor.getString(folderCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
// Display the current folder name in `edit_folder_name_edittext`.
folderNameEditText.setText(currentFolderName);
// If the event is a key-down on the "enter" button, select the PositiveButton `Save`.
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && editButton.isEnabled()) { // The enter key was pressed and the edit button is enabled.
// Trigger `editBookmarkListener` and return the DialogFragment to the parent activity.
- editBookmarkFolderListener.onSaveBookmarkFolder(EditBookmarkFolderDialog.this, selectedFolderDatabaseId);
+ editBookmarkFolderListener.onSaveBookmarkFolder(this, selectedFolderDatabaseId, favoriteIconBitmap);
// Manually dismiss the `AlertDialog`.
alertDialog.dismiss();
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import com.stoutner.privacybrowser.views.WrapVerticalContentViewPager;
import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
+import java.io.ByteArrayOutputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment must be used or an error is produced on API <=22.
import androidx.viewpager.widget.PagerAdapter;
pinnedMismatchListener = (PinnedMismatchListener) context;
}
- public static PinnedMismatchDialog displayDialog(long webViewFragmentId) {
+ public static PinnedMismatchDialog displayDialog(long webViewFragmentId, Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
// Create an arguments bundle.
Bundle argumentsBundle = new Bundle();
- // Store the WebView position in the bundle.
+ // Store the variables in the bundle.
argumentsBundle.putLong("webview_fragment_id", webViewFragmentId);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
// Create a new instance of the pinned mismatch dialog.
PinnedMismatchDialog pinnedMismatchDialog = new PinnedMismatchDialog();
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
// Remove the incorrect lint warning below that `.getArguments().getInt()` might be null.
- assert getArguments() != null;
+ assert arguments != null;
// Get the current position of this WebView fragment.
- int webViewPosition = MainWebViewActivity.webViewPagerAdapter.getPositionForId(getArguments().getLong("webview_fragment_id"));
+ int webViewPosition = MainWebViewActivity.webViewPagerAdapter.getPositionForId(arguments.getLong("webview_fragment_id"));
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
// Get the WebView tab fragment.
WebViewTabFragment webViewTabFragment = MainWebViewActivity.webViewPagerAdapter.getPageFragment(webViewPosition);
dialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowserAlertDialogLight);
}
+ // Get the context.
+ Context context = getContext();
+
+ // Remove the incorrect lint warning below that the context might be null.
+ assert context != null;
+
+ // Get the default favorite icon drawable. `ContextCompat` must be used until API >= 21.
+ Drawable defaultFavoriteIconDrawable = ContextCompat.getDrawable(context, R.drawable.world);
+
+ // Cast the favorite icon drawable to a bitmap drawable.
+ BitmapDrawable defaultFavoriteIconBitmapDrawable = (BitmapDrawable) defaultFavoriteIconDrawable;
+
+ // Remove the incorrect warning below that the favorite icon bitmap drawable might be null.
+ assert defaultFavoriteIconBitmapDrawable != null;
+
+ // Store the default icon bitmap.
+ Bitmap defaultFavoriteIconBitmap = defaultFavoriteIconBitmapDrawable.getBitmap();
+
// Set the favorite icon as the dialog icon if it exists.
- if (MainWebViewActivity.favoriteIconBitmap.equals(MainWebViewActivity.favoriteIconDefaultBitmap)) { // There is no favorite icon.
+ if (favoriteIconBitmap.sameAs(defaultFavoriteIconBitmap)) { // There is no website favorite icon.
// Set the icon according to the theme.
if (MainWebViewActivity.darkTheme) {
dialogBuilder.setIcon(R.drawable.ssl_certificate_enabled_dark);
}
} else { // There is a favorite icon.
// Create a drawable version of the favorite icon.
- Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), MainWebViewActivity.favoriteIconBitmap);
+ Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), favoriteIconBitmap);
// Set the icon.
dialogBuilder.setIcon(favoriteIconDrawable);
Bundle bundle = new Bundle();
// Store the request details.
- bundle.putInt("ID", id);
- bundle.putBoolean("Is Last Request", isLastRequest);
- bundle.putStringArray("Request Details", requestDetails);
+ bundle.putInt("id", id);
+ bundle.putBoolean("is_last_request", isLastRequest);
+ bundle.putStringArray("request_details", requestDetails);
// Add the bundle to the dialog.
ViewRequestDialog viewRequestDialog = new ViewRequestDialog();
assert getArguments() != null;
// Get the info from the bundle.
- int id = getArguments().getInt("ID");
- boolean isLastRequest = getArguments().getBoolean("Is Last Request");
- String[] requestDetails = getArguments().getStringArray("Request Details");
+ int id = getArguments().getInt("id");
+ boolean isLastRequest = getArguments().getBoolean("is_last_request");
+ String[] requestDetails = getArguments().getStringArray("request_details");
// Use an alert dialog builder to create the alert dialog.
AlertDialog.Builder dialogBuilder;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import com.stoutner.privacybrowser.fragments.WebViewTabFragment;
import com.stoutner.privacybrowser.views.NestedScrollWebView;
+import java.io.ByteArrayOutputStream;
import java.text.DateFormat;
import java.util.Calendar;
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 ViewSslCertificateDialog extends DialogFragment {
- public static ViewSslCertificateDialog displayDialog(long webViewFragmentId) {
+ public static ViewSslCertificateDialog displayDialog(long webViewFragmentId, Bitmap favoriteIconBitmap) {
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon to a PNG and place it in the byte array output stream. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the byte array output stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
// Create an arguments bundle.
Bundle argumentsBundle = new Bundle();
- // Store the WebView fragment ID in the bundle.
+ // Store the variables in the bundle.
argumentsBundle.putLong("webview_fragment_id", webViewFragmentId);
+ argumentsBundle.putByteArray("favorite_icon_byte_array", favoriteIconByteArray);
// Create a new instance of the dialog.
ViewSslCertificateDialog viewSslCertificateDialog = new ViewSslCertificateDialog();
// Get the activity's layout inflater.
LayoutInflater layoutInflater = getActivity().getLayoutInflater();
+ // Get the arguments.
+ Bundle arguments = getArguments();
+
// Remove the incorrect lint warning below that `getArguments().getLong()` might be null.
- assert getArguments() != null;
+ assert arguments != null;
+
+ // Get the favorite icon byte array.
+ byte[] favoriteIconByteArray = arguments.getByteArray("favorite_icon_byte_array");
+
+ // Remove the incorrect lint warning below that the favorite icon byte array might be null.
+ assert favoriteIconByteArray != null;
+
+ // Convert the favorite icon byte array to a bitmap.
+ Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length);
// Get the current position of this WebView fragment.
- int webViewPosition = MainWebViewActivity.webViewPagerAdapter.getPositionForId(getArguments().getLong("webview_fragment_id"));
+ int webViewPosition = MainWebViewActivity.webViewPagerAdapter.getPositionForId(arguments.getLong("webview_fragment_id"));
// Get the WebView tab fragment.
WebViewTabFragment webViewTabFragment = MainWebViewActivity.webViewPagerAdapter.getPageFragment(webViewPosition);
}
// Create a drawable version of the favorite icon.
- Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), MainWebViewActivity.favoriteIconBitmap);
+ Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), favoriteIconBitmap);
// Set the icon.
dialogBuilder.setIcon(favoriteIconDrawable);
!currentWebsiteSslEndDateString.equals(pinnedSslEndDateString)))) {
// Get a handle for the pinned mismatch alert dialog.
- DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(nestedScrollWebView.getWebViewFragmentId());
+ DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(nestedScrollWebView.getWebViewFragmentId(), nestedScrollWebView.getFavoriteOrDefaultIcon());
// Show the pinned mismatch alert dialog.
pinnedMismatchDialogFragment.show(fragmentManager, "Pinned Mismatch");
package com.stoutner.privacybrowser.views;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;
+import com.stoutner.privacybrowser.R;
+
import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
import androidx.core.view.NestedScrollingChild2;
import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat;
// The ignore pinned domain information tracker. This is set when a user proceeds past a pinned mismatch dialog to prevent the dialog from showing again until after the domain changes.
private boolean ignorePinnedDomainInformation;
+ // The default or favorite icon.
+ Bitmap favoriteOrDefaultIcon;
+
// The nested scrolling child helper is used throughout the class.
private NestedScrollingChildHelper nestedScrollingChildHelper;
}
+ // Favorite or default icon.
+ public void initializeFavoriteIcon() {
+ // Get the default favorite icon drawable. `ContextCompat` must be used until API >= 21.
+ Drawable favoriteIconDrawable = ContextCompat.getDrawable(getContext(), R.drawable.world);
+
+ // Cast the favorite icon drawable to a bitmap drawable.
+ BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable;
+
+ // Remove the incorrect warning below that the favorite icon bitmap drawable might be null.
+ assert favoriteIconBitmapDrawable != null;
+
+ // Store the default icon bitmap.
+ favoriteOrDefaultIcon = favoriteIconBitmapDrawable.getBitmap();
+ }
+
+ public void setFavoriteOrDefaultIcon(Bitmap icon) {
+ // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
+ if ((icon.getHeight() > 256) || (icon.getWidth() > 256)) {
+ favoriteOrDefaultIcon = Bitmap.createScaledBitmap(icon, 256, 256, true);
+ } else {
+ // Store the icon as presented.
+ favoriteOrDefaultIcon = icon;
+ }
+ }
+
+ public Bitmap getFavoriteOrDefaultIcon() {
+ // Return the favorite or default icon.
+ return favoriteOrDefaultIcon;
+ }
+
+
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {