import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.DialogFragment;
-import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentPagerAdapter;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager.widget.ViewPager;
import com.stoutner.privacybrowser.BuildConfig;
import com.stoutner.privacybrowser.R;
+import com.stoutner.privacybrowser.adapters.WebViewPagerAdapter;
import com.stoutner.privacybrowser.asynctasks.GetHostIpAddresses;
import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
// This is needed to get rid of the Android Studio warning that the action bar might be null.
assert actionBar != null;
- // Add the custom `url_app_bar` layout, which shows the favorite icon and the URL text bar.
+ // Add the custom layout, which shows the URL text bar.
actionBar.setCustomView(R.layout.url_app_bar);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
@Override
public void onPageSelected(int position) {
// Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.webViewFragmentsList.get(position);
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(position);
// Get the fragment view.
View fragmentView = webViewTabFragment.getView();
}
});
- // Add the first tab.
- webViewPagerAdapter.addPage();
+ // Add the first tab. (It doesn't matter what view is passed. That is just required as part of the ImageView `onClick()` syntax).
+ addTab(webViewPager);
// Set the bookmarks drawer resources according to the theme. This can't be done in the layout due to compatibility issues with the `DrawerLayout` support widget.
if (darkTheme) {
// Reload the webpage if displaying of images has been disabled in the Settings activity.
if (reloadOnRestart) {
// Reload the WebViews.
- for (int i = 0; i < webViewPagerAdapter.webViewFragmentsList.size(); i++) {
+ for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
// Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.webViewFragmentsList.get(i);
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
// Get the fragment view.
View fragmentView = webViewTabFragment.getView();
// Run the default commands.
super.onResume();
- for (int i = 0; i < webViewPagerAdapter.webViewFragmentsList.size(); i++) {
+ for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
// Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.webViewFragmentsList.get(i);
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
// Get the fragment view.
View fragmentView = webViewTabFragment.getView();
// Get the nested scroll WebView from the tab fragment.
NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
- // Pause the nested scroll WebView JavaScript timers.
+ // Resume the nested scroll WebView JavaScript timers.
nestedScrollWebView.resumeTimers();
- // Pause the nested scroll WebView.
+ // Resume the nested scroll WebView.
nestedScrollWebView.onResume();
}
}
// Run the default commands.
super.onPause();
- for (int i = 0; i < webViewPagerAdapter.webViewFragmentsList.size(); i++) {
+ for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
// Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.webViewFragmentsList.get(i);
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
// Get the fragment view.
View fragmentView = webViewTabFragment.getView();
MenuItem nightModeMenuItem = menu.findItem(R.id.night_mode);
MenuItem proxyThroughOrbotMenuItem = menu.findItem(R.id.proxy_through_orbot);
- // Set the text for the domain menu item.
- if (currentWebView.getDomainSettingsApplied()) {
- addOrEditDomain.setTitle(R.string.edit_domain_settings);
- } else {
- addOrEditDomain.setTitle(R.string.add_domain_settings);
+ // Initialize the current user agent string and the font size.
+ String currentUserAgent = getString(R.string.user_agent_privacy_browser);
+ int fontSize = 100;
+
+ // Set items that require the current web view to be populated. It will be null when the program is first opened, as `onPrepareOptionsMenu()` is called before the first WebView is initialized.
+ if (currentWebView != null) {
+ // Set the add or edit domain text.
+ if (currentWebView.getDomainSettingsApplied()) {
+ addOrEditDomain.setTitle(R.string.edit_domain_settings);
+ } else {
+ addOrEditDomain.setTitle(R.string.add_domain_settings);
+ }
+
+ // Get the current user agent from the WebView.
+ currentUserAgent = currentWebView.getSettings().getUserAgentString();
+
+ // Get the current font size from the
+ fontSize = currentWebView.getSettings().getTextZoom();
+
+ // Set the status of the display images menu item.
+ displayImagesMenuItem.setChecked(currentWebView.getSettings().getLoadsImagesAutomatically());
}
// Set the status of the menu item checkboxes.
ultraPrivacyMenuItem.setChecked(ultraPrivacyEnabled);
blockAllThirdPartyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
- displayImagesMenuItem.setChecked(currentWebView.getSettings().getLoadsImagesAutomatically());
nightModeMenuItem.setChecked(nightMode);
proxyThroughOrbotMenuItem.setChecked(proxyThroughOrbot);
ultraPrivacyMenuItem.setTitle(ultraPrivacyBlockedRequests + " - " + getString(R.string.ultraprivacy));
blockAllThirdPartyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests));
- // Get the current user agent.
- String currentUserAgent = currentWebView.getSettings().getUserAgentString();
-
// Select the current user agent menu item. A switch statement cannot be used because the user agents are not compile time constants.
if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[0])) { // Privacy Browser.
menu.findItem(R.id.user_agent_privacy_browser).setChecked(true);
menu.findItem(R.id.user_agent_custom).setChecked(true);
}
- // Initialize font size variables.
- int fontSize = currentWebView.getSettings().getTextZoom();
+ // Instantiate the font size title and the selected font size menu item.
String fontSizeTitle;
MenuItem selectedFontSizeMenuItem;
// Get the current tab number.
int currentTabNumber = tabLayout.getSelectedTabPosition();
- // Delete the tab and page.
+ // Delete the current tab.
+ tabLayout.removeTabAt(currentTabNumber);
+
+ // Delete the current page.
webViewPagerAdapter.deletePage(currentTabNumber);
break;
// TODO this also needs to be set when creating a new tab.
// Set the app bar scrolling for each WebView.
- for (int i = 0; i < webViewPagerAdapter.webViewFragmentsList.size(); i++) {
+ for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
// Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.webViewFragmentsList.get(i);
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
// Get the fragment view.
View fragmentView = webViewTabFragment.getView();
// Reload the WebViews if requested.
if (reloadWebsite) {
// Reload the WebViews.
- for (int i = 0; i < webViewPagerAdapter.webViewFragmentsList.size(); i++) {
+ for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
// Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.webViewFragmentsList.get(i);
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
// Get the fragment view.
View fragmentView = webViewTabFragment.getView();
}
}
- private class WebViewPagerAdapter extends FragmentPagerAdapter {
- // The WebView fragments list contains all the WebViews.
- private LinkedList<WebViewTabFragment> webViewFragmentsList = new LinkedList<>();
-
- // Define the constructor.
- private WebViewPagerAdapter(FragmentManager fragmentManager){
- // Run the default commands.
- super(fragmentManager);
- }
-
- @Override
- public int getCount() {
- // Return the number of pages.
- return webViewFragmentsList.size();
- }
-
- @Override
- public int getItemPosition(@NonNull Object object) {
- //noinspection SuspiciousMethodCalls
- if (webViewFragmentsList.contains(object)) {
- // The tab has not been deleted.
- return POSITION_UNCHANGED;
- } else {
- // The tab has been deleted.
- return POSITION_NONE;
- }
- }
-
- @Override
- public Fragment getItem(int pageNumber) {
- // Get a WebView for a particular page. Page numbers are 0 indexed.
- return webViewFragmentsList.get(pageNumber);
- }
-
- private void addPage() {
- // Add a new page. The pages and tabs are 0 indexed, so the size of the current list equals the number of the next page.
- webViewFragmentsList.add(WebViewTabFragment.createTab(webViewFragmentsList.size()));
-
- // Update the view pager.
- notifyDataSetChanged();
- }
-
- private void deletePage(int pageNumber) {
- // Get a handle for the tab layout.
- TabLayout tabLayout = findViewById(R.id.tablayout);
-
- // TODO always move to the next tab if possible.
- // Select a tab that is not being deleted.
- if (pageNumber == 0) { // The first tab is being deleted.
- // Get a handle for the second tab. The tabs are 0 indexed.
- TabLayout.Tab secondTab = tabLayout.getTabAt(1);
-
- // Remove the incorrect lint warning below that the second tab might be null.
- assert secondTab != null;
-
- // Select the second tab.
- secondTab.select();
- } else { // The first tab is not being deleted.
- // Get a handle for the previous tab.
- TabLayout.Tab previousTab = tabLayout.getTabAt(pageNumber - 1);
+ public void addTab(View view) {
+ // Get a handle for the tab layout.
+ TabLayout tabLayout = findViewById(R.id.tablayout);
- // Remove the incorrect lint warning below tha the previous tab might be null.
- assert previousTab != null;
+ // Get the new page number. The page numbers are 0 indexed, so the new page number will match the current count.
+ int newTabNumber = tabLayout.getTabCount();
- // Select the previous tab.
- previousTab.select();
- }
+ // Add a new tab.
+ tabLayout.addTab(tabLayout.newTab());
- // Delete the page.
- webViewFragmentsList.remove(pageNumber);
+ // Get the new tab.
+ TabLayout.Tab newTab = tabLayout.getTabAt(newTabNumber);
- // Delete the tab.
- tabLayout.removeTabAt(pageNumber);
+ // Remove the lint warning below that the current tab might be null.
+ assert newTab != null;
- // Update the view pager.
- notifyDataSetChanged();
- }
- }
+ // Set a custom view on the current tab.
+ newTab.setCustomView(R.layout.custom_tab_view);
- public void addTab(View view) {
// Add the new WebView page.
- webViewPagerAdapter.addPage();
-
- // Get a handle for the tab layout.
- TabLayout tabLayout = findViewById(R.id.tablayout);
-
- // Get a handle for the new tab. The tabs are 0 indexed.
- TabLayout.Tab newTab = tabLayout.getTabAt(tabLayout.getTabCount() - 1);
+ webViewPagerAdapter.addPage(newTabNumber);
- // Remove the incorrect warning below that the new tab might be null.
- assert newTab != null;
-
- // Move the tab layout to the new tab.
- newTab.select();
+ if (newTabNumber > 0) {
+ // Move to the new tab.
+ newTab.select();
+ }
}
@Override
- public void initializeWebView(int tabNumber, ProgressBar progressBar, NestedScrollWebView nestedScrollWebView) {
+ public void initializeWebView(long pageId, int pageNumber, ProgressBar progressBar, NestedScrollWebView nestedScrollWebView) {
// Get handles for the activity views.
- final FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
- final DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
- final RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
- final ActionBar actionBar = getSupportActionBar();
+ FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
+ DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+ RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
+ ActionBar actionBar = getSupportActionBar();
EditText urlEditText = findViewById(R.id.url_edittext);
- final TabLayout tabLayout = findViewById(R.id.tablayout);
- final SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
+ TabLayout tabLayout = findViewById(R.id.tablayout);
+ SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
// Remove the incorrect lint warnings below that the some of the views might be null.
assert actionBar != null;
- // TODO. Still doesn't work right.
- // Create the tab if it doesn't already exist.
- try {
- TabLayout.Tab tab = tabLayout.getTabAt(tabNumber);
-
- assert tab != null;
-
- tab.getCustomView();
- } catch (Exception exception) {
- tabLayout.addTab(tabLayout.newTab());
- }
-
- // Get the current tab.
- TabLayout.Tab currentTab = tabLayout.getTabAt(tabNumber);
-
- // Remove the lint warning below that the current tab might be null.
- assert currentTab != null;
-
- // Set a custom view on the current tab.
- currentTab.setCustomView(R.layout.custom_tab_view);
-
- // Get the custom view from the tab.
- View currentTabView = currentTab.getCustomView();
-
- // Remove the incorrect warning below that the current tab view might be null.
- assert currentTabView != null;
-
- // Get the current views from the tab.
- ImageView tabFavoriteIconImageView = currentTabView.findViewById(R.id.favorite_icon_imageview);
- TextView tabTitleTextView = currentTabView.findViewById(R.id.title_textview);
-
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Only update the favorite icon if the website has finished loading.
if (progressBar.getVisibility() == View.GONE) {
// Save a copy of the favorite icon.
- // TODO. We need to save and access the icons for each tab.
favoriteIconBitmap = icon;
+ // Get the current page position.
+ int currentPosition = webViewPagerAdapter.getPositionForId(pageId);
+
+ // 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();
+
+ // Remove the incorrect warning below that the current tab view might be null.
+ assert tabView != null;
+
+ // Get the favorite icon image view from the tab.
+ ImageView tabFavoriteIconImageView = tabView.findViewById(R.id.favorite_icon_imageview);
+
+ // Display the favorite icon in the tab.
tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
}
}
// Save a copy of the title when it changes.
@Override
public void onReceivedTitle(WebView view, String title) {
+ // Get the current page position.
+ int currentPosition = webViewPagerAdapter.getPositionForId(pageId);
+
+ // 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();
+
+ // 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);
+
// Set the title as the tab text.
tabTitleTextView.setText(title);
}
}
});
- // Check to see if this is the first tab.
- if (tabNumber == 0) {
+ // Check to see if this is the first page.
+ if (pageNumber == 0) {
// Set this nested scroll WebView as the current WebView.
currentWebView = nestedScrollWebView;
--- /dev/null
+/*
+ * Copyright © 2019 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.adapters;
+
+import com.stoutner.privacybrowser.fragments.WebViewTabFragment;
+
+import java.util.LinkedList;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+
+public class WebViewPagerAdapter extends FragmentPagerAdapter {
+ // The WebView fragments list contains all the WebViews.
+ private LinkedList<WebViewTabFragment> webViewFragmentsList = new LinkedList<>();
+
+ // Define the constructor.
+ public WebViewPagerAdapter(FragmentManager fragmentManager){
+ // Run the default commands.
+ super(fragmentManager);
+ }
+
+ @Override
+ public int getCount() {
+ // Return the number of pages.
+ return webViewFragmentsList.size();
+ }
+
+ @Override
+ public int getItemPosition(@NonNull Object object) {
+ //noinspection SuspiciousMethodCalls
+ if (webViewFragmentsList.contains(object)) {
+ // Return the current page position.
+ //noinspection SuspiciousMethodCalls
+ return webViewFragmentsList.indexOf(object);
+ } else {
+ // The tab has been deleted.
+ return POSITION_NONE;
+ }
+ }
+
+ @Override
+ public Fragment getItem(int pageNumber) {
+ // Get the fragment for a particular page. Page numbers are 0 indexed.
+ return webViewFragmentsList.get(pageNumber);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ // Return the unique ID for this page.
+ return webViewFragmentsList.get(position).tabId;
+ }
+
+ public int getPositionForId(long pageId) {
+ // Initialize the position variable.
+ int position = -1;
+
+ // Initialize the while counter.
+ int i = 0;
+
+ // Find the current position of the WebView fragment with the given ID.
+ while (position < 0 && i < webViewFragmentsList.size()) {
+ // Check to see if the tab ID of this WebView matches the page ID.
+ if (webViewFragmentsList.get(i).tabId == pageId) {
+ // Store the position if they are a match.
+ position = i;
+ }
+
+ // Increment the counter.
+ i++;
+ }
+
+ // Return the position.
+ return position;
+ }
+
+ public void addPage(int pageNumber) {
+ // Add a new page.
+ webViewFragmentsList.add(WebViewTabFragment.createPage(pageNumber));
+
+ // Update the view pager.
+ notifyDataSetChanged();
+ }
+
+ public void deletePage(int pageNumber) {
+ // Delete the page.
+ webViewFragmentsList.remove(pageNumber);
+
+ // Update the view pager.
+ notifyDataSetChanged();
+ }
+
+ public WebViewTabFragment getPageFragment(int pageNumber) {
+ return webViewFragmentsList.get(pageNumber);
+ }
+}
\ No newline at end of file