From 30b6db5cdccb01d98f19b3a6af91d9f8ae1322bf Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Wed, 17 May 2017 01:03:18 -0700 Subject: [PATCH 01/16] Don't add URL redirects to the history list. Implements https://redmine.stoutner.com/issues/127. --- .../activities/MainWebViewActivity.java | 12 +- .../fragments/SettingsFragment.java | 109 +++++++++++++++++- app/src/main/res/drawable/font_size.xml | 2 +- app/src/main/res/drawable/user_agent.xml | 2 +- app/src/main/res/layout/domain_settings.xml | 2 - app/src/main/res/xml/preferences.xml | 6 +- 6 files changed, 121 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 3c832ae3..a7dfad7e 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -568,8 +568,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation @SuppressWarnings("deprecation") @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - // Use an external email program if the link begins with `mailto:`. - if (url.startsWith("mailto:")) { + if (url.startsWith("mailto:")) { // Load the URL in an external email program because it begins with `mailto:`. // We use `ACTION_SENDTO` instead of `ACTION_SEND` so that only email programs are launched. Intent emailIntent = new Intent(Intent.ACTION_SENDTO); @@ -581,10 +580,15 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Make it so. startActivity(emailIntent); + + // Returning `true` indicates the application is handling the URL. return true; } else { // Load the URL in Privacy Browser. - loadUrl(url); - return true; + // Apply the domain settings for the new URL. + applyDomainSettings(url); + + // Returning `false` causes the current `WebView` to handle the URL and prevents it from adding redirects to the history list. + return false; } } diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index b783703e..75e008ad 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -44,8 +44,10 @@ public class SettingsFragment extends PreferenceFragment { savedPreferences = getPreferenceScreen().getSharedPreferences(); // Get handles for the preferences we need to modify. - final Preference domStorageEnabled = findPreference("dom_storage_enabled"); + final Preference javaScriptEnabled = findPreference("javascript_enabled"); + final Preference firstPartyCookiesEnabled = findPreference("first_party_cookies_enabled"); final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled"); + final Preference domStorageEnabled = findPreference("dom_storage_enabled"); final Preference userAgentPreference = findPreference("user_agent"); final Preference customUserAgent = findPreference("custom_user_agent"); final Preference torHomepagePreference = findPreference("tor_homepage"); @@ -68,8 +70,13 @@ public class SettingsFragment extends PreferenceFragment { String torSearchString = savedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); String searchString = savedPreferences.getString("search", "https://duckduckgo.com/html/?q="); + // Get booleans from the preferences. + boolean javaScriptEnabledBoolean = savedPreferences.getBoolean("javascript_enabled", false); + boolean firstPartyCookiesEnabledBoolean = savedPreferences.getBoolean("first_party_cookies_enabled", false); + boolean thirdPartyCookiesEnabledBoolean = savedPreferences.getBoolean("third_party_cookies_enabled", false); + // Only enable `third_party_cookies_enabled` if `first_party_cookies_enabled` is `true` and API >= 21. - thirdPartyCookiesEnabled.setEnabled(savedPreferences.getBoolean("first_party_cookies_enabled", false) && (Build.VERSION.SDK_INT >= 21)); + thirdPartyCookiesEnabled.setEnabled(firstPartyCookiesEnabledBoolean && (Build.VERSION.SDK_INT >= 21)); // We need to inflated a `WebView` to get the default user agent. LayoutInflater inflater = getActivity().getLayoutInflater(); @@ -145,6 +152,42 @@ public class SettingsFragment extends PreferenceFragment { defaultFontSizePreference.setSummary(savedPreferences.getString("default_font_size", "100") + "%%"); + // Set the `javascript_enabled` icon. + if (javaScriptEnabledBoolean) { + javaScriptEnabled.setIcon(R.drawable.javascript_enabled); + } else { + javaScriptEnabled.setIcon(R.drawable.privacy_mode); + } + + // Set the `first_party_cookies_enabled` icon. + if (firstPartyCookiesEnabledBoolean) { + firstPartyCookiesEnabled.setIcon(R.drawable.cookies_enabled); + } else { + firstPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + } + + // Set the `third_party_cookies_enabled` icon. + if (firstPartyCookiesEnabledBoolean && Build.VERSION.SDK_INT >= 21) { + if (thirdPartyCookiesEnabledBoolean) { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_warning); + } else { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + } + } else { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_ghosted); + } + + // Set the `dom_storage_enabled` icon. + if (javaScriptEnabledBoolean) { + if (savedPreferences.getBoolean("dom_storage_enabled", false)) { + domStorageEnabled.setIcon(R.drawable.dom_storage_enabled); + } else { + domStorageEnabled.setIcon(R.drawable.dom_storage_disabled); + } + } else { + domStorageEnabled.setIcon(R.drawable.dom_storage_ghosted); + } + // Listen for preference changes. preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override @@ -153,11 +196,73 @@ public class SettingsFragment extends PreferenceFragment { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { switch (key) { + case "javascript_enabled": + // Update the icons. + if (sharedPreferences.getBoolean("javascript_enabled", false)) { + // Update the icon for `javascript_enabled`. + javaScriptEnabled.setIcon(R.drawable.javascript_enabled); + + // Update the icon for `dom_storage_enabled`. + if (sharedPreferences.getBoolean("dom_storage_enabled", false)) { + domStorageEnabled.setIcon(R.drawable.dom_storage_enabled); + } else { + domStorageEnabled.setIcon(R.drawable.dom_storage_disabled); + } + } else { // `javascript_enabled` is `false`. + // Update the icon for `javascript_enabled`. + javaScriptEnabled.setIcon(R.drawable.privacy_mode); + + // Set the icon for `dom_storage_disabled` to be ghosted. + domStorageEnabled.setIcon(R.drawable.dom_storage_ghosted); + } + break; + case "first_party_cookies_enabled": + // Update the icons for `first_party_cookies_enabled` and `third_party_cookies_enabled`. + if (sharedPreferences.getBoolean("first_party_cookies_enabled", false)) { + // Set the icon for `first_party_cookies_enabled`. + firstPartyCookiesEnabled.setIcon(R.drawable.cookies_enabled); + + // Update the icon for `third_party_cookies_enabled`. + if (Build.VERSION.SDK_INT >= 21) { + if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_warning); + } else { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + } + } else { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_ghosted); + } + } else { // `first_party_cookies_enabled` is `false`. + // Update the icon for `first_party_cookies_enabled`. + firstPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + + // Set the icon for `third_party_cookies_enabled` to be ghosted. + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_ghosted); + } + // Enable `third_party_cookies_enabled` if `first_party_cookies_enabled` is `true` and API >= 21. thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false) && (Build.VERSION.SDK_INT >= 21)); break; + case "third_party_cookies_enabled": + // Update the icon. + if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_warning); + } else { + thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + } + break; + + case "dom_storage_enabled": + // Update the icon. + if (sharedPreferences.getBoolean("dom_storage_enabled", false)) { + domStorageEnabled.setIcon(R.drawable.dom_storage_enabled); + } else { + domStorageEnabled.setIcon(R.drawable.dom_storage_disabled); + } + break; + case "user_agent": String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"); diff --git a/app/src/main/res/drawable/font_size.xml b/app/src/main/res/drawable/font_size.xml index 906a0dbc..5b6bf635 100644 --- a/app/src/main/res/drawable/font_size.xml +++ b/app/src/main/res/drawable/font_size.xml @@ -13,6 +13,6 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/user_agent.xml b/app/src/main/res/drawable/user_agent.xml index 08b897e8..a346c597 100644 --- a/app/src/main/res/drawable/user_agent.xml +++ b/app/src/main/res/drawable/user_agent.xml @@ -13,6 +13,6 @@ diff --git a/app/src/main/res/layout/domain_settings.xml b/app/src/main/res/layout/domain_settings.xml index 37c8490d..00479b52 100644 --- a/app/src/main/res/layout/domain_settings.xml +++ b/app/src/main/res/layout/domain_settings.xml @@ -237,7 +237,6 @@ android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" android:src="@drawable/user_agent" - android:tint="@color/blue_800" android:contentDescription="@string/user_agent" /> + android:defaultValue="PrivacyBrowser/1.0" + android:icon="@drawable/user_agent" /> + android:defaultValue="100" + android:icon="@drawable/font_size" /> Date: Thu, 18 May 2017 11:30:44 -0700 Subject: [PATCH 02/16] Add the title when sharing a URL. Implements https://redmine.stoutner.com/issues/130. --- app/src/main/assets/de/about_licenses.html | 1 + app/src/main/assets/en/about_licenses.html | 1 + .../main/assets/en/images/ic_location_off.png | Bin 0 -> 1880 bytes app/src/main/assets/es/about_licenses.html | 1 + app/src/main/assets/it/about_licenses.html | 1 + .../main/assets/zh-rTW/about_licenses.html | 1 + .../activities/MainWebViewActivity.java | 13 +- .../fragments/SettingsFragment.java | 146 ++++++++++++------ .../res/drawable/do_not_track_disabled.xml | 17 ++ .../res/drawable/do_not_track_enabled.xml | 17 ++ ...{user_agent.xml => user_agent_enabled.xml} | 2 +- .../main/res/drawable/user_agent_ghosted.xml | 18 +++ app/src/main/res/layout/domain_settings.xml | 2 +- app/src/main/res/xml/preferences.xml | 2 +- 14 files changed, 170 insertions(+), 52 deletions(-) create mode 100644 app/src/main/assets/en/images/ic_location_off.png create mode 100644 app/src/main/res/drawable/do_not_track_disabled.xml create mode 100644 app/src/main/res/drawable/do_not_track_enabled.xml rename app/src/main/res/drawable/{user_agent.xml => user_agent_enabled.xml} (86%) create mode 100644 app/src/main/res/drawable/user_agent_ghosted.xml diff --git a/app/src/main/assets/de/about_licenses.html b/app/src/main/assets/de/about_licenses.html index 3e4da269..a9b150c8 100644 --- a/app/src/main/assets/de/about_licenses.html +++ b/app/src/main/assets/de/about_licenses.html @@ -81,6 +81,7 @@

ic_info_outline.

ic_language.

ic_list.

+

ic_location_off.

ic_more.

ic_question_answer.

ic_select_all.

diff --git a/app/src/main/assets/en/about_licenses.html b/app/src/main/assets/en/about_licenses.html index 6be0e356..f655a94c 100644 --- a/app/src/main/assets/en/about_licenses.html +++ b/app/src/main/assets/en/about_licenses.html @@ -79,6 +79,7 @@

ic_info_outline.

ic_language.

ic_list.

+

ic_location_off.

ic_more.

ic_question_answer.

ic_select_all.

diff --git a/app/src/main/assets/en/images/ic_location_off.png b/app/src/main/assets/en/images/ic_location_off.png new file mode 100644 index 0000000000000000000000000000000000000000..181aba4a77d6a8a88932287376fac57c040506ac GIT binary patch literal 1880 zcmV-e2dDUnP)HKD-~nJ4FhIDV*RwByhk*9@%`<8-23Ubh*AhXmW=C)tXJXu@ z8pEjo%YmQK3;aks20Q|cirDUC=>&EH(*)|e0@#6mz-!qa;QDB-PmnI)Fs||615+c_ zQvp^3edq_dk@e$-g|-+SkrJK2FPz`_eT2^h6MzrU31%LX%8Dus|K^XhkeOfsaIi)_ zMX(-VQJ}s^hHBsZkrpBoEC!A?sHX^a61X*IUnE1lZ+^&3umtFBvYsMXA8?mvUnIkH znh$Z%o+4Nuu+*b3lA!`@BzwbshlBMVb){~-z||gokqi}J6WJT?n+Y~})RnsR z08>2rA{i_b=*M;|1I z4F~>qlyiF%3yoz0e|yrS{YhdX@UtFDw7skXY$kgrwEA#Rin+iUQWwDy+;;D6z;@tU z+_rB`0es=n?xaag1U~?4aOVSRu@JXFbHKyzyfy&L^=Nm}q#%M*z|**0#LY4qcnp^* zBt@{^qs_^qDS~d`vK+oo!JPq+62P7uz9x-^2tFswe*JO4`%U_r*G>bM1n@aYD!{wQ zi6BeLZ^Ss{GQr&e{ceclI`klJgJ)K{fKSOTf`2^fszo0zFcJquZxpCQjji~9Gh%Ex z&&o>TXMm5zTBE=|@^wzk!zax!hWOjme-vwtFztjnvaKzGbya){X{Uh;r5Yp2EW&k? zrU(`_>0=(Nw^$Vv$w}bF0n7587>1x5I3BrzSoMN$Bh0+-i?yA(otVmOF9njRCe z{Q*VI0B4Xqnm(Mvk;|VDx%{(83LsWp8Y1WytSc�{AOp*`2^A$ju32FW2@)F8?f& z0*HP0p5(-^D{}cKBbTqjY~nvYNjxH6E6|475&c(V3~rG_LIg3FjbDuH`@gvT2&F{w zX0I5TU@Y;krQ09a=ekIrO8HK(t{8KIr+^s&%d5tL$mO3$nFRo0MKB9k8=#y z#y!Xl0U?Kj3An&W_F3N1_>VrfXN;{7K;58PXwz4{VP4Mp(lVr z{2vjY5b*6455Ee>Qgj87vIuVW@TqXLk;Vm(sfpkuZk?eecnf_243gHIV2g(zh2;+P zgP&R^xYNUj!qSdQdD_8GB@-MY>_L`7;B!>0teN0-k9rHwLiB^4iU<~a)L9C?LOm}f1@Al zS{7?K=tK96V^X|{exRjAu-T)$(lQ6P8B#mY^(^FY(2w8&(4ydTeN0g^!8;yhl%Dy> zZ5!7Vfqnbyum$}9H)DB*gSS0C*D}n-UGAhE;Fuz4`RD#dXm1&l7!Hg&Oa^{OKe#3W zMb@GpSQCLF?Z8jy2i8QO$o=RCHLGb~VOJ_DxT{~ZgKC*Tk*g@qW1)#45-I;&T+eJc z2t)_67fVl(18E{qRs1m#2r~)yu084C@1^zz&k8mt5al{#e>U#JU2stk%LKwai<|&fHR+Ry zK#)<$JQ{w43v9EP2n3l1{7Ssw_W+lA_+@hfL2e?qeqcreyJ{Tn_p z8~|1b*4;8p1`g6V_y^H>b5{lT>!JleBJ-)gwY(Qtpyr(+!fjN)ldzwXzqHXf$K(88 z04r5JGQ=6a8rPC<>}Yk`aOVxTBRk_a5@P(28HQmPhG7_nVHk#C7=~e#nEwDo!W@=9 SuJKm@0000 ic_info_outline.

ic_language.

ic_list.

+

ic_location_off.

ic_more.

ic_question_answer.

ic_select_all.

diff --git a/app/src/main/assets/it/about_licenses.html b/app/src/main/assets/it/about_licenses.html index f92b4f3a..c7ad171f 100644 --- a/app/src/main/assets/it/about_licenses.html +++ b/app/src/main/assets/it/about_licenses.html @@ -85,6 +85,7 @@

ic_info_outline.

ic_language.

ic_list.

+

ic_location_off.

ic_more.

ic_question_answer.

ic_select_all.

diff --git a/app/src/main/assets/zh-rTW/about_licenses.html b/app/src/main/assets/zh-rTW/about_licenses.html index ab596eae..741f8db7 100644 --- a/app/src/main/assets/zh-rTW/about_licenses.html +++ b/app/src/main/assets/zh-rTW/about_licenses.html @@ -79,6 +79,7 @@

ic_info_outline.

ic_language.

ic_list.

+

ic_location_off.

ic_more.

ic_question_answer.

ic_select_all.

diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index a7dfad7e..9551b16c 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -1236,10 +1236,21 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation return true; case R.id.share: + // Setup the share string. + String shareString; + if (webViewTitle != null) { + shareString = webViewTitle + " – " + urlTextBox.getText().toString(); + } else { + shareString = urlTextBox.getText().toString(); + } + + // Create the share intent. Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, urlTextBox.getText().toString()); + shareIntent.putExtra(Intent.EXTRA_TEXT, shareString); shareIntent.setType("text/plain"); + + // Make it so. startActivity(Intent.createChooser(shareIntent, "Share URL")); return true; diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index 75e008ad..06fd18ec 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -44,12 +44,14 @@ public class SettingsFragment extends PreferenceFragment { savedPreferences = getPreferenceScreen().getSharedPreferences(); // Get handles for the preferences we need to modify. - final Preference javaScriptEnabled = findPreference("javascript_enabled"); - final Preference firstPartyCookiesEnabled = findPreference("first_party_cookies_enabled"); - final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled"); - final Preference domStorageEnabled = findPreference("dom_storage_enabled"); + final Preference javaScriptPreference = findPreference("javascript_enabled"); + final Preference firstPartyCookiesPreference = findPreference("first_party_cookies_enabled"); + final Preference thirdPartyCookiesPreference = findPreference("third_party_cookies_enabled"); + final Preference domStoragePreference = findPreference("dom_storage_enabled"); + final Preference saveFormDataPreference = findPreference("save_form_data_enabled"); final Preference userAgentPreference = findPreference("user_agent"); - final Preference customUserAgent = findPreference("custom_user_agent"); + final Preference customUserAgentPreference = findPreference("custom_user_agent"); + final Preference doNotTrackPreference = findPreference("do_not_track"); final Preference torHomepagePreference = findPreference("tor_homepage"); final Preference torSearchPreference = findPreference("tor_search"); final Preference torSearchCustomURLPreference = findPreference("tor_search_custom_url"); @@ -61,7 +63,7 @@ public class SettingsFragment extends PreferenceFragment { final Preference defaultFontSizePreference = findPreference("default_font_size"); // Set dependencies. - domStorageEnabled.setDependency("javascript_enabled"); + domStoragePreference.setDependency("javascript_enabled"); torHomepagePreference.setDependency("proxy_through_orbot"); torSearchPreference.setDependency("proxy_through_orbot"); hideSystemBarsPreference.setDependency("enable_full_screen_browsing_mode"); @@ -75,8 +77,8 @@ public class SettingsFragment extends PreferenceFragment { boolean firstPartyCookiesEnabledBoolean = savedPreferences.getBoolean("first_party_cookies_enabled", false); boolean thirdPartyCookiesEnabledBoolean = savedPreferences.getBoolean("third_party_cookies_enabled", false); - // Only enable `third_party_cookies_enabled` if `first_party_cookies_enabled` is `true` and API >= 21. - thirdPartyCookiesEnabled.setEnabled(firstPartyCookiesEnabledBoolean && (Build.VERSION.SDK_INT >= 21)); + // Only enable `thirdPartyCookiesPreference` if `firstPartyCookiesEnabledBoolean` is `true` and API >= 21. + thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabledBoolean && (Build.VERSION.SDK_INT >= 21)); // We need to inflated a `WebView` to get the default user agent. LayoutInflater inflater = getActivity().getLayoutInflater(); @@ -102,9 +104,9 @@ public class SettingsFragment extends PreferenceFragment { break; } - // Set the summary text for "custom_user_agent" (the default is "PrivacyBrowser/1.0") and enable it if "user_agent" it set to "Custom user agent". - customUserAgent.setSummary(savedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0")); - customUserAgent.setEnabled(userAgentPreference.getSummary().equals("Custom user agent")); + // Set the summary text for "customUserAgentPreference" (the default is `PrivacyBrowser/1.0`) and enable it if `userAgentPreference` it set to `Custom user agent`. + customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0")); + customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals("Custom user agent")); // Set the Tor homepage URL as the summary text for the `tor_homepage` preference when the preference screen is loaded. The default is DuckDuckGo: `https://3g2upl4pq6kufc4m.onion`. @@ -152,40 +154,61 @@ public class SettingsFragment extends PreferenceFragment { defaultFontSizePreference.setSummary(savedPreferences.getString("default_font_size", "100") + "%%"); - // Set the `javascript_enabled` icon. + // Set the `javaScriptPreference` icon. if (javaScriptEnabledBoolean) { - javaScriptEnabled.setIcon(R.drawable.javascript_enabled); + javaScriptPreference.setIcon(R.drawable.javascript_enabled); } else { - javaScriptEnabled.setIcon(R.drawable.privacy_mode); + javaScriptPreference.setIcon(R.drawable.privacy_mode); } - // Set the `first_party_cookies_enabled` icon. + // Set the `firstPartyCookiesPreference` icon. if (firstPartyCookiesEnabledBoolean) { - firstPartyCookiesEnabled.setIcon(R.drawable.cookies_enabled); + firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled); } else { - firstPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled); } - // Set the `third_party_cookies_enabled` icon. + // Set the `thirdPartyCookiesPreference` icon. if (firstPartyCookiesEnabledBoolean && Build.VERSION.SDK_INT >= 21) { if (thirdPartyCookiesEnabledBoolean) { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_warning); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning); } else { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled); } } else { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_ghosted); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted); } - // Set the `dom_storage_enabled` icon. + // Set the `domStoragePreference` icon. if (javaScriptEnabledBoolean) { if (savedPreferences.getBoolean("dom_storage_enabled", false)) { - domStorageEnabled.setIcon(R.drawable.dom_storage_enabled); + domStoragePreference.setIcon(R.drawable.dom_storage_enabled); } else { - domStorageEnabled.setIcon(R.drawable.dom_storage_disabled); + domStoragePreference.setIcon(R.drawable.dom_storage_disabled); } } else { - domStorageEnabled.setIcon(R.drawable.dom_storage_ghosted); + domStoragePreference.setIcon(R.drawable.dom_storage_ghosted); + } + + // Set the `saveFormDataPreference` icon. + if (savedPreferences.getBoolean("save_form_data_enabled", false)) { + saveFormDataPreference.setIcon(R.drawable.form_data_enabled); + } else { + saveFormDataPreference.setIcon(R.drawable.form_data_disabled); + } + + // Set the `customUserAgentPreference` icon. + if (customUserAgentPreference.isEnabled()) { + customUserAgentPreference.setIcon(R.drawable.user_agent_enabled); + } else { + customUserAgentPreference.setIcon(R.drawable.user_agent_ghosted); + } + + // Set the `doNotTrackPreference` icon. + if (savedPreferences.getBoolean("do_not_track", false)) { + doNotTrackPreference.setIcon(R.drawable.do_not_track_enabled); + } else { + doNotTrackPreference.setIcon(R.drawable.do_not_track_disabled); } // Listen for preference changes. @@ -200,20 +223,20 @@ public class SettingsFragment extends PreferenceFragment { // Update the icons. if (sharedPreferences.getBoolean("javascript_enabled", false)) { // Update the icon for `javascript_enabled`. - javaScriptEnabled.setIcon(R.drawable.javascript_enabled); + javaScriptPreference.setIcon(R.drawable.javascript_enabled); // Update the icon for `dom_storage_enabled`. if (sharedPreferences.getBoolean("dom_storage_enabled", false)) { - domStorageEnabled.setIcon(R.drawable.dom_storage_enabled); + domStoragePreference.setIcon(R.drawable.dom_storage_enabled); } else { - domStorageEnabled.setIcon(R.drawable.dom_storage_disabled); + domStoragePreference.setIcon(R.drawable.dom_storage_disabled); } } else { // `javascript_enabled` is `false`. // Update the icon for `javascript_enabled`. - javaScriptEnabled.setIcon(R.drawable.privacy_mode); + javaScriptPreference.setIcon(R.drawable.privacy_mode); // Set the icon for `dom_storage_disabled` to be ghosted. - domStorageEnabled.setIcon(R.drawable.dom_storage_ghosted); + domStoragePreference.setIcon(R.drawable.dom_storage_ghosted); } break; @@ -221,75 +244,102 @@ public class SettingsFragment extends PreferenceFragment { // Update the icons for `first_party_cookies_enabled` and `third_party_cookies_enabled`. if (sharedPreferences.getBoolean("first_party_cookies_enabled", false)) { // Set the icon for `first_party_cookies_enabled`. - firstPartyCookiesEnabled.setIcon(R.drawable.cookies_enabled); + firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled); // Update the icon for `third_party_cookies_enabled`. if (Build.VERSION.SDK_INT >= 21) { if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_warning); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning); } else { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled); } } else { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_ghosted); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted); } } else { // `first_party_cookies_enabled` is `false`. // Update the icon for `first_party_cookies_enabled`. - firstPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled); // Set the icon for `third_party_cookies_enabled` to be ghosted. - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_ghosted); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted); } // Enable `third_party_cookies_enabled` if `first_party_cookies_enabled` is `true` and API >= 21. - thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false) && (Build.VERSION.SDK_INT >= 21)); + thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false) && (Build.VERSION.SDK_INT >= 21)); break; case "third_party_cookies_enabled": // Update the icon. if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_warning); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning); } else { - thirdPartyCookiesEnabled.setIcon(R.drawable.cookies_disabled); + thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled); } break; case "dom_storage_enabled": // Update the icon. if (sharedPreferences.getBoolean("dom_storage_enabled", false)) { - domStorageEnabled.setIcon(R.drawable.dom_storage_enabled); + domStoragePreference.setIcon(R.drawable.dom_storage_enabled); } else { - domStorageEnabled.setIcon(R.drawable.dom_storage_disabled); + domStoragePreference.setIcon(R.drawable.dom_storage_disabled); } break; + case "save_form_data_enabled": + // Update the icon. + if (sharedPreferences.getBoolean("save_form_data_enabled", false)) { + saveFormDataPreference.setIcon(R.drawable.form_data_enabled); + } else { + saveFormDataPreference.setIcon(R.drawable.form_data_disabled); + } + case "user_agent": String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"); switch (userAgentString) { case "WebView default user agent": - // Display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`. + // Display the user agent as the summary text for `userAgentPreference`. userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString()); - customUserAgent.setEnabled(false); + + // Update `customUserAgentPreference`. + customUserAgentPreference.setEnabled(false); + customUserAgentPreference.setIcon(R.drawable.user_agent_ghosted); break; case "Custom user agent": - // Display `Custom user agent` as the summary text for `userAgentPreference`, and enable `customUserAgent`. + // Display `Custom user agent` as the summary text for `userAgentPreference`. userAgentPreference.setSummary(R.string.custom_user_agent); - customUserAgent.setEnabled(true); + + // Update `customUserAgentPreference`. + customUserAgentPreference.setEnabled(true); + customUserAgentPreference.setIcon(R.drawable.user_agent_enabled); break; default: - // Display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`. + // Display the user agent as the summary text for `userAgentPreference`. userAgentPreference.setSummary(sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0")); - customUserAgent.setEnabled(false); + + // Update `customUserAgentPreference`. + customUserAgentPreference.setEnabled(false); + customUserAgentPreference.setIcon(R.drawable.user_agent_ghosted); break; } break; case "custom_user_agent": // Set the new custom user agent as the summary text for `custom_user_agent`. The default is `PrivacyBrowser/1.0`. - customUserAgent.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0")); + customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0")); + break; + + case "do_not_track": + // Update the icon. + if (sharedPreferences.getBoolean("do_not_track", false)) { + doNotTrackPreference.setIcon(R.drawable.do_not_track_enabled); + } else { + doNotTrackPreference.setIcon(R.drawable.do_not_track_disabled); + } + break; case "proxy_through_orbot": diff --git a/app/src/main/res/drawable/do_not_track_disabled.xml b/app/src/main/res/drawable/do_not_track_disabled.xml new file mode 100644 index 00000000..77ba07e1 --- /dev/null +++ b/app/src/main/res/drawable/do_not_track_disabled.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/app/src/main/res/drawable/do_not_track_enabled.xml b/app/src/main/res/drawable/do_not_track_enabled.xml new file mode 100644 index 00000000..c60ecc1b --- /dev/null +++ b/app/src/main/res/drawable/do_not_track_enabled.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/app/src/main/res/drawable/user_agent.xml b/app/src/main/res/drawable/user_agent_enabled.xml similarity index 86% rename from app/src/main/res/drawable/user_agent.xml rename to app/src/main/res/drawable/user_agent_enabled.xml index a346c597..35fba81a 100644 --- a/app/src/main/res/drawable/user_agent.xml +++ b/app/src/main/res/drawable/user_agent_enabled.xml @@ -1,4 +1,4 @@ - + + + + + + + + diff --git a/app/src/main/res/layout/domain_settings.xml b/app/src/main/res/layout/domain_settings.xml index 00479b52..ec020546 100644 --- a/app/src/main/res/layout/domain_settings.xml +++ b/app/src/main/res/layout/domain_settings.xml @@ -236,7 +236,7 @@ android:layout_marginTop="1dp" android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" - android:src="@drawable/user_agent" + android:src="@drawable/user_agent_enabled" android:contentDescription="@string/user_agent" /> + android:icon="@drawable/user_agent_enabled" /> Date: Thu, 18 May 2017 17:56:17 -0700 Subject: [PATCH 03/16] Updates about_licenses, adding the full text of the Apache License 2.0 and the 3-Clause BSD License. --- app/build.gradle | 2 +- app/src/free/assets/de/about_permissions.html | 2 +- .../free/assets/de/about_privacy_policy.html | 2 +- app/src/free/assets/en/about_permissions.html | 2 +- .../free/assets/en/about_privacy_policy.html | 2 +- app/src/free/assets/es/about_permissions.html | 2 +- .../free/assets/es/about_privacy_policy.html | 2 +- app/src/free/assets/it/about_permissions.html | 2 +- .../free/assets/it/about_privacy_policy.html | 2 +- .../free/assets/zh-rTW/about_permissions.html | 2 +- .../assets/zh-rTW/about_privacy_policy.html | 2 +- .../com/stoutner/privacybrowser/BannerAd.java | 2 +- app/src/free/res/layout/main_webview.xml | 2 +- app/src/free/res/values-de/strings.xml | 2 +- app/src/free/res/values-es/strings.xml | 2 +- app/src/free/res/values-it/strings.xml | 2 +- app/src/free/res/values-zh-rTW/strings.xml | 2 +- app/src/free/res/values/strings.xml | 2 +- app/src/main/AndroidManifest.xml | 2 +- app/src/main/assets/de/about_changelog.html | 2 +- .../main/assets/de/about_contributors.html | 2 +- app/src/main/assets/de/about_licenses.html | 344 +++++++++++++++++- app/src/main/assets/de/about_links.html | 2 +- app/src/main/assets/de/about_permissions.html | 2 +- .../main/assets/de/about_privacy_policy.html | 2 +- .../main/assets/de/guide_clear_and_exit.html | 2 +- .../main/assets/de/guide_domain_settings.html | 2 +- app/src/main/assets/de/guide_javascript.html | 2 +- .../main/assets/de/guide_local_storage.html | 2 +- app/src/main/assets/de/guide_overview.html | 2 +- .../assets/de/guide_planned_features.html | 2 +- app/src/main/assets/de/guide_tor.html | 2 +- .../main/assets/de/guide_tracking_ids.html | 2 +- app/src/main/assets/de/guide_user_agent.html | 2 +- app/src/main/assets/en/about_changelog.html | 2 +- .../main/assets/en/about_contributors.html | 2 +- app/src/main/assets/en/about_licenses.html | 340 ++++++++++++++++- app/src/main/assets/en/about_links.html | 2 +- app/src/main/assets/en/about_permissions.html | 2 +- .../main/assets/en/about_privacy_policy.html | 2 +- .../main/assets/en/guide_clear_and_exit.html | 2 +- .../main/assets/en/guide_domain_settings.html | 2 +- app/src/main/assets/en/guide_javascript.html | 2 +- .../main/assets/en/guide_local_storage.html | 2 +- app/src/main/assets/en/guide_overview.html | 2 +- .../assets/en/guide_planned_features.html | 2 +- app/src/main/assets/en/guide_tor.html | 2 +- .../main/assets/en/guide_tracking_ids.html | 2 +- app/src/main/assets/en/guide_user_agent.html | 2 +- .../main/assets/en/images/ic_find_in_page.png | Bin 0 -> 2115 bytes .../assets/en/images/ic_important_devices.png | Bin 0 -> 1592 bytes .../assets/en/images/ic_local_activity.png | Bin 0 -> 1889 bytes app/src/main/assets/en/images/ic_search.png | Bin 0 -> 1893 bytes .../assets/en/images/ic_visibility_off.png | Bin 0 -> 2400 bytes app/src/main/assets/en/images/orbot.png | Bin 0 -> 1995 bytes app/src/main/assets/es/about_changelog.html | 2 +- .../main/assets/es/about_contributors.html | 2 +- app/src/main/assets/es/about_licenses.html | 340 ++++++++++++++++- app/src/main/assets/es/about_links.html | 2 +- app/src/main/assets/es/about_permissions.html | 2 +- .../main/assets/es/about_privacy_policy.html | 2 +- .../main/assets/es/guide_clear_and_exit.html | 2 +- .../main/assets/es/guide_domain_settings.html | 2 +- app/src/main/assets/es/guide_javascript.html | 2 +- .../main/assets/es/guide_local_storage.html | 2 +- app/src/main/assets/es/guide_overview.html | 2 +- .../assets/es/guide_planned_features.html | 4 +- app/src/main/assets/es/guide_tor.html | 2 +- .../main/assets/es/guide_tracking_ids.html | 2 +- app/src/main/assets/es/guide_user_agent.html | 2 +- app/src/main/assets/it/about_changelog.html | 2 +- .../main/assets/it/about_contributors.html | 2 +- app/src/main/assets/it/about_licenses.html | 338 ++++++++++++++++- app/src/main/assets/it/about_links.html | 2 +- app/src/main/assets/it/about_permissions.html | 2 +- .../main/assets/it/about_privacy_policy.html | 2 +- .../main/assets/it/guide_clear_and_exit.html | 2 +- .../main/assets/it/guide_domain_settings.html | 4 +- app/src/main/assets/it/guide_javascript.html | 2 +- .../main/assets/it/guide_local_storage.html | 2 +- app/src/main/assets/it/guide_overview.html | 2 +- .../assets/it/guide_planned_features.html | 2 +- app/src/main/assets/it/guide_tor.html | 4 +- .../main/assets/it/guide_tracking_ids.html | 2 +- app/src/main/assets/it/guide_user_agent.html | 2 +- .../main/assets/zh-rTW/about_changelog.html | 2 +- .../assets/zh-rTW/about_contributors.html | 2 +- .../main/assets/zh-rTW/about_licenses.html | 340 ++++++++++++++++- app/src/main/assets/zh-rTW/about_links.html | 2 +- .../main/assets/zh-rTW/about_permissions.html | 2 +- .../assets/zh-rTW/about_privacy_policy.html | 2 +- .../assets/zh-rTW/guide_clear_and_exit.html | 2 +- .../assets/zh-rTW/guide_domain_settings.html | 2 +- .../main/assets/zh-rTW/guide_javascript.html | 2 +- .../assets/zh-rTW/guide_local_storage.html | 2 +- .../main/assets/zh-rTW/guide_overview.html | 2 +- .../assets/zh-rTW/guide_planned_features.html | 2 +- app/src/main/assets/zh-rTW/guide_tor.html | 2 +- .../assets/zh-rTW/guide_tracking_ids.html | 2 +- .../main/assets/zh-rTW/guide_user_agent.html | 2 +- .../activities/AboutActivity.java | 2 +- .../activities/BookmarksActivity.java | 2 +- .../BookmarksDatabaseViewActivity.java | 2 +- .../activities/DomainSettingsActivity.java | 2 +- .../activities/DomainsActivity.java | 2 +- .../activities/GuideActivity.java | 2 +- .../activities/MainWebViewActivity.java | 2 +- .../activities/SettingsActivity.java | 2 +- .../adapters/HistoryArrayAdapter.java | 4 +- .../privacybrowser/definitions/History.java | 2 +- .../dialogs/AddDomainDialog.java | 2 +- .../dialogs/CreateBookmarkDialog.java | 2 +- .../dialogs/CreateBookmarkFolderDialog.java | 2 +- .../CreateHomeScreenShortcutDialog.java | 2 +- .../dialogs/DownloadFileDialog.java | 2 +- .../dialogs/DownloadImageDialog.java | 2 +- .../dialogs/EditBookmarkDialog.java | 2 +- .../dialogs/EditBookmarkFolderDialog.java | 2 +- .../dialogs/MoveToFolderDialog.java | 2 +- .../dialogs/SslCertificateErrorDialog.java | 2 +- .../dialogs/UrlHistoryDialog.java | 2 +- .../dialogs/ViewSslCertificateDialog.java | 2 +- .../fragments/AboutTabFragment.java | 2 +- .../fragments/DomainSettingsFragment.java | 2 +- .../fragments/GuideTabFragment.java | 2 +- .../fragments/SettingsFragment.java | 92 ++++- .../helpers/BookmarksDatabaseHelper.java | 2 +- .../helpers/DomainsDatabaseHelper.java | 2 +- .../helpers/OrbotProxyHelper.java | 2 +- app/src/main/res/drawable/about.xml | 1 - app/src/main/res/drawable/add.xml | 1 - app/src/main/res/drawable/back.xml | 2 +- .../main/res/drawable/block_ads_disabled.xml | 12 + .../main/res/drawable/block_ads_enabled.xml | 12 + app/src/main/res/drawable/bookmarks.xml | 1 - app/src/main/res/drawable/close.xml | 1 - .../main/res/drawable/cookies_disabled.xml | 2 +- app/src/main/res/drawable/cookies_enabled.xml | 2 +- app/src/main/res/drawable/cookies_ghosted.xml | 2 +- app/src/main/res/drawable/cookies_warning.xml | 2 +- app/src/main/res/drawable/create_folder.xml | 2 +- .../drawable/custom_user_agent_enabled.xml | 18 + .../drawable/custom_user_agent_ghosted.xml | 18 + app/src/main/res/drawable/delete.xml | 1 - app/src/main/res/drawable/delete_blue.xml | 1 - .../res/drawable/do_not_track_disabled.xml | 3 +- .../res/drawable/do_not_track_enabled.xml | 3 +- .../res/drawable/dom_storage_disabled.xml | 2 +- .../main/res/drawable/dom_storage_enabled.xml | 2 +- .../main/res/drawable/dom_storage_ghosted.xml | 2 +- app/src/main/res/drawable/domains.xml | 2 +- app/src/main/res/drawable/downloads.xml | 1 - app/src/main/res/drawable/edit.xml | 2 +- app/src/main/res/drawable/exit.xml | 2 +- .../main/res/drawable/folder_dark_blue.xml | 1 - app/src/main/res/drawable/folder_gray.xml | 1 - app/src/main/res/drawable/font_size.xml | 2 +- .../main/res/drawable/form_data_disabled.xml | 2 +- .../main/res/drawable/form_data_enabled.xml | 2 +- app/src/main/res/drawable/forward.xml | 2 +- app/src/main/res/drawable/guide.xml | 2 +- app/src/main/res/drawable/history.xml | 2 +- app/src/main/res/drawable/home.xml | 1 - .../res/drawable/incognito_mode_disabled.xml | 18 + .../res/drawable/incognito_mode_enabled.xml | 18 + .../main/res/drawable/javascript_enabled.xml | 2 +- .../drawable/move_bookmark_down_disabled.xml | 1 - .../drawable/move_bookmark_down_enabled.xml | 1 - .../drawable/move_bookmark_up_disabled.xml | 1 - .../res/drawable/move_bookmark_up_enabled.xml | 1 - app/src/main/res/drawable/move_to_folder.xml | 2 +- app/src/main/res/drawable/next.xml | 1 - app/src/main/res/drawable/orbot_disabled.xml | 19 + app/src/main/res/drawable/orbot_enabled.xml | 19 + app/src/main/res/drawable/previous.xml | 1 - app/src/main/res/drawable/privacy_mode.xml | 2 +- .../drawable/search_custom_url_enabled.xml | 18 + .../drawable/search_custom_url_ghosted.xml | 18 + app/src/main/res/drawable/search_enabled.xml | 18 + app/src/main/res/drawable/select_all.xml | 1 - app/src/main/res/drawable/settings.xml | 1 - ...{user_agent_ghosted.xml => user_agent.xml} | 6 +- app/src/main/res/drawable/warning.xml | 2 +- .../main/res/layout-w900dp/domains_list.xml | 2 +- .../res/layout/about_coordinatorlayout.xml | 2 +- app/src/main/res/layout/about_tab_version.xml | 2 +- app/src/main/res/layout/add_domain_dialog.xml | 2 +- app/src/main/res/layout/bare_webview.xml | 2 +- .../layout/bookmarks_coordinatorlayout.xml | 2 +- ...kmarks_database_view_coordinatorlayout.xml | 2 +- ...kmarks_database_view_item_linearlayout.xml | 2 +- .../layout/bookmarks_item_linearlayout.xml | 2 +- .../res/layout/create_bookmark_dialog.xml | 2 +- .../layout/create_bookmark_folder_dialog.xml | 2 +- .../create_home_screen_shortcut_dialog.xml | 2 +- .../res/layout/domain_name_linearlayout.xml | 2 +- app/src/main/res/layout/domain_settings.xml | 4 +- .../domain_settings_coordinatorlayout.xml | 2 +- .../res/layout/domains_coordinatorlayout.xml | 2 +- app/src/main/res/layout/domains_list.xml | 2 +- .../main/res/layout/download_file_dialog.xml | 2 +- .../main/res/layout/download_image_dialog.xml | 2 +- .../main/res/layout/edit_bookmark_dialog.xml | 2 +- .../layout/edit_bookmark_folder_dialog.xml | 2 +- .../main/res/layout/find_on_page_app_bar.xml | 2 +- .../res/layout/guide_coordinatorlayout.xml | 2 +- app/src/main/res/layout/guide_tab_webview.xml | 2 +- app/src/main/res/layout/main_drawerlayout.xml | 2 +- app/src/main/res/layout/main_webview.xml | 2 +- .../main/res/layout/move_to_folder_dialog.xml | 2 +- .../move_to_folder_item_linearlayout.xml | 2 +- app/src/main/res/layout/navigation_header.xml | 2 +- .../main/res/layout/ssl_certificate_error.xml | 2 +- .../main/res/layout/unencrypted_website.xml | 2 +- app/src/main/res/layout/url_app_bar.xml | 2 +- .../main/res/layout/url_history_dialog.xml | 2 +- .../layout/url_history_item_linearlayout.xml | 2 +- .../main/res/layout/view_ssl_certificate.xml | 2 +- .../main/res/menu/bookmarks_context_menu.xml | 2 +- .../main/res/menu/bookmarks_options_menu.xml | 2 +- .../main/res/menu/domains_options_menu.xml | 2 +- .../main/res/menu/webview_navigation_menu.xml | 2 +- .../main/res/menu/webview_options_menu.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/colors.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/styles.xml | 2 +- app/src/main/res/xml/preferences.xml | 7 +- .../com/stoutner/privacybrowser/BannerAd.java | 4 +- 232 files changed, 2122 insertions(+), 283 deletions(-) create mode 100644 app/src/main/assets/en/images/ic_find_in_page.png create mode 100644 app/src/main/assets/en/images/ic_important_devices.png create mode 100644 app/src/main/assets/en/images/ic_local_activity.png create mode 100644 app/src/main/assets/en/images/ic_search.png create mode 100644 app/src/main/assets/en/images/ic_visibility_off.png create mode 100644 app/src/main/assets/en/images/orbot.png create mode 100644 app/src/main/res/drawable/block_ads_disabled.xml create mode 100644 app/src/main/res/drawable/block_ads_enabled.xml create mode 100644 app/src/main/res/drawable/custom_user_agent_enabled.xml create mode 100644 app/src/main/res/drawable/custom_user_agent_ghosted.xml create mode 100644 app/src/main/res/drawable/incognito_mode_disabled.xml create mode 100644 app/src/main/res/drawable/incognito_mode_enabled.xml create mode 100644 app/src/main/res/drawable/orbot_disabled.xml create mode 100644 app/src/main/res/drawable/orbot_enabled.xml create mode 100644 app/src/main/res/drawable/search_custom_url_enabled.xml create mode 100644 app/src/main/res/drawable/search_custom_url_ghosted.xml create mode 100644 app/src/main/res/drawable/search_enabled.xml rename app/src/main/res/drawable/{user_agent_ghosted.xml => user_agent.xml} (86%) diff --git a/app/build.gradle b/app/build.gradle index d6155919..16dd5a44 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,5 @@ /* - * Copyright 2016-2017 Soren Stoutner . + * Copyright © 2016-2017 Soren Stoutner . * * This file is part of Privacy Browser . * diff --git a/app/src/free/assets/de/about_permissions.html b/app/src/free/assets/de/about_permissions.html index 45083853..75b01770 100644 --- a/app/src/free/assets/de/about_permissions.html +++ b/app/src/free/assets/de/about_permissions.html @@ -1,5 +1,5 @@ - - - + + + + + + diff --git a/app/src/main/res/drawable/block_ads_enabled.xml b/app/src/main/res/drawable/block_ads_enabled.xml new file mode 100644 index 00000000..de1efc61 --- /dev/null +++ b/app/src/main/res/drawable/block_ads_enabled.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/drawable/bookmarks.xml b/app/src/main/res/drawable/bookmarks.xml index 29b2648d..995775bc 100644 --- a/app/src/main/res/drawable/bookmarks.xml +++ b/app/src/main/res/drawable/bookmarks.xml @@ -1,5 +1,4 @@ - - . It is released under the Apache License 2.0. --> - + . It is released under the Apache License 2.0. --> - + . It is released under the Apache License 2.0. --> - + . It is released under the Apache License 2.0. --> - + - + + + + + + + + diff --git a/app/src/main/res/drawable/custom_user_agent_ghosted.xml b/app/src/main/res/drawable/custom_user_agent_ghosted.xml new file mode 100644 index 00000000..86bdf912 --- /dev/null +++ b/app/src/main/res/drawable/custom_user_agent_ghosted.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/delete.xml b/app/src/main/res/drawable/delete.xml index 15b276bd..853d272c 100644 --- a/app/src/main/res/drawable/delete.xml +++ b/app/src/main/res/drawable/delete.xml @@ -1,5 +1,4 @@ - - - + + diff --git a/app/src/main/res/drawable/do_not_track_enabled.xml b/app/src/main/res/drawable/do_not_track_enabled.xml index c60ecc1b..dafb11e6 100644 --- a/app/src/main/res/drawable/do_not_track_enabled.xml +++ b/app/src/main/res/drawable/do_not_track_enabled.xml @@ -1,6 +1,6 @@ - + + diff --git a/app/src/main/res/drawable/dom_storage_disabled.xml b/app/src/main/res/drawable/dom_storage_disabled.xml index b6a8d83f..d6180570 100644 --- a/app/src/main/res/drawable/dom_storage_disabled.xml +++ b/app/src/main/res/drawable/dom_storage_disabled.xml @@ -1,6 +1,6 @@ - + - + - + - + - - + - + - - - + - + - + - + - + - + - + + + + + + + diff --git a/app/src/main/res/drawable/incognito_mode_enabled.xml b/app/src/main/res/drawable/incognito_mode_enabled.xml new file mode 100644 index 00000000..a8fee863 --- /dev/null +++ b/app/src/main/res/drawable/incognito_mode_enabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/javascript_enabled.xml b/app/src/main/res/drawable/javascript_enabled.xml index 3af89ca6..02c9b168 100644 --- a/app/src/main/res/drawable/javascript_enabled.xml +++ b/app/src/main/res/drawable/javascript_enabled.xml @@ -1,5 +1,5 @@ + Modifications copyright Soren Stoutner 2016. The resulting image is released under the GPLv3+ license. --> - - - - - + - , which is released under the 3-clause BSD license. + Modifications copyright Soren Stoutner 2017. The resulting image is released under the GPLv3+ license. --> + + + + + + + diff --git a/app/src/main/res/drawable/orbot_enabled.xml b/app/src/main/res/drawable/orbot_enabled.xml new file mode 100644 index 00000000..1b3c2cc7 --- /dev/null +++ b/app/src/main/res/drawable/orbot_enabled.xml @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/previous.xml b/app/src/main/res/drawable/previous.xml index 2b0eb08f..c10bb3d4 100644 --- a/app/src/main/res/drawable/previous.xml +++ b/app/src/main/res/drawable/previous.xml @@ -1,5 +1,4 @@ - in 2016 and are released under the GPLv3+ license. --> + Modifications copyright Soren Stoutner 2016. The resulting image is released under the GPLv3+ license. --> + + + + + + + diff --git a/app/src/main/res/drawable/search_custom_url_ghosted.xml b/app/src/main/res/drawable/search_custom_url_ghosted.xml new file mode 100644 index 00000000..c2cc1177 --- /dev/null +++ b/app/src/main/res/drawable/search_custom_url_ghosted.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/search_enabled.xml b/app/src/main/res/drawable/search_enabled.xml new file mode 100644 index 00000000..7f4a880e --- /dev/null +++ b/app/src/main/res/drawable/search_enabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/select_all.xml b/app/src/main/res/drawable/select_all.xml index 216677e3..c27e108e 100644 --- a/app/src/main/res/drawable/select_all.xml +++ b/app/src/main/res/drawable/select_all.xml @@ -1,5 +1,4 @@ - - + - + = 21. Then we can use `@color`. --> diff --git a/app/src/main/res/drawable/warning.xml b/app/src/main/res/drawable/warning.xml index 863c1262..6225884c 100644 --- a/app/src/main/res/drawable/warning.xml +++ b/app/src/main/res/drawable/warning.xml @@ -1,5 +1,5 @@ + Modifications copyright © 2016 Soren Stoutner . The resulting image is released under the GPLv3+ license. --> + android:defaultValue="https://duckduckgo.com/html/?q=" + android:icon="@drawable/search_enabled" /> . +/* + * Copyright © 2016-2017 Soren Stoutner . * * This file is part of Privacy Browser . * -- 2.45.2 From ae5cf6844097d6e1d24e628149de3109eac5a120 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Sat, 20 May 2017 20:09:03 -0700 Subject: [PATCH 04/16] Add icons to the settings activity. Implements https://redmine.stoutner.com/issues/129. --- app/src/main/assets/de/about_licenses.html | 46 +++-- app/src/main/assets/en/about_licenses.html | 46 +++-- .../assets/en/images/ic_call_to_action.png | Bin 0 -> 775 bytes .../main/assets/en/images/ic_fullscreen.png | Bin 0 -> 482 bytes app/src/main/assets/en/images/ic_refresh.png | Bin 0 -> 1992 bytes .../main/assets/en/images/ic_smartphone.png | Bin 0 -> 864 bytes app/src/main/assets/es/about_licenses.html | 64 +++--- app/src/main/assets/it/about_licenses.html | 10 +- .../main/assets/zh-rTW/about_licenses.html | 46 +++-- .../activities/MainWebViewActivity.java | 2 +- .../fragments/SettingsFragment.java | 186 ++++++++++++++++-- .../res/drawable/full_screen_disabled.xml | 13 ++ .../main/res/drawable/full_screen_enabled.xml | 13 ++ .../drawable/hide_system_bars_disabled.xml | 13 ++ .../res/drawable/hide_system_bars_enabled.xml | 13 ++ .../res/drawable/hide_system_bars_ghosted.xml | 13 ++ .../drawable/{home.xml => home_enabled.xml} | 4 +- app/src/main/res/drawable/home_ghosted.xml | 13 ++ app/src/main/res/drawable/more_disabled.xml | 18 ++ app/src/main/res/drawable/more_enabled.xml | 18 ++ .../main/res/drawable/refresh_disabled.xml | 18 ++ app/src/main/res/drawable/refresh_enabled.xml | 18 ++ .../drawable/search_custom_url_disabled.xml | 18 ++ app/src/main/res/drawable/search_ghosted.xml | 18 ++ .../res/drawable/translucent_bar_disabled.xml | 13 ++ .../res/drawable/translucent_bar_enabled.xml | 13 ++ .../res/drawable/translucent_bar_ghosted.xml | 13 ++ .../main/res/drawable/user_agent_enabled.xml | 18 -- .../main/res/menu/webview_navigation_menu.xml | 2 +- app/src/main/res/values-es/strings.xml | 4 +- app/src/main/res/values-it/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 4 +- app/src/main/res/values/strings.xml | 8 +- app/src/main/res/xml/preferences.xml | 9 +- 34 files changed, 531 insertions(+), 147 deletions(-) create mode 100644 app/src/main/assets/en/images/ic_call_to_action.png create mode 100644 app/src/main/assets/en/images/ic_fullscreen.png create mode 100644 app/src/main/assets/en/images/ic_refresh.png create mode 100644 app/src/main/assets/en/images/ic_smartphone.png create mode 100644 app/src/main/res/drawable/full_screen_disabled.xml create mode 100644 app/src/main/res/drawable/full_screen_enabled.xml create mode 100644 app/src/main/res/drawable/hide_system_bars_disabled.xml create mode 100644 app/src/main/res/drawable/hide_system_bars_enabled.xml create mode 100644 app/src/main/res/drawable/hide_system_bars_ghosted.xml rename app/src/main/res/drawable/{home.xml => home_enabled.xml} (66%) create mode 100644 app/src/main/res/drawable/home_ghosted.xml create mode 100644 app/src/main/res/drawable/more_disabled.xml create mode 100644 app/src/main/res/drawable/more_enabled.xml create mode 100644 app/src/main/res/drawable/refresh_disabled.xml create mode 100644 app/src/main/res/drawable/refresh_enabled.xml create mode 100644 app/src/main/res/drawable/search_custom_url_disabled.xml create mode 100644 app/src/main/res/drawable/search_ghosted.xml create mode 100644 app/src/main/res/drawable/translucent_bar_disabled.xml create mode 100644 app/src/main/res/drawable/translucent_bar_enabled.xml create mode 100644 app/src/main/res/drawable/translucent_bar_ghosted.xml delete mode 100644 app/src/main/res/drawable/user_agent_enabled.xml diff --git a/app/src/main/assets/de/about_licenses.html b/app/src/main/assets/de/about_licenses.html index 645c0c69..ddd730db 100644 --- a/app/src/main/assets/de/about_licenses.html +++ b/app/src/main/assets/de/about_licenses.html @@ -60,8 +60,8 @@ are derived from ic_security and ic_language, which are part of the Android Material icon set and are released under the Apache License 2.0. The full text of the license is below. Modifications copyright © 2016 Soren Stoutner. The resulting images are released under the GPLv3+ license.

orbot is a modified version of the status icon from the Orbot project, which is copyright - 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

+ 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. + The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. The resulting image is released under the GPLv3+ license.

cookie was created by Google. It is released under the Apache License 2.0 and can be downloaded from Material Design Icons. It is unchanged except for layout information like color and size.

@@ -72,6 +72,7 @@

ic_arrow_forward.

ic_bookmark_border.

ic_bug_report.

+

ic_call_to_action.

ic_chrome_reader_mode.

ic_close.

ic_create_new_folder.

@@ -86,6 +87,7 @@

ic_find_in_page.

ic_folder.

ic_folder_special.

+

ic_fullscreen.

ic_home.

ic_import_contacts.

ic_important_devices.

@@ -96,9 +98,11 @@

ic_location_off.

ic_more.

ic_question_answer.

+

ic_refresh.

ic_search.

ic_select_all.

ic_settings.

+

ic_smartphone.

ic_subtitles.

ic_text_fields.

ic_vertical_align_bottom.

@@ -127,7 +131,7 @@

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to - share and change all versions of a program--to make sure it remains free + share and change all versions of a program—to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to @@ -155,16 +159,16 @@ (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

-

For the developers' and authors' protection, the GPL clearly explains - that there is no warranty for this free software. For both users' and - authors' sake, the GPL requires that modified versions be marked as +

For the developers’ and authors’ protection, the GPL clearly explains + that there is no warranty for this free software. For both users’ and + authors’ sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of - protecting users' freedom to change the software. The systematic + protecting users’ freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those @@ -248,7 +252,7 @@

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to - control those activities. However, it does not include the work's + control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source @@ -290,7 +294,7 @@ the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

-

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

+

3. Protecting Users’ Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article @@ -302,13 +306,13 @@ circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or - modification of the work as a means of enforcing, against the work's - users, your or third parties' legal rights to forbid circumvention of + modification of the work as a means of enforcing, against the work’s + users, your or third parties’ legal rights to forbid circumvention of technological measures.

4. Conveying Verbatim Copies.

-

You may convey verbatim copies of the Program's source code as you +

You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any @@ -353,7 +357,7 @@ and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not - used to limit the access or legal rights of the compilation's users + used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

@@ -575,7 +579,7 @@ organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever - licenses to the work the party's predecessor in interest had or could + licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

@@ -592,9 +596,9 @@

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The - work thus licensed is called the contributor's “contributor version”.

+ work thus licensed is called the contributor’s “contributor version”.

-

A contributor's “essential patent claims” are all patent claims +

A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, @@ -605,7 +609,7 @@ this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free - patent license under the contributor's essential patent claims, to + patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

@@ -626,7 +630,7 @@ consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the - covered work in a country, or your recipient's use of the covered work + covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

@@ -657,7 +661,7 @@ any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

-

12. No Surrender of Others' Freedom.

+

12. No Surrender of Others’ Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not @@ -697,7 +701,7 @@ by the Free Software Foundation.

If the Program specifies that a proxy can decide which future - versions of the GNU General Public License can be used, that proxy's + versions of the GNU General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

@@ -790,7 +794,7 @@ certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate - parts of the General Public License. Of course, your program's commands + parts of the General Public License. Of course, your program’s commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, diff --git a/app/src/main/assets/en/about_licenses.html b/app/src/main/assets/en/about_licenses.html index ed4aa4d5..c433ce37 100644 --- a/app/src/main/assets/en/about_licenses.html +++ b/app/src/main/assets/en/about_licenses.html @@ -55,8 +55,8 @@ are derived from ic_security and ic_language, which are part of the Android Material icon set and are released under the Apache License 2.0. The full text of the license is below. Modifications copyright © 2016 Soren Stoutner. The resulting images are released under the GPLv3+ license.

orbot is a modified version of the status icon from the Orbot project, which is copyright - 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

+ 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. + The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. The resulting image is released under the GPLv3+ license.

cookie was created by Google. It is released under the Apache License 2.0 and can be downloaded from Material Design Icons. It is unchanged except for layout information like color and size.

The following icons come from the Android Material icon set, which is released under the Apache License 2.0. They are unchanged except for layout @@ -66,6 +66,7 @@

ic_arrow_forward.

ic_bookmark_border.

ic_bug_report.

+

ic_call_to_action.

ic_chrome_reader_mode.

ic_close.

ic_create_new_folder.

@@ -80,6 +81,7 @@

ic_find_in_page.

ic_folder.

ic_folder_special.

+

ic_fullscreen.

ic_home.

ic_import_contacts.

ic_important_devices.

@@ -90,9 +92,11 @@

ic_location_off.

ic_more.

ic_question_answer.

+

ic_refresh.

ic_search.

ic_select_all.

ic_settings.

+

ic_smartphone.

ic_subtitles.

ic_text_fields.

ic_vertical_align_bottom.

@@ -119,7 +123,7 @@

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to - share and change all versions of a program--to make sure it remains free + share and change all versions of a program—to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to @@ -147,16 +151,16 @@ (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

-

For the developers' and authors' protection, the GPL clearly explains - that there is no warranty for this free software. For both users' and - authors' sake, the GPL requires that modified versions be marked as +

For the developers’ and authors’ protection, the GPL clearly explains + that there is no warranty for this free software. For both users’ and + authors’ sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of - protecting users' freedom to change the software. The systematic + protecting users’ freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those @@ -240,7 +244,7 @@

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to - control those activities. However, it does not include the work's + control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source @@ -282,7 +286,7 @@ the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

-

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

+

3. Protecting Users’ Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article @@ -294,13 +298,13 @@ circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or - modification of the work as a means of enforcing, against the work's - users, your or third parties' legal rights to forbid circumvention of + modification of the work as a means of enforcing, against the work’s + users, your or third parties’ legal rights to forbid circumvention of technological measures.

4. Conveying Verbatim Copies.

-

You may convey verbatim copies of the Program's source code as you +

You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any @@ -345,7 +349,7 @@ and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not - used to limit the access or legal rights of the compilation's users + used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

@@ -567,7 +571,7 @@ organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever - licenses to the work the party's predecessor in interest had or could + licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

@@ -584,9 +588,9 @@

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The - work thus licensed is called the contributor's “contributor version”.

+ work thus licensed is called the contributor’s “contributor version”.

-

A contributor's “essential patent claims” are all patent claims +

A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, @@ -597,7 +601,7 @@ this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free - patent license under the contributor's essential patent claims, to + patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

@@ -618,7 +622,7 @@ consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the - covered work in a country, or your recipient's use of the covered work + covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

@@ -649,7 +653,7 @@ any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

-

12. No Surrender of Others' Freedom.

+

12. No Surrender of Others’ Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not @@ -689,7 +693,7 @@ by the Free Software Foundation.

If the Program specifies that a proxy can decide which future - versions of the GNU General Public License can be used, that proxy's + versions of the GNU General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

@@ -782,7 +786,7 @@ certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate - parts of the General Public License. Of course, your program's commands + parts of the General Public License. Of course, your program’s commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, diff --git a/app/src/main/assets/en/images/ic_call_to_action.png b/app/src/main/assets/en/images/ic_call_to_action.png new file mode 100644 index 0000000000000000000000000000000000000000..84c2e372dd4e3c0264f08f45cda6669e0f732e4b GIT binary patch literal 775 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zsKU_vQ3YHM`H2IZjgXgrUFrVN!PgbvDGF4NYLSxchb4 zl@tC6{5M$RLO<_)Ex(D&hG8Eg`?(eA@;l<^Myg+HoGW-|#^s!Q49~OAZJro>V7K6% zp38a54%|Ak((FSHi}^zxGygQduM@VpZKzy6d#C5YJ^qZr4}Q%#zSTzUK<_SgFUB0E z_tm%i+BR_3{3!nz@$lsKUw6CNHiT}E;CfKhFMZJ<>--jx1FdrAixOkjMC-5?EIQts zA))?S%$rf8g|WrBp@2=`9K#_=2McD7bcTmK3UdZj@XklRb%o2DvsdhW-o0l>H$z-W z0Wa?ndqyH0HgzB0zq=2lxNGItDt}&`w^8K4bT;vQcWd;e4m{s=^wRu>e%m~k!z*kr zPdzkQe`?%4nJ zsKs+ z4Tpm_=WidVt_`{Rd_ncx)vs>-oK-!)zIgenUA$I)&;HN<9%!EA$HbxDP=H3XuVt@z zw0xBw@ALW9yhY__*SCG{5B+*Kb6Q>+?}MPw{n7k|&!aw{y>dodVGhF~PQ1j~U8ZkD zx4SL1w}-oGgHk+~toq-d;(zb`+i?H1e8#Eg+x77p0=DApulbJ0kA1!#;UB+g-hYqR z#&7RU`ugEoa_`qKd(Z!$5bj{X*dmNh?14b2(F!(Q!GsHHJ}2!putOGbFcFC|MUtCtZlu zQ7(%nUs)xqD7VzoB$`?!_sem z_%D?d*LDXf^4Xfem>yn%N^6s@#K>Fo$V5sA69CL2{v~96Zp;3)P%p(ZI3?gvYzjLv zIR;>}*;a802bj^3i7{4(lJ{Qt>Y@(-2v0Avd*I=VQM9@m4DbJRaP z(KE#2Ug{R@#QwOkkN8;EE=zy(hXm7KP7#o!aYY@(@L z1EU+^ULUi_nFR;kvdxUIc4Y3-tbB^CTt9KW7oBD~jC!kL?>ueiJh^3(1kndCfbWsU z^3XSsZqs>*^W;@oi!ZoQ7?h*Nzj+(dQ!sHL@M?Dp6^xZQEum%UgP9T=S%q6w^qC+w z@`Yk8J{?;+lt$0uJoIxN>-!VhfG@SZl0E*^x!9~Ml&l!j=Lxk3#26C2O{S5irjGAe z{Z#^loJYpP!r@lTJzp=2sPCL5N2TAB5b`ay@I9k1`s74LOOtBceQUSab+n`{i728P zPml-Bqo0W_p9`-y33}fEjZjUm8Oj^5=+igP>Kxic7}SL^?|OU+s?WK$p}xI0H^S<9nbD@m1ll;&L(9}sV@5E1oWCPr2|Y}6QnPUCuR zxPHmVj39s3t<+H{er@ZBeyB~3v&AjJTxXF)#BX~W0kd57^PtkPb}EN4c#LX1-|N@HD0HK*Z1LN2(h0`jxR+;*HyX8f(n-h!5)URqeV~u!6AHSn^G^BsTM#&C?KuE-du5RCs@5=J%4%R|K=hxFnO)TZ>~8Q zs@!SQh7ndrH0oKKpM2s0mBwgLOunB5hAr#v@f-pTKW>I(@|*6zE>-LVB9L^u)(c}n z?K`0>xYhb>B2i@&MuXDn)lMw>z_|8q;h3V z5}`Z9GoMdeN7`7_jio+*5T5#BWHJ_wg}Cirz4?sC2>`n9e15dqj4WH{7EhEF z-U(Y>@mD`PK^NppnDh6*AjTATHl|8`AzaLa(Jrt zOKytsk+J=DxoyZm@y@kTb>HtD|qH(Z3J`)@P(;SeJw z6UT#!n%^h`2@LA#v35UX6Jjy;VV2>^ZN!Wxk(6XcH|Fkq-T-w;^F^xPiNffQF51(< z2%=@i69*nT-n7DcL^w9#-J_Uv@|4qq(QwH2Yjq3iSHbc8e(CH$#?6`@^%x0jG$xY-;zDl`eUYBgKEf?2Sy>c+VtjAZjaB+Webra z-m&PKHw6~{+YEH4g2e_R7x!}?la<|hjB(`N5hFs_7FujGIwVlvnO+xfoyhIgzop=d zXv3$=ONJCBDqXCAE%p#Gb~)v<+t3h1;>C!+vO!9f8f3q4cer;?=oG%c>SUZ7>Bbya z4ylWAHTkGBlKu?O6}pUyTNn8!Z&g!WhWnKjz|EigA zhwsQelm0MU2>9+j~1?dUBJuJ Kmt5yT&-w?=EPWUN literal 0 HcmV?d00001 diff --git a/app/src/main/assets/en/images/ic_smartphone.png b/app/src/main/assets/en/images/ic_smartphone.png new file mode 100644 index 0000000000000000000000000000000000000000..9704accdcf363cc3f52e20705bbeef23c041674b GIT binary patch literal 864 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zsK;H}N}xph$K#vqy|zqJDh!Npyuzz-WuL2ezG8-? z-aA2=)iP{%bmv`Pd`UL+AD_YL7nbJ17MtCz56FC2oD}g?{eWoA=l{oa3U+2iq%wSN z-CPyEZS^UJb0X(n-MzWW@oGGisR5h7Ifg@$4i?ND=?o8f6y`9t7&jDLUaMcwVfrBX zwYSd=rVUqq3GJ88V(4#BU#oAJsLf-*AkPR_idFw$7hDz{|3Kh-{~FIEFMj^@#rpk=ryrR2{J`f&FS6ercLm1kX*p1=_V2s4 z?@r2><$kZ1@;}Xa|6b)(=>yrf)9?S - derivan de ic_security y de ic_language, which are part of the Android Material icon set and are released under the Apache License 2.0. - The full text of the license is below. Modifications copyright © 2016 Soren Stoutner. The resulting images are released under the GPLv3+ license.

-

orbot is a modified version of the status icon from the Orbot project, which is copyright - 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

+ derivan de ic_security y de ic_language, que son parte del conjunto de iconos Android Material y son liberados bajo la Licencia Apache 2.0. + El texto completo de la licencia se encuentra debajo. Copyright de modificaciones © 2016 Soren Stoutner. Las imágenes resultantes se liberan bajo la + licencia GPLv3+.

+

orbot es una versión modificada del icono de estado del proyecto Orbot, + que tiene copyright 2009-2010 por Nathan Freitas, The Guardian Project. Es liberado bajo la licencia BSD modificada (de 3 cláusulas). + El texto completo de la licencia se encuentra debajo. Copyright de modificaciones © 2017 Soren Stoutner. + La imagen resultante se libera bajo la licencia GPLv3+.

cookie fue creado por Google. Es liberado bajo la licencia Apache 2.0 y puede ser descargado desde Material Design Icons. Está sin cambios, excepto por la información de diseño como el color y el tamaño.

Los siguientes iconos proceden de Android Material icon set, el cual es liberado bajo la licencia Apache 2.0. - Están sin cambios, excepto por la información de diseño como el color y el tamaño. Algunos de ellos se han renombrado para que coincida con su uso en el código. Los iconos originales y los nombres se muestran a continuación.

+ Están sin cambios, excepto por la información de diseño como el color y el tamaño. Algunos de ellos se han renombrado para que coincida con su uso en el código. Los iconos y los nombres originales se muestran a continuación.

ic_add.

ic_arrow_back.

ic_arrow_forward.

ic_bookmark_border.

ic_bug_report.

+

ic_call_to_action.

ic_chrome_reader_mode.

ic_close.

ic_create_new_folder.

@@ -82,6 +85,7 @@

ic_find_in_page.

ic_folder.

ic_folder_special.

+

ic_fullscreen.

ic_home.

ic_import_contacts.

ic_important_devices.

@@ -92,9 +96,11 @@

ic_location_off.

ic_more.

ic_question_answer.

+

ic_refresh.

ic_search.

ic_select_all.

ic_settings.

+

ic_smartphone.

ic_subtitles.

ic_text_fields.

ic_vertical_align_bottom.

@@ -1015,36 +1021,34 @@ limitations under the License.
-

3-Clause BSD License

+

Licencia BSD modificada (de 3 cláusulas)

-

Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met:

+

La redistribución y el uso en las formas de código fuente y binario, con o sin + modificaciones, están permitidos siempre que se cumplan las siguientes condiciones:

    -
  • Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer.
  • +
  • Las redistribuciones del código fuente deben conservar el aviso de copyright + anterior, esta lista de condiciones y el siguiente descargo de responsabilidad.
  • -
  • Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution.
  • +
  • Las redistribuciones en formato binario deben reproducir el aviso de copyright + anterior, esta lista de condiciones y el siguiente descargo de responsabilidad + en la documentación y/u otros materiales suministrados con la distribución.
  • -
  • Neither the names of the copyright owners nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission.
  • +
  • Ni el nombre de los titulares de derechos de autor ni los nombres de sus + colaboradores pueden usarse para apoyar o promocionar productos derivados de + este software sin permiso específico previo y por escrito.
-

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+

ESTE SOFTWARE SE SUMINISTRA POR LOS PROPIETARIOS DEL COPYRIGHT Y COLABORADORES + “COMO ESTÁ” Y CUALQUIER GARANTÍAS EXPRESA O IMPLÍCITA, INCLUYENDO, PERO NO + LIMITADO A, LAS GARANTÍAS IMPLÍCITAS DE COMERCIALIZACIÓN Y APTITUD PARA UN + PROPÓSITO PARTICULAR SON RECHAZADAS. EN NINGÚN CASO LOS PROPIETARIOS DEL COPYRIGHT + Y COLABORADORES SERÁN RESPONSABLES POR NINGÚN DAÑO DIRECTO, INDIRECTO, INCIDENTAL, + ESPECIAL, EJEMPLAR O COSECUENCIAL (INCLUYENDO, PERO NO LIMITADO A, LA ADQUISICIÓN + O SUSTITUCIÓN DE BIENES O SERVICIOS; LA PÉRDIDA DE USO, DE DATOS O DE BENEFICIOS; + O INTERRUPCIÓN DE LA ACTIVIDAD EMPRESARIAL) O POR CUALQUIER TEORÍA DE + RESPONSABILIDAD, YA SEA POR CONTRATO, RESPONSABILIDAD ESTRICTA O AGRAVIO + (INCLUYENDO NEGLIGENCIA O CUALQUIER OTRA CAUSA) QUE SURJA DE CUALQUIER MANERA DEL + USO DE ESTE SOFTWARE, INCLUSO SI SE HA ADVERTIDO DE LA POSIBILIDAD DE TALES DAÑOS.

\ No newline at end of file diff --git a/app/src/main/assets/it/about_licenses.html b/app/src/main/assets/it/about_licenses.html index 2c5c24c8..e960817c 100644 --- a/app/src/main/assets/it/about_licenses.html +++ b/app/src/main/assets/it/about_licenses.html @@ -61,9 +61,9 @@ are derived from ic_security and ic_language, which are part of the Android Material icon set and are released under the Apache License 2.0. The full text of the license is below. Modifications copyright © 2016 Soren Stoutner. The resulting images are released under the GPLv3+ license.

orbot is a modified version of the status icon from the Orbot project, which is copyright - 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

-

cookie was created by Google. It is released under the Apache License 2.0 + 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. + The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. The resulting image is released under the GPLv3+ license.

+

cookie was created by Google. It is released under the Apache License 2.0 and can be downloaded from Material Design Icons. It is unchanged except for layout information like color and size.

The following icons come from the Android Material icon set, which is released under the Apache License 2.0. They are unchanged except for layout information like color and size. Some of them have been renamed to match their use in the code. The original icons and names are shown below.

@@ -72,6 +72,7 @@

ic_arrow_forward.

ic_bookmark_border.

ic_bug_report.

+

ic_call_to_action.

ic_chrome_reader_mode.

ic_close.

ic_create_new_folder.

@@ -86,6 +87,7 @@

ic_find_in_page.

ic_folder.

ic_folder_special.

+

ic_fullscreen.

ic_home.

ic_import_contacts.

ic_important_devices.

@@ -96,9 +98,11 @@

ic_location_off.

ic_more.

ic_question_answer.

+

ic_refresh.

ic_search.

ic_select_all.

ic_settings.

+

ic_smartphone.

ic_subtitles.

ic_text_fields.

ic_vertical_align_bottom.

diff --git a/app/src/main/assets/zh-rTW/about_licenses.html b/app/src/main/assets/zh-rTW/about_licenses.html index d3fb878c..c206459d 100644 --- a/app/src/main/assets/zh-rTW/about_licenses.html +++ b/app/src/main/assets/zh-rTW/about_licenses.html @@ -55,8 +55,8 @@ are derived from ic_security and ic_language, which are part of the Android Material icon set and are released under the Apache License 2.0. The full text of the license is below. Modifications copyright © 2016 Soren Stoutner. The resulting images are released under the GPLv3+ license.

orbot is a modified version of the status icon from the Orbot project, which is copyright - 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

+ 2009-2010 Nathan Freitas, The Guardian Project. It is released under the 3-clause BSD license. + The full text of the license is below. Modifications copyright © 2017 Soren Stoutner. The resulting image is released under the GPLv3+ license.

cookie was created by Google. It is released under the Apache License 2.0 and can be downloaded from Material Design Icons. It is unchanged except for layout information like color and size.

The following icons come from the Android Material icon set, which is released under the Apache License 2.0. They are unchanged except for layout @@ -66,6 +66,7 @@

ic_arrow_forward.

ic_bookmark_border.

ic_bug_report.

+

ic_call_to_action.

ic_chrome_reader_mode.

ic_close.

ic_create_new_folder.

@@ -80,6 +81,7 @@

ic_find_in_page.

ic_folder.

ic_folder_special.

+

ic_fullscreen.

ic_home.

ic_import_contacts.

ic_important_devices.

@@ -90,9 +92,11 @@

ic_location_off.

ic_more.

ic_question_answer.

+

ic_refresh.

ic_search.

ic_select_all.

ic_settings.

+

ic_smartphone.

ic_subtitles.

ic_text_fields.

ic_vertical_align_bottom.

@@ -119,7 +123,7 @@

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to - share and change all versions of a program--to make sure it remains free + share and change all versions of a program—to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to @@ -147,16 +151,16 @@ (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

-

For the developers' and authors' protection, the GPL clearly explains - that there is no warranty for this free software. For both users' and - authors' sake, the GPL requires that modified versions be marked as +

For the developers’ and authors’ protection, the GPL clearly explains + that there is no warranty for this free software. For both users’ and + authors’ sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of - protecting users' freedom to change the software. The systematic + protecting users’ freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those @@ -240,7 +244,7 @@

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to - control those activities. However, it does not include the work's + control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source @@ -282,7 +286,7 @@ the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

-

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

+

3. Protecting Users’ Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article @@ -294,13 +298,13 @@ circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or - modification of the work as a means of enforcing, against the work's - users, your or third parties' legal rights to forbid circumvention of + modification of the work as a means of enforcing, against the work’s + users, your or third parties’ legal rights to forbid circumvention of technological measures.

4. Conveying Verbatim Copies.

-

You may convey verbatim copies of the Program's source code as you +

You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any @@ -345,7 +349,7 @@ and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not - used to limit the access or legal rights of the compilation's users + used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

@@ -567,7 +571,7 @@ organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever - licenses to the work the party's predecessor in interest had or could + licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

@@ -584,9 +588,9 @@

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The - work thus licensed is called the contributor's “contributor version”.

+ work thus licensed is called the contributor’s “contributor version”.

-

A contributor's “essential patent claims” are all patent claims +

A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, @@ -597,7 +601,7 @@ this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free - patent license under the contributor's essential patent claims, to + patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

@@ -618,7 +622,7 @@ consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the - covered work in a country, or your recipient's use of the covered work + covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

@@ -649,7 +653,7 @@ any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

-

12. No Surrender of Others' Freedom.

+

12. No Surrender of Others’ Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not @@ -689,7 +693,7 @@ by the Free Software Foundation.

If the Program specifies that a proxy can decide which future - versions of the GNU General Public License can be used, that proxy's + versions of the GNU General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

@@ -782,7 +786,7 @@ certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate - parts of the General Public License. Of course, your program's commands + parts of the General Public License. Of course, your program’s commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 353a8d16..05625983 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -2154,7 +2154,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false); boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false); boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); - fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false); + fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false); hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false); translucentNavigationBarOnFullscreen = sharedPreferences.getBoolean("translucent_navigation_bar", true); swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh", false); diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index f64a9b5d..dcc54893 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -60,16 +60,19 @@ public class SettingsFragment extends PreferenceFragment { final Preference torSearchCustomURLPreference = findPreference("tor_search_custom_url"); final Preference searchPreference = findPreference("search"); final Preference searchCustomURLPreference = findPreference("search_custom_url"); + final Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode"); final Preference hideSystemBarsPreference = findPreference("hide_system_bars"); final Preference translucentNavigationBarPreference = findPreference("translucent_navigation_bar"); final Preference homepagePreference = findPreference("homepage"); final Preference defaultFontSizePreference = findPreference("default_font_size"); + final Preference swipeToRefreshPreference = findPreference("swipe_to_refresh"); + final Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons"); // Set dependencies. domStoragePreference.setDependency("javascript_enabled"); torHomepagePreference.setDependency("proxy_through_orbot"); torSearchPreference.setDependency("proxy_through_orbot"); - hideSystemBarsPreference.setDependency("enable_full_screen_browsing_mode"); + hideSystemBarsPreference.setDependency("full_screen_browsing_mode"); // Get strings from the preferences. String torSearchString = savedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); @@ -80,6 +83,8 @@ public class SettingsFragment extends PreferenceFragment { boolean firstPartyCookiesEnabledBoolean = savedPreferences.getBoolean("first_party_cookies_enabled", false); boolean thirdPartyCookiesEnabledBoolean = savedPreferences.getBoolean("third_party_cookies_enabled", false); boolean proxyThroughOrbotBoolean = savedPreferences.getBoolean("proxy_through_orbot", false); + boolean fullScreenBrowsingModeBoolean = savedPreferences.getBoolean("full_screen_browsing_mode", false); + boolean hideSystemBarsBoolean = savedPreferences.getBoolean("hide_system_bars", false); // Only enable `thirdPartyCookiesPreference` if `firstPartyCookiesEnabledBoolean` is `true` and API >= 21. thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabledBoolean && (Build.VERSION.SDK_INT >= 21)); @@ -147,8 +152,8 @@ public class SettingsFragment extends PreferenceFragment { searchCustomURLPreference.setEnabled(searchString.equals("Custom URL")); - // Enable `transparent_navigation_bar` only if full screen browsing mode is enabled and `hide_system_bars` is disabled. - translucentNavigationBarPreference.setEnabled(savedPreferences.getBoolean("enable_full_screen_browsing_mode", false) && !savedPreferences.getBoolean("hide_system_bars", false)); + // Enable `translucentNavigationBarPreference` only if full screen browsing mode is enabled and `hide_system_bars` is disabled. + translucentNavigationBarPreference.setEnabled(fullScreenBrowsingModeBoolean && !hideSystemBarsBoolean); // Set the homepage URL as the summary text for the `Homepage` preference when the preference screen is loaded. The default is `https://duckduckgo.com`. @@ -236,6 +241,24 @@ public class SettingsFragment extends PreferenceFragment { proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled); } + // Set the `torSearchPreference` and `torSearchCustomURLPreference` icons. + if (proxyThroughOrbotBoolean) { + // Set the `torHomepagePreference` and `torSearchPreference` icons. + torHomepagePreference.setIcon(R.drawable.home_enabled); + torSearchPreference.setIcon(R.drawable.search_enabled); + + // Set the `torSearchCustomURLPreference` icon. + if (torSearchCustomURLPreference.isEnabled()) { + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled); + } else { + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled); + } + } else { // Proxy through Orbot is disabled. + torHomepagePreference.setIcon(R.drawable.home_ghosted); + torSearchPreference.setIcon(R.drawable.search_ghosted); + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted); + } + // Set the `searchCustomURLPreference` icon. if (searchCustomURLPreference.isEnabled()) { searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled); @@ -243,6 +266,47 @@ public class SettingsFragment extends PreferenceFragment { searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted); } + // Set the full screen browsing mode icons. + if (fullScreenBrowsingModeBoolean) { + // Set the `fullScreenBrowsingModePreference` icon. + fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled); + + if (hideSystemBarsBoolean) { + // Set `hideSystemBarsPreference` to use the enabled icon. + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled); + + // Set `translucentNavigationBarPreference` to use the ghosted icon. + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted); + } else { // `hideSystemBarsBoolean` is false. + // Set `hideSystemBarsPreference` to use the disabled icon. + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled); + + // Set the correct icon for `translucentNavigationBarPreference`. + if (savedPreferences.getBoolean("translucent_navigation_bar", true)) { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled); + } else { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled); + } + } + } else { // `fullScreenBrwosingModeBoolean` is false. + fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled); + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted); + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted); + } + + // Set the `swipeToRefreshPreference` icon. + if (savedPreferences.getBoolean("swipe_to_refresh", false)) { + swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled); + } else { + swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled); + } + + // Set the `displayAdditionalAppBarIconsPreference` icon. + if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) { + displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled); + } else { + displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled); + } // Listen for preference changes. preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @@ -401,11 +465,24 @@ public class SettingsFragment extends PreferenceFragment { // Enable the Tor custom URL search option only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`. torSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorSearchString.equals("Custom URL")); - // Update the icon. + // Update the icons. if (currentProxyThroughOrbot) { + // Set the `proxyThroughOrbotPreference`, `torHomepagePreference`, and `torSearchPreference` icons. proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled); - } else { + torHomepagePreference.setIcon(R.drawable.home_enabled); + torSearchPreference.setIcon(R.drawable.search_enabled); + + // Set the `torSearchCustomURLPreference` icon. + if (torSearchCustomURLPreference.isEnabled()) { + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled); + } else { + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled); + } + } else { // Proxy through Orbot is disabled. proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled); + torHomepagePreference.setIcon(R.drawable.home_ghosted); + torSearchPreference.setIcon(R.drawable.search_ghosted); + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted); } break; @@ -418,17 +495,22 @@ public class SettingsFragment extends PreferenceFragment { // Get the present search string. String presentTorSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); - // Set the summary text for `tor_search`. + // Update the preferences. if (presentTorSearchString.equals("Custom URL")) { - // Use R.string.custom_url, which is translated, instead of the array value, which isn't. + // Use `R.string.custom_url`, which is translated, as the summary instead of the array value, which isn't. torSearchPreference.setSummary(R.string.custom_url); + + // Update `torSearchCustomURLPreference`. + torSearchCustomURLPreference.setEnabled(true); + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled); } else { // Set the array value as the summary text. torSearchPreference.setSummary(presentTorSearchString); - } - // Set the status of `torJavaScriptDisabledSearchCustomURLPreference`. - torSearchCustomURLPreference.setEnabled(presentTorSearchString.equals("Custom URL")); + // Update `torSearchCustomURLPreference`. + torSearchCustomURLPreference.setEnabled(false); + torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled); + } break; case "tor_search_custom_url": @@ -463,14 +545,70 @@ public class SettingsFragment extends PreferenceFragment { searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", "")); break; - case "enable_full_screen_browsing_mode": - // Enable `transparent_navigation_bar` only if full screen browsing mode is enabled and `hide_system_bars` is disabled. - translucentNavigationBarPreference.setEnabled(sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false) && !sharedPreferences.getBoolean("hide_system_bars", false)); + case "full_screen_browsing_mode": + if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) { + // Set `fullScreenBrowsingModePreference` to use the enabled icon. + fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled); + + if (sharedPreferences.getBoolean("hide_system_bars", false)) { + // Set `hideSystemBarsPreference` to use the enabled icon. + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled); + + // Update `translucentNavigationBarPreference`. + translucentNavigationBarPreference.setEnabled(false); + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted); + } else { // `hide_system_bars` is false. + // Set `hideSystemBarsPreference` to use the disabled icon. + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled); + + // Update `translucentNavigationBarPreference`. + translucentNavigationBarPreference.setEnabled(true); + if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled); + } else { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled); + } + } + } else { // `full_screen_browsing_mode` is false. + // Disable `translucentNavigationBarPreference`. + translucentNavigationBarPreference.setEnabled(false); + + // Update the icons. + fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled); + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted); + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted); + } break; case "hide_system_bars": - // Enable `translucentNavigationBarPreference` if `hide_system_bars` is disabled. - translucentNavigationBarPreference.setEnabled(!sharedPreferences.getBoolean("hide_system_bars", false)); + if (sharedPreferences.getBoolean("hide_system_bars", false)) { + // Set `hideSystemBarsPreference` to use the enabled icon. + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled); + + // Update `translucentNavigationBarPreference`. + translucentNavigationBarPreference.setEnabled(false); + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted); + } else { // `hide_system_bars` is false. + // Set `hideSystemBarsPreference` to use the disabled icon. + hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled); + + // Update `translucentNavigationBarPreference`. + translucentNavigationBarPreference.setEnabled(true); + if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled); + } else { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled); + } + } + break; + + case "translucent_navigation_bar": + // Update the icon. + if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled); + } else { + translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled); + } break; case "homepage": @@ -483,6 +621,24 @@ public class SettingsFragment extends PreferenceFragment { defaultFontSizePreference.setSummary(sharedPreferences.getString("default_font_size", "100") + "%%"); break; + case "swipe_to_refresh": + // Update the icon. + if (sharedPreferences.getBoolean("swipe_to_refresh", false)) { + swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled); + } else { + swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled); + } + break; + + case "display_additional_app_bar_icons": + // Update the icon. + if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) { + displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled); + } else { + displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled); + } + break; + default: // If no match, do nothing. break; diff --git a/app/src/main/res/drawable/full_screen_disabled.xml b/app/src/main/res/drawable/full_screen_disabled.xml new file mode 100644 index 00000000..d7d02a37 --- /dev/null +++ b/app/src/main/res/drawable/full_screen_disabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/full_screen_enabled.xml b/app/src/main/res/drawable/full_screen_enabled.xml new file mode 100644 index 00000000..533a5eb2 --- /dev/null +++ b/app/src/main/res/drawable/full_screen_enabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/hide_system_bars_disabled.xml b/app/src/main/res/drawable/hide_system_bars_disabled.xml new file mode 100644 index 00000000..82f5ba16 --- /dev/null +++ b/app/src/main/res/drawable/hide_system_bars_disabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/hide_system_bars_enabled.xml b/app/src/main/res/drawable/hide_system_bars_enabled.xml new file mode 100644 index 00000000..36fb7a61 --- /dev/null +++ b/app/src/main/res/drawable/hide_system_bars_enabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/hide_system_bars_ghosted.xml b/app/src/main/res/drawable/hide_system_bars_ghosted.xml new file mode 100644 index 00000000..59a673b6 --- /dev/null +++ b/app/src/main/res/drawable/hide_system_bars_ghosted.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/home.xml b/app/src/main/res/drawable/home_enabled.xml similarity index 66% rename from app/src/main/res/drawable/home.xml rename to app/src/main/res/drawable/home_enabled.xml index a87c3b75..349e6099 100644 --- a/app/src/main/res/drawable/home.xml +++ b/app/src/main/res/drawable/home_enabled.xml @@ -1,4 +1,4 @@ - + = 21. Then we can use `@color`. --> \ No newline at end of file diff --git a/app/src/main/res/drawable/home_ghosted.xml b/app/src/main/res/drawable/home_ghosted.xml new file mode 100644 index 00000000..44c366c8 --- /dev/null +++ b/app/src/main/res/drawable/home_ghosted.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/more_disabled.xml b/app/src/main/res/drawable/more_disabled.xml new file mode 100644 index 00000000..2484a22d --- /dev/null +++ b/app/src/main/res/drawable/more_disabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/more_enabled.xml b/app/src/main/res/drawable/more_enabled.xml new file mode 100644 index 00000000..458c8d29 --- /dev/null +++ b/app/src/main/res/drawable/more_enabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/refresh_disabled.xml b/app/src/main/res/drawable/refresh_disabled.xml new file mode 100644 index 00000000..b0a3e7b4 --- /dev/null +++ b/app/src/main/res/drawable/refresh_disabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/refresh_enabled.xml b/app/src/main/res/drawable/refresh_enabled.xml new file mode 100644 index 00000000..9d1b023e --- /dev/null +++ b/app/src/main/res/drawable/refresh_enabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/search_custom_url_disabled.xml b/app/src/main/res/drawable/search_custom_url_disabled.xml new file mode 100644 index 00000000..ff0969b9 --- /dev/null +++ b/app/src/main/res/drawable/search_custom_url_disabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/search_ghosted.xml b/app/src/main/res/drawable/search_ghosted.xml new file mode 100644 index 00000000..e078033b --- /dev/null +++ b/app/src/main/res/drawable/search_ghosted.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/translucent_bar_disabled.xml b/app/src/main/res/drawable/translucent_bar_disabled.xml new file mode 100644 index 00000000..395dea04 --- /dev/null +++ b/app/src/main/res/drawable/translucent_bar_disabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/translucent_bar_enabled.xml b/app/src/main/res/drawable/translucent_bar_enabled.xml new file mode 100644 index 00000000..d7b10efc --- /dev/null +++ b/app/src/main/res/drawable/translucent_bar_enabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/translucent_bar_ghosted.xml b/app/src/main/res/drawable/translucent_bar_ghosted.xml new file mode 100644 index 00000000..efa1137d --- /dev/null +++ b/app/src/main/res/drawable/translucent_bar_ghosted.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/user_agent_enabled.xml b/app/src/main/res/drawable/user_agent_enabled.xml deleted file mode 100644 index 35fba81a..00000000 --- a/app/src/main/res/drawable/user_agent_enabled.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/menu/webview_navigation_menu.xml b/app/src/main/res/menu/webview_navigation_menu.xml index 8cac40c3..06599268 100644 --- a/app/src/main/res/menu/webview_navigation_menu.xml +++ b/app/src/main/res/menu/webview_navigation_menu.xml @@ -23,7 +23,7 @@ URL personalizado de búsqueda URL personalizado Pantalla Completa - Habilitar pantalla completa - Doble toque para alternar a modo de navegación de pantalla completa. + Navegación de pantalla completa + Doble toque para alternar a modo de navegación de pantalla completa. Esconder barras del systema Esconder las barras de estado y de navegación en el modo de navegación a pantalla completa. Esto no funciona bien si el teclado es mostrado durante el modo de navegación a pantalla completa. Barra de navegación translúcida diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3d6e76fc..2a811071 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -262,8 +262,8 @@ Ricerca personalizzata URL Personalizzata Schermo intero - Abilita la navigazione a schermo intero - Toccare due volte per avviare la navigazione a schermo intero. + Navigazione a schermo intero + Toccare due volte per avviare la navigazione a schermo intero. Nascondi le barre di sistema Nasconde la barra di stato e la barra di navigazione durante la navigazione a schermo intero. Questa opzione non funziona perfettamente se si visualizza la tastiera durante la navigazione a schermo intero. Barra di navigazione trasparente diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 02f96f0d..aed97ad5 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -264,8 +264,8 @@ Search custom URL Custom URL Full Screen - Enable full screen browsing mode - Double-tap to toggle full screen browsing mode. + Full screen browsing mode + Double-tap to toggle full screen browsing mode. Hide system bars Hide the status and navigation bars in full screen browsing mode. This doesn\'t work well if the keyboard is displayed during full screen browsing mode. Translucent navigation bar diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3552849b..dfff1a27 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -298,10 +298,10 @@ Search custom URL Custom URL Full Screen - Enable full screen browsing mode - Double-tap to toggle full screen browsing mode. + Full screen browsing mode + Double-tap to toggle full screen browsing mode. Hide system bars - Hide the status and navigation bars in full screen browsing mode. This doesn\'t work well if the keyboard is displayed during full screen browsing mode. + Hide the status and navigation bars in full screen browsing mode. This doesn’t work well if the keyboard is displayed during full screen browsing mode. Translucent navigation bar Make the navigation bar translucent in full screen browsing mode. General @@ -328,7 +328,7 @@ 200 Swipe to refresh - Some websites don\'t work well if swipe to refresh is enabled. + Some websites don’t work well if swipe to refresh is enabled. Display additional app bar icons Display icons for toggling cookies, DOM storage, and form data in the app bar if there is room. diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 2263b0c4..194aa4d3 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -141,9 +141,9 @@ android:title="@string/full_screen"> + android:inputType="textUri" + android:icon="@drawable/home_enabled" /> Date: Tue, 23 May 2017 16:28:15 -0700 Subject: [PATCH 05/16] Move `Refresh` to the bottom of the main options menu. https://redmine.stoutner.com/issues/89. --- app/src/main/assets/de/about_licenses.html | 5 +++-- app/src/main/assets/en/about_licenses.html | 5 +++-- app/src/main/assets/es/about_licenses.html | 5 +++-- app/src/main/assets/it/about_licenses.html | 5 +++-- app/src/main/assets/zh-rTW/about_licenses.html | 5 +++-- .../activities/MainWebViewActivity.java | 8 ++++---- app/src/main/res/menu/webview_options_menu.xml | 14 +++++++------- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app/src/main/assets/de/about_licenses.html b/app/src/main/assets/de/about_licenses.html index ddd730db..6b479aea 100644 --- a/app/src/main/assets/de/about_licenses.html +++ b/app/src/main/assets/de/about_licenses.html @@ -48,7 +48,8 @@

Privacy Browser ist copyright © 2015-2017 von Soren Stoutner.

Lizenz

-

Privacy Browser ist veröffentlicht unter der GPLv3+ Lizenz. The full text of the license is below.

+

Privacy Browser ist veröffentlicht unter der GPLv3+ Lizenz. The full text of the license is below. + The source code is available from git.stoutner.com.

Attribute

The list of ad servers used by the ad blocker comes from pgl.yoyo.org. @@ -77,7 +78,7 @@

ic_close.

ic_create_new_folder.

ic_devices_other.

-

ic_download.

+

ic_delete.

ic_dns.

ic_edit.

ic_exit_to_app.

diff --git a/app/src/main/assets/en/about_licenses.html b/app/src/main/assets/en/about_licenses.html index c433ce37..4e9f8f66 100644 --- a/app/src/main/assets/en/about_licenses.html +++ b/app/src/main/assets/en/about_licenses.html @@ -43,7 +43,8 @@

Privacy Browser copyright © 2015-2017 Soren Stoutner.

License

-

Privacy Browser is released under the GPLv3+ license. The full text of the license is below.

+

Privacy Browser is released under the GPLv3+ license. The full text of the license is below. + The source code is available from git.stoutner.com.

Attributions

The list of ad servers used by the ad blocker comes from pgl.yoyo.org. @@ -71,7 +72,7 @@

ic_close.

ic_create_new_folder.

ic_devices_other.

-

ic_download.

+

ic_delete.

ic_dns.

ic_edit.

ic_exit_to_app.

diff --git a/app/src/main/assets/es/about_licenses.html b/app/src/main/assets/es/about_licenses.html index 15727c8d..b34a68f3 100644 --- a/app/src/main/assets/es/about_licenses.html +++ b/app/src/main/assets/es/about_licenses.html @@ -45,7 +45,8 @@

Navegador Privado tiene derechos de autor © 2015-2017 por Soren Stoutner.

Licencia

-

Navegador Privado está liberado bajo la licencia GPLv3+. El texto completo de la licencia se encuentra en la parte inferior de este documento (se deja en el idioma original).

+

Navegador Privado está liberado bajo la licencia GPLv3+. El texto completo de la licencia se encuentra en la parte inferior de este documento (se deja en el idioma original). + The source code is available from git.stoutner.com.

Atribuciones

La lista de servidores publicitarios usados por el bloqueador de anuncios procede de pgl.yoyo.org. @@ -75,7 +76,7 @@

ic_close.

ic_create_new_folder.

ic_devices_other.

-

ic_download.

+

ic_delete.

ic_dns.

ic_edit.

ic_exit_to_app.

diff --git a/app/src/main/assets/it/about_licenses.html b/app/src/main/assets/it/about_licenses.html index e960817c..eeae2d53 100644 --- a/app/src/main/assets/it/about_licenses.html +++ b/app/src/main/assets/it/about_licenses.html @@ -49,7 +49,8 @@ che usa la GNU GPL. Soltanto la versione originale in inglese della GNU GPL fa ciò. Lo scopo di questa traduzione è unicamente quello di aiutare gli utenti di lingua italiana a comprendere la GNU GPL, e pertanto in caso di eventuali discrepanze tra traduzione e versione originale in inglese, prevarrà e sarà unicamente la versione originale ad avere valore legale. - E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini qui riportati.

+ E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini qui riportati. + The source code is available from git.stoutner.com.

Attribuzioni

La lista dei server utilizzata dalla funzionalità di blocco degli annunci è tratta da pgl.yoyo.org. @@ -77,7 +78,7 @@

ic_close.

ic_create_new_folder.

ic_devices_other.

-

ic_download.

+

ic_delete.

ic_dns.

ic_edit.

ic_exit_to_app.

diff --git a/app/src/main/assets/zh-rTW/about_licenses.html b/app/src/main/assets/zh-rTW/about_licenses.html index c206459d..0af91d73 100644 --- a/app/src/main/assets/zh-rTW/about_licenses.html +++ b/app/src/main/assets/zh-rTW/about_licenses.html @@ -43,7 +43,8 @@

Privacy Browser copyright © 2015-2017 Soren Stoutner.

License

-

Privacy Browser is released under the GPLv3+ license. The full text of the license is below.

+

Privacy Browser is released under the GPLv3+ license. The full text of the license is below. + The source code is available from git.stoutner.com.

Attributions

The list of ad servers used by the ad blocker comes from pgl.yoyo.org. @@ -71,7 +72,7 @@

ic_close.

ic_create_new_folder.

ic_devices_other.

-

ic_download.

+

ic_delete.

ic_dns.

ic_edit.

ic_exit_to_app.

diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 05625983..01978f46 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -1277,10 +1277,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation }, 200); return true; - case R.id.refresh: - mainWebView.reload(); - return true; - case R.id.print: // Get a `PrintManager` instance. PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE); @@ -1300,6 +1296,10 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation //Everything else will be handled by `CreateHomeScreenShortcutDialog` and the associated listener below. return true; + case R.id.refresh: + mainWebView.reload(); + return true; + default: // Don't consume the event. return super.onOptionsItemSelected(menuItem); diff --git a/app/src/main/res/menu/webview_options_menu.xml b/app/src/main/res/menu/webview_options_menu.xml index c1fc680a..d2d57432 100644 --- a/app/src/main/res/menu/webview_options_menu.xml +++ b/app/src/main/res/menu/webview_options_menu.xml @@ -146,22 +146,22 @@ android:title="@string/find_on_page" android:orderInCategory="110" app:showAsAction="never|collapseActionView" /> - + -- 2.45.2 From ed0a4234b452924acf1602bee6578a7a84445a85 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Wed, 24 May 2017 21:25:49 -0700 Subject: [PATCH 06/16] Add controls for displaying webpage images. Implements https://redmine.stoutner.com/issues/123. --- app/src/main/assets/de/about_licenses.html | 1 + app/src/main/assets/en/about_licenses.html | 1 + app/src/main/assets/en/images/ic_image.png | Bin 0 -> 1288 bytes app/src/main/assets/es/about_licenses.html | 3 +- app/src/main/assets/it/about_licenses.html | 1 + .../main/assets/zh-rTW/about_licenses.html | 1 + .../activities/DomainSettingsActivity.java | 24 +- .../activities/DomainsActivity.java | 23 +- .../activities/MainWebViewActivity.java | 636 ++++++++++-------- .../activities/SettingsActivity.java | 2 +- .../fragments/DomainSettingsFragment.java | 70 +- .../fragments/SettingsFragment.java | 20 +- .../helpers/DomainsDatabaseHelper.java | 39 +- app/src/main/res/drawable/images_disabled.xml | 18 + app/src/main/res/drawable/images_enabled.xml | 18 + app/src/main/res/layout/domain_settings.xml | 40 +- .../main/res/menu/webview_options_menu.xml | 55 +- app/src/main/res/values/strings.xml | 12 +- app/src/main/res/xml/preferences.xml | 6 + 19 files changed, 604 insertions(+), 366 deletions(-) create mode 100644 app/src/main/assets/en/images/ic_image.png create mode 100644 app/src/main/res/drawable/images_disabled.xml create mode 100644 app/src/main/res/drawable/images_enabled.xml diff --git a/app/src/main/assets/de/about_licenses.html b/app/src/main/assets/de/about_licenses.html index 6b479aea..8f99162a 100644 --- a/app/src/main/assets/de/about_licenses.html +++ b/app/src/main/assets/de/about_licenses.html @@ -90,6 +90,7 @@

ic_folder_special.

ic_fullscreen.

ic_home.

+

ic_image.

ic_import_contacts.

ic_important_devices.

ic_info_outline.

diff --git a/app/src/main/assets/en/about_licenses.html b/app/src/main/assets/en/about_licenses.html index 4e9f8f66..01ebe5d1 100644 --- a/app/src/main/assets/en/about_licenses.html +++ b/app/src/main/assets/en/about_licenses.html @@ -84,6 +84,7 @@

ic_folder_special.

ic_fullscreen.

ic_home.

+

ic_image.

ic_import_contacts.

ic_important_devices.

ic_info_outline.

diff --git a/app/src/main/assets/en/images/ic_image.png b/app/src/main/assets/en/images/ic_image.png new file mode 100644 index 0000000000000000000000000000000000000000..3e4dc0c9d8908c1de3ee600b923887e06df6b996 GIT binary patch literal 1288 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zsKVHUAq>Cy;O)gc=G7MrOnNoJDQtkcV7z; zV0n3I?V?4OPTDWnu|?yeL{eZ&Sc`&P@5;lq6WS-JeV_B$_IY*n{`ulECraw-Dn9L1 ze_QP6f(nj3>+7nOXNzO<^Qo`nxDj2r$8aXYe&*8$!Vmm>d478<>x1M3<{c~3F6A+J zAE-HGxx<2M&7=K^$+`QPy7&4o-sqYj``=fpI-0%jtIgyzu@{$K?zIfOB^B!%`bMwY zui<;+^4?#Q?%p-eoj<)S<)cV}#Ez!e8B6B#KH&He?5SQZ_uR{R1IGc!W;>Ph%1dPV1_1o zp-X?6_H^x&d0l@me$Jgue|c>zW4~83&p5B(^kOfg?(J;j*Y}uf%o{9se!kZb_V#k_ zwSNX5+CT5PQz`G$UB;OW?R2Myz=h4jlaJuR$pU&w}*d4+HID&7aQ5< zeQmIQ@4V{fJ#GjLzGhv|u>QhcueHxC?oaxs#M2KHJAL$=UHklX7U#4+Bs{Cz zvX1@E)|fYMiY*SXiyoW7;4k{d{WVb4>ehL8)81I_>d!h|7^i=K(z34&yT!WiytMpN z_kewIp`G^K9?7+@7|XYc-*|5MhofL`!JPMv)t|N}M(YAaO~t?K|GnSymFK5FTRmfc z>e{+=sBqY$n0qHAl7%Y_OD}R}U1xrmrTZrPQ=CVoTH%~><6|D7o8=0^lLNJ%*tef& z6tC_po>-P|yEc@6$L6>TZ&Ll&u{X$9(rVmOYMPd$-oYFMb-(pO;vd#C&@)i&^i&RaWOjpxxTB2X6O1%lx<~CtF=}J^P)h zKL4a|*|zhCX4*c`D}SW@B>r2ECy1SXNo=}pa!?Tej?*)@TunVc@LKh#-#}*2>qaH9^T(P!5))k0SLkRVCwb%crTje zfjKB0U%kYq!}MXZqx_`h74LPKJ}d>Yo_7NU^_ut?!(Xg3TsoKcK_HhstBxJxv_^lP zUlUEdd0t$9Z?nPe-u$+!mu_oq*nj<`NeNHH@%rLp_pUXnSIzS*c7M6g=VtZfW4Ep~ z9KE;vVT#<3j$ij5iLSiMV7KJZ@w&71TD1ZeuHWx(=40eOaIfoe@5z>TO}R7Q8UD6m j*7|{34!ES;_{V(f$!(?M`g`Mmr51yytDnm{r-UW|=jli6 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/es/about_licenses.html b/app/src/main/assets/es/about_licenses.html index b34a68f3..220c15ee 100644 --- a/app/src/main/assets/es/about_licenses.html +++ b/app/src/main/assets/es/about_licenses.html @@ -46,7 +46,7 @@

Licencia

Navegador Privado está liberado bajo la licencia GPLv3+. El texto completo de la licencia se encuentra en la parte inferior de este documento (se deja en el idioma original). - The source code is available from git.stoutner.com.

+ El código fuente está disponible en git.stoutner.com.

Atribuciones

La lista de servidores publicitarios usados por el bloqueador de anuncios procede de pgl.yoyo.org. @@ -88,6 +88,7 @@

ic_folder_special.

ic_fullscreen.

ic_home.

+

ic_image.

ic_import_contacts.

ic_important_devices.

ic_info_outline.

diff --git a/app/src/main/assets/it/about_licenses.html b/app/src/main/assets/it/about_licenses.html index eeae2d53..2612a65c 100644 --- a/app/src/main/assets/it/about_licenses.html +++ b/app/src/main/assets/it/about_licenses.html @@ -90,6 +90,7 @@

ic_folder_special.

ic_fullscreen.

ic_home.

+

ic_image.

ic_import_contacts.

ic_important_devices.

ic_info_outline.

diff --git a/app/src/main/assets/zh-rTW/about_licenses.html b/app/src/main/assets/zh-rTW/about_licenses.html index 0af91d73..9b32ce20 100644 --- a/app/src/main/assets/zh-rTW/about_licenses.html +++ b/app/src/main/assets/zh-rTW/about_licenses.html @@ -84,6 +84,7 @@

ic_folder_special.

ic_fullscreen.

ic_home.

+

ic_image.

ic_import_contacts.

ic_important_devices.

ic_info_outline.

diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java index ccb444a7..49364db3 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java @@ -22,7 +22,6 @@ package com.stoutner.privacybrowser.activities; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.support.design.widget.BaseTransientBottomBar; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.app.NavUtils; @@ -111,20 +110,22 @@ public class DomainSettingsActivity extends AppCompatActivity { Spinner userAgentSpinner = (Spinner) findViewById(R.id.domain_settings_user_agent_spinner); EditText customUserAgentEditText = (EditText) findViewById(R.id.domain_settings_custom_user_agent_edittext); Spinner fontSizeSpinner = (Spinner) findViewById(R.id.domain_settings_font_size_spinner); + Spinner displayWebpageImagesSpinner = (Spinner) findViewById(R.id.domain_settings_display_webpage_images_spinner); // Extract the data for the domain settings. String domainNameString = domainNameEditText.getText().toString(); - boolean javaScriptEnabled = javaScriptEnabledSwitch.isChecked(); - boolean firstPartyCookiesEnabled = firstPartyCookiesEnabledSwitch.isChecked(); - boolean thirdPartyCookiesEnabled = thirdPartyCookiesEnabledSwitch.isChecked(); - boolean domStorageEnabledEnabled = domStorageEnabledSwitch.isChecked(); - boolean formDataEnabled = formDataEnabledSwitch.isChecked(); - int userAgentPosition = userAgentSpinner.getSelectedItemPosition(); - int fontSizePosition = fontSizeSpinner.getSelectedItemPosition(); + boolean javaScriptEnabledBoolean = javaScriptEnabledSwitch.isChecked(); + boolean firstPartyCookiesEnabledBoolean = firstPartyCookiesEnabledSwitch.isChecked(); + boolean thirdPartyCookiesEnabledBoolean = thirdPartyCookiesEnabledSwitch.isChecked(); + boolean domStorageEnabledEnabledBoolean = domStorageEnabledSwitch.isChecked(); + boolean formDataEnabledBoolean = formDataEnabledSwitch.isChecked(); + int userAgentPositionInt = userAgentSpinner.getSelectedItemPosition(); + int fontSizePositionInt = fontSizeSpinner.getSelectedItemPosition(); + int displayWebpageImagesInt = displayWebpageImagesSpinner.getSelectedItemPosition(); // Get the data for the `Spinners` from the entry values string arrays. - String userAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[userAgentPosition]; - int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.default_font_size_entry_values)[fontSizePosition]); + String userAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[userAgentPositionInt]; + int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.default_font_size_entry_values)[fontSizePositionInt]); // Check to see if we are using a custom user agent. if (userAgentString.equals("Custom user agent")) { @@ -133,7 +134,8 @@ public class DomainSettingsActivity extends AppCompatActivity { } // Save the domain settings. - domainsDatabaseHelper.saveDomain(databaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabledEnabled, formDataEnabled, userAgentString, fontSizeInt); + domainsDatabaseHelper.saveDomain(databaseId, domainNameString, javaScriptEnabledBoolean, firstPartyCookiesEnabledBoolean, thirdPartyCookiesEnabledBoolean, domStorageEnabledEnabledBoolean, formDataEnabledBoolean, userAgentString, fontSizeInt, + displayWebpageImagesInt); // Navigate to `DomainsActivity`. NavUtils.navigateUpFromSameTask(this); diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java index 2500fe9e..320cddb8 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java @@ -187,20 +187,22 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo Spinner userAgentSpinner = (Spinner) findViewById(R.id.domain_settings_user_agent_spinner); EditText customUserAgentEditText = (EditText) findViewById(R.id.domain_settings_custom_user_agent_edittext); Spinner fontSizeSpinner = (Spinner) findViewById(R.id.domain_settings_font_size_spinner); + Spinner displayWebpageImagesSpinner = (Spinner) findViewById(R.id.domain_settings_display_webpage_images_spinner); // Extract the data for the domain settings. String domainNameString = domainNameEditText.getText().toString(); - boolean javaScriptEnabled = javaScriptEnabledSwitch.isChecked(); - boolean firstPartyCookiesEnabled = firstPartyCookiesEnabledSwitch.isChecked(); - boolean thirdPartyCookiesEnabled = thirdPartyCookiesEnabledSwitch.isChecked(); - boolean domStorageEnabledEnabled = domStorageEnabledSwitch.isChecked(); - boolean formDataEnabled = formDataEnabledSwitch.isChecked(); - int userAgentPosition = userAgentSpinner.getSelectedItemPosition(); - int fontSizePosition = fontSizeSpinner.getSelectedItemPosition(); + boolean javaScriptEnabledBoolean = javaScriptEnabledSwitch.isChecked(); + boolean firstPartyCookiesEnabledBoolean = firstPartyCookiesEnabledSwitch.isChecked(); + boolean thirdPartyCookiesEnabledBoolean = thirdPartyCookiesEnabledSwitch.isChecked(); + boolean domStorageEnabledEnabledBoolean = domStorageEnabledSwitch.isChecked(); + boolean formDataEnabledBoolean = formDataEnabledSwitch.isChecked(); + int userAgentPositionInt = userAgentSpinner.getSelectedItemPosition(); + int fontSizePositionInt = fontSizeSpinner.getSelectedItemPosition(); + int displayWebpageImagesInt = displayWebpageImagesSpinner.getSelectedItemPosition(); // Get the data for the `Spinners` from the entry values string arrays. - String userAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[userAgentPosition]; - int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.default_font_size_entry_values)[fontSizePosition]); + String userAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[userAgentPositionInt]; + int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.default_font_size_entry_values)[fontSizePositionInt]); // Check to see if we are using a custom user agent. if (userAgentString.equals("Custom user agent")) { @@ -209,7 +211,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo } // Save the domain settings. - domainsDatabaseHelper.saveDomain(databaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabledEnabled, formDataEnabled, userAgentString, fontSizeInt); + domainsDatabaseHelper.saveDomain(databaseId, domainNameString, javaScriptEnabledBoolean, firstPartyCookiesEnabledBoolean, thirdPartyCookiesEnabledBoolean, domStorageEnabledEnabledBoolean, formDataEnabledBoolean, userAgentString, fontSizeInt, + displayWebpageImagesInt); // Display a `Snackbar`. Snackbar.make(domainsListView, R.string.domain_settings_saved, Snackbar.LENGTH_SHORT).show(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 01978f46..0c80f526 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -138,6 +138,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // `webViewTitle` is public static so it can be accessed from `CreateBookmarkDialog` and `CreateHomeScreenShortcutDialog`. It is also used in `onCreate()`. public static String webViewTitle; + // `displayWebpageImagesBoolean` is public static so it can be accessed from `DomainSettingsFragment`. It is also used in `applyAppSettings` and `applyDomainSettings()`. + public static boolean displayWebpageImagesBoolean; + // `navigatingHistory` is used in `onCreate()`, `onNavigationItemSelected()`, and `applyDomainSettings()`. private boolean navigatingHistory; @@ -151,7 +154,8 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // `rootCoordinatorLayout` is used in `onCreate()` and `applyAppSettings()`. private CoordinatorLayout rootCoordinatorLayout; - // 'mainWebView' is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`, `findNextOnPage()`, `closeFindOnPage()`, and `loadUrlFromTextBox()`. + // `mainWebView` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`, `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()` + // and `setDisplayWebpageImages()`. private WebView mainWebView; // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`. @@ -218,12 +222,21 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // `translucentNavigationBarOnFullscreen` is used in `onCreate()` and `applyAppSettings()`. private boolean translucentNavigationBarOnFullscreen; - // `currentDomainName` is used in `onCreate(), `onNavigationItemSelected()`, and `applyDomainSettings()`. + // `currentDomainName` is used in `onCreate()`, `onNavigationItemSelected()`, and `applyDomainSettings()`. private String currentDomainName; // `waitingForOrbot` is used in `onCreate()` and `applyAppSettings()`. private boolean waitingForOrbot; + // `domainSettingsApplied` is used in `applyDomainSettings()` and `setDisplayWebpageImages()`. + private boolean domainSettingsApplied; + + // `displayWebpageImagesInt` is used in `applyDomainSettings()` and `setDisplayWebpageImages()`. + private int displayWebpageImagesInt; + + // `onTheFlyDisplayImagesSet` is used in `applyDomainSettings()` and `setDisplayWebpageImages()`. + private boolean onTheFlyDisplayImagesSet; + // `waitingForOrbotData` is used in `onCreate()` and `applyAppSettings()`. private String waitingForOrbotHTMLString; @@ -893,6 +906,55 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation } } + @Override + public void onRestart() { + super.onRestart(); + + // Apply the app settings, which may have been changed in `SettingsActivity`. + applyAppSettings(); + + // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step. + updatePrivacyIcons(true); + + // Set the display webpage images mode. + setDisplayWebpageImages(); + + // Reload the webpage to remove images if `setDisplayWebpageImages` has turned them off. + mainWebView.reload(); + } + + // `onResume()` runs after `onStart()`, which runs after `onCreate()` and `onRestart()`. + @Override + public void onResume() { + super.onResume(); + + // Resume JavaScript (if enabled). + mainWebView.resumeTimers(); + + // Resume `mainWebView`. + mainWebView.onResume(); + + // Resume the adView for the free flavor. + if (BuildConfig.FLAVOR.contentEquals("free")) { + BannerAd.resumeAd(adView); + } + } + + @Override + public void onPause() { + // Pause `mainWebView`. + mainWebView.onPause(); + + // Stop all JavaScript. + mainWebView.pauseTimers(); + + // Pause the adView or it will continue to consume resources in the background on the free flavor. + if (BuildConfig.FLAVOR.contentEquals("free")) { + BannerAd.pauseAd(adView); + } + + super.onPause(); + } @Override protected void onNewIntent(Intent intent) { @@ -929,26 +991,26 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation updatePrivacyIcons(false); // Get handles for the menu items. - MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies); - MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies); - MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage); - MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData); + MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies); + MenuItem toggleThirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies); + MenuItem toggleDomStorageMenuItem = menu.findItem(R.id.toggle_dom_storage); + MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data); // Only display third-party cookies if SDK >= 21 - toggleThirdPartyCookies.setVisible(Build.VERSION.SDK_INT >= 21); + toggleThirdPartyCookiesMenuItem.setVisible(Build.VERSION.SDK_INT >= 21); // Get the shared preference values. `this` references the current context. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); // Set the status of the additional app bar icons. The default is `false`. if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) { - toggleFirstPartyCookies.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - toggleDomStorage.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - toggleSaveFormData.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + toggleDomStorageMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + toggleSaveFormDataMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); } else { //Do not display the additional icons. - toggleFirstPartyCookies.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - toggleDomStorage.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - toggleSaveFormData.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); + toggleFirstPartyCookiesMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); + toggleDomStorageMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); + toggleSaveFormDataMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); } return true; @@ -957,35 +1019,35 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation @Override public boolean onPrepareOptionsMenu(Menu menu) { // Get handles for the menu items. - MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies); - MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies); - MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage); - MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData); - MenuItem clearCookies = menu.findItem(R.id.clearCookies); - MenuItem clearFormData = menu.findItem(R.id.clearFormData); + MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies); + MenuItem toggleThirdPartyCookiesMenuItem = menu.findItem(R.id.toggle_third_party_cookies); + MenuItem toggleDomStorageMenuItem = menu.findItem(R.id.toggle_dom_storage); + MenuItem toggleSaveFormDataMenuItem = menu.findItem(R.id.toggle_save_form_data); + MenuItem clearCookiesMenuItem = menu.findItem(R.id.clear_cookies); + MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data); + MenuItem fontSizeMenuItem = menu.findItem(R.id.font_size); + MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images); MenuItem refreshMenuItem = menu.findItem(R.id.refresh); // Set the status of the menu item checkboxes. - toggleFirstPartyCookies.setChecked(firstPartyCookiesEnabled); - toggleThirdPartyCookies.setChecked(thirdPartyCookiesEnabled); - toggleDomStorage.setChecked(domStorageEnabled); - toggleSaveFormData.setChecked(saveFormDataEnabled); + toggleFirstPartyCookiesMenuItem.setChecked(firstPartyCookiesEnabled); + toggleThirdPartyCookiesMenuItem.setChecked(thirdPartyCookiesEnabled); + toggleDomStorageMenuItem.setChecked(domStorageEnabled); + toggleSaveFormDataMenuItem.setChecked(saveFormDataEnabled); + displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically()); // Enable third-party cookies if first-party cookies are enabled. - toggleThirdPartyCookies.setEnabled(firstPartyCookiesEnabled); + toggleThirdPartyCookiesMenuItem.setEnabled(firstPartyCookiesEnabled); // Enable DOM Storage if JavaScript is enabled. - toggleDomStorage.setEnabled(javaScriptEnabled); + toggleDomStorageMenuItem.setEnabled(javaScriptEnabled); // Enable Clear Cookies if there are any. - clearCookies.setEnabled(cookieManager.hasCookies()); + clearCookiesMenuItem.setEnabled(cookieManager.hasCookies()); // Enable Clear Form Data is there is any. WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this); - clearFormData.setEnabled(mainWebViewDatabase.hasFormData()); - - // Only show `Refresh` if `swipeToRefresh` is disabled. - refreshMenuItem.setVisible(!swipeToRefreshEnabled); + clearFormDataMenuItem.setEnabled(mainWebViewDatabase.hasFormData()); // Initialize font size variables. int fontSize = mainWebView.getSettings().getTextZoom(); @@ -996,55 +1058,57 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation switch (fontSize) { case 25: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.twenty_five_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeTwentyFivePercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_twenty_five_percent); break; case 50: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.fifty_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeFiftyPercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_fifty_percent); break; case 75: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.seventy_five_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeSeventyFivePercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_seventy_five_percent); break; case 100: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.one_hundred_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeOneHundredPercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_one_hundred_percent); break; case 125: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.one_hundred_twenty_five_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeOneHundredTwentyFivePercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_one_hundred_twenty_five_percent); break; case 150: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.one_hundred_fifty_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeOneHundredFiftyPercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_one_hundred_fifty_percent); break; case 175: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.one_hundred_seventy_five_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeOneHundredSeventyFivePercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_one_hundred_seventy_five_percent); break; case 200: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.two_hundred_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeTwoHundredPercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_two_hundred_percent); break; default: fontSizeTitle = getResources().getString(R.string.font_size) + " - " + getResources().getString(R.string.one_hundred_percent); - selectedFontSizeMenuItem = menu.findItem(R.id.fontSizeOneHundredPercent); + selectedFontSizeMenuItem = menu.findItem(R.id.font_size_one_hundred_percent); break; } // Set the font size title and select the current size menu item. - MenuItem fontSizeMenuItem = menu.findItem(R.id.fontSize); fontSizeMenuItem.setTitle(fontSizeTitle); selectedFontSizeMenuItem.setChecked(true); + // Only show `Refresh` if `swipeToRefresh` is disabled. + refreshMenuItem.setVisible(!swipeToRefreshEnabled); + // Run all the other default commands. super.onPrepareOptionsMenu(menu); @@ -1062,7 +1126,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Set the commands that relate to the menu entries. switch (menuItemId) { - case R.id.toggleJavaScript: + case R.id.toggle_javascript: // Switch the status of javaScriptEnabled. javaScriptEnabled = !javaScriptEnabled; @@ -1085,7 +1149,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation mainWebView.reload(); return true; - case R.id.toggleFirstPartyCookies: + case R.id.toggle_first_party_cookies: // Switch the status of firstPartyCookiesEnabled. firstPartyCookiesEnabled = !firstPartyCookiesEnabled; @@ -1111,7 +1175,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation mainWebView.reload(); return true; - case R.id.toggleThirdPartyCookies: + case R.id.toggle_third_party_cookies: if (Build.VERSION.SDK_INT >= 21) { // Switch the status of thirdPartyCookiesEnabled. thirdPartyCookiesEnabled = !thirdPartyCookiesEnabled; @@ -1134,7 +1198,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation } // Else do nothing because SDK < 21. return true; - case R.id.toggleDomStorage: + case R.id.toggle_dom_storage: // Switch the status of domStorageEnabled. domStorageEnabled = !domStorageEnabled; @@ -1158,7 +1222,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation mainWebView.reload(); return true; - case R.id.toggleSaveFormData: + case R.id.toggle_save_form_data: // Switch the status of saveFormDataEnabled. saveFormDataEnabled = !saveFormDataEnabled; @@ -1182,7 +1246,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation mainWebView.reload(); return true; - case R.id.clearCookies: + case R.id.clear_cookies: if (Build.VERSION.SDK_INT < 21) { cookieManager.removeAllCookie(); } else { @@ -1191,50 +1255,62 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation Snackbar.make(findViewById(R.id.main_webview), R.string.cookies_deleted, Snackbar.LENGTH_SHORT).show(); return true; - case R.id.clearDomStorage: + case R.id.clear_dom_storage: WebStorage webStorage = WebStorage.getInstance(); webStorage.deleteAllData(); Snackbar.make(findViewById(R.id.main_webview), R.string.dom_storage_deleted, Snackbar.LENGTH_SHORT).show(); return true; - case R.id.clearFormData: + case R.id.clear_form_data: WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this); mainWebViewDatabase.clearFormData(); Snackbar.make(findViewById(R.id.main_webview), R.string.form_data_deleted, Snackbar.LENGTH_SHORT).show(); return true; - case R.id.fontSizeTwentyFivePercent: + case R.id.font_size_twenty_five_percent: mainWebView.getSettings().setTextZoom(25); return true; - case R.id.fontSizeFiftyPercent: + case R.id.font_size_fifty_percent: mainWebView.getSettings().setTextZoom(50); return true; - case R.id.fontSizeSeventyFivePercent: + case R.id.font_size_seventy_five_percent: mainWebView.getSettings().setTextZoom(75); return true; - case R.id.fontSizeOneHundredPercent: + case R.id.font_size_one_hundred_percent: mainWebView.getSettings().setTextZoom(100); return true; - case R.id.fontSizeOneHundredTwentyFivePercent: + case R.id.font_size_one_hundred_twenty_five_percent: mainWebView.getSettings().setTextZoom(125); return true; - case R.id.fontSizeOneHundredFiftyPercent: + case R.id.font_size_one_hundred_fifty_percent: mainWebView.getSettings().setTextZoom(150); return true; - case R.id.fontSizeOneHundredSeventyFivePercent: + case R.id.font_size_one_hundred_seventy_five_percent: mainWebView.getSettings().setTextZoom(175); return true; - case R.id.fontSizeTwoHundredPercent: + case R.id.font_size_two_hundred_percent: mainWebView.getSettings().setTextZoom(200); return true; + case R.id.display_images: + if (mainWebView.getSettings().getLoadsImagesAutomatically()) { // Images are currently loaded automatically. + mainWebView.getSettings().setLoadsImagesAutomatically(false); + mainWebView.reload(); + } else { // Images are not currently loaded automatically. + mainWebView.getSettings().setLoadsImagesAutomatically(true); + } + + // Set `onTheFlyDisplayImagesSet`. + onTheFlyDisplayImagesSet = true; + return true; + case R.id.share: // Setup the share string. String shareString; @@ -1288,7 +1364,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation printManager.print(getResources().getString(R.string.privacy_browser_web_page), printDocumentAdapter, null); return true; - case R.id.addToHomescreen: + case R.id.add_to_homescreen: // Show the `CreateHomeScreenShortcutDialog` `AlertDialog` and name this instance `R.string.create_shortcut`. AppCompatDialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog(); createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getResources().getString(R.string.create_shortcut)); @@ -1832,50 +1908,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation } } - @Override - public void onPause() { - // Pause `mainWebView`. - mainWebView.onPause(); - - // Stop all JavaScript. - mainWebView.pauseTimers(); - - // Pause the adView or it will continue to consume resources in the background on the free flavor. - if (BuildConfig.FLAVOR.contentEquals("free")) { - BannerAd.pauseAd(adView); - } - - super.onPause(); - } - - @Override - public void onResume() { // `onResume()` also runs every time the app starts after `onCreate()` and `onStart()`. - super.onResume(); - - // Resume JavaScript (if enabled). - mainWebView.resumeTimers(); - - // Resume `mainWebView`. - mainWebView.onResume(); - - // Resume the adView for the free flavor. - if (BuildConfig.FLAVOR.contentEquals("free")) { - BannerAd.resumeAd(adView); - } - } - - @Override - public void onRestart() { - super.onRestart(); - - // Apply the settings from shared preferences, which might have been changed in `SettingsActivity`. - applyAppSettings(); - - // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step. - updatePrivacyIcons(true); - - } - private void loadUrlFromTextBox() throws UnsupportedEncodingException { // Get the text from urlTextBox and convert it to a string. trim() removes white spaces from the beginning and end of the string. String unformattedUrlString = urlTextBox.getText().toString().trim(); @@ -1933,6 +1965,176 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation mainWebView.loadUrl(url, customHeaders); } + public void findPreviousOnPage(View view) { + // Go to the previous highlighted phrase on the page. `false` goes backwards instead of forwards. + mainWebView.findNext(false); + } + + public void findNextOnPage(View view) { + // Go to the next highlighted phrase on the page. `true` goes forwards instead of backwards. + mainWebView.findNext(true); + } + + public void closeFindOnPage(View view) { + // Delete the contents of `find_on_page_edittext`. + findOnPageEditText.setText(null); + + // Clear the highlighted phrases. + mainWebView.clearMatches(); + + // Hide the Find on Page `RelativeLayout`. + findOnPageLinearLayout.setVisibility(View.GONE); + + // Show the URL app bar. + supportAppBar.setVisibility(View.VISIBLE); + + // Hide the keyboard so we can see the webpage. `0` indicates no additional flags. + inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); + } + + private void applyAppSettings() { + // Get the shared preference values. `this` references the current context. + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + + // Store the values from `sharedPreferences` in variables. + String homepageString = sharedPreferences.getString("homepage", "https://duckduckgo.com"); + String torHomepageString = sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"); + String torSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); + String torSearchCustomURLString = sharedPreferences.getString("tor_search_custom_url", ""); + String searchString = sharedPreferences.getString("search", "https://duckduckgo.com/html/?q="); + String searchCustomURLString = sharedPreferences.getString("search_custom_url", ""); + adBlockerEnabled = sharedPreferences.getBoolean("block_ads", true); + incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false); + boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false); + boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); + fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false); + hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false); + translucentNavigationBarOnFullscreen = sharedPreferences.getBoolean("translucent_navigation_bar", true); + swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh", false); + displayWebpageImagesBoolean = sharedPreferences.getBoolean("display_webpage_images", true); + + // Set the homepage, search, and proxy options. + if (proxyThroughOrbot) { // Set the Tor options. + // Set `torHomepageString` as `homepage`. + homepage = torHomepageString; + + // If formattedUrlString is null assign the homepage to it. + if (formattedUrlString == null) { + formattedUrlString = homepage; + } + + // Set the search URL. + if (torSearchString.equals("Custom URL")) { // Get the custom URL string. + searchURL = torSearchCustomURLString; + } else { // Use the string from the pre-built list. + searchURL = torSearchString; + } + + // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. + OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); + + // Display a message to the user if we are waiting on Orbot. + if (!orbotStatus.equals("ON")) { + // Set `waitingForOrbot`. + waitingForOrbot = true; + + // Load a waiting page. `null` specifies no encoding, which defaults to ASCII. + mainWebView.loadData(waitingForOrbotHTMLString, "text/html", null); + } + } else { // Set the non-Tor options. + // Set `homepageString` as `homepage`. + homepage = homepageString; + + // If formattedUrlString is null assign the homepage to it. + if (formattedUrlString == null) { + formattedUrlString = homepage; + } + + // Set the search URL. + if (searchString.equals("Custom URL")) { // Get the custom URL string. + searchURL = searchCustomURLString; + } else { // Use the string from the pre-built list. + searchURL = searchString; + } + + // Reset the proxy to default. The host is `""` and the port is `"0"`. + OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); + + // Reset `waitingForOrbot. + waitingForOrbot = false; + } + + // Set swipe to refresh. + swipeRefreshLayout.setEnabled(swipeToRefreshEnabled); + + // Set Do Not Track status. + if (doNotTrackEnabled) { + customHeaders.put("DNT", "1"); + } else { + customHeaders.remove("DNT"); + } + + // Apply the appropriate full screen mode the `SYSTEM_UI` flags. + if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { + if (hideSystemBarsOnFullscreen) { // Hide everything. + // Remove the translucent navigation setting if it is currently flagged. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + + // Remove the translucent status bar overlay. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + // Remove the translucent status bar overlay on the `Drawer Layout`, which is special and needs its own command. + drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + + /* SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen. + * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. + * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically rehides them after they are shown. + */ + rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } else { // Hide everything except the status and navigation bars. + // Add the translucent status flag if it is unset. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + if (translucentNavigationBarOnFullscreen) { + // Set the navigation bar to be translucent. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + } else { + // Set the navigation bar to be black. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + } + } + } else { // Switch to normal viewing mode. + // Reset `inFullScreenBrowsingMode` to `false`. + inFullScreenBrowsingMode = false; + + // Show the `appBar` if `findOnPageLinearLayout` is not visible. + if (findOnPageLinearLayout.getVisibility() == View.GONE) { + appBar.show(); + } + + // Show the `BannerAd` in the free flavor. + if (BuildConfig.FLAVOR.contentEquals("free")) { + // Reload the ad. Because the screen may have rotated, we need to use `reloadAfterRotate`. + BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); + + // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. + adView = findViewById(R.id.adview); + } + + // Remove the translucent navigation bar flag if it is set. + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + + // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + + // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. + rootCoordinatorLayout.setSystemUiVisibility(0); + + // Constrain `rootCoordinatorLayout` inside the status and navigation bars. + rootCoordinatorLayout.setFitsSystemWindows(true); + } + } + // We have to use the deprecated `.getDrawable()` until the minimum API >= 21. @SuppressWarnings("deprecation") private void applyDomainSettings(String url) { @@ -1991,21 +2193,21 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Close `domainNameCursor. domainNameCursor.close(); - // Initialize variables to track if this domain has stored domain settings, and if so, under which name. - boolean hostHasDomainSettings = false; + // Initialize variables to track if domain settings will be applied and, if so, under which name. + domainSettingsApplied = false; String domainNameInDatabase = null; // Check the hostname. if (domainSettingsSet.contains(hostName)) { - hostHasDomainSettings = true; + domainSettingsApplied = true; domainNameInDatabase = hostName; } // If `hostName` is not `null`, check all the subdomains of `hostName` against wildcard domains in `domainCursor`. if (hostName != null) { - while (hostName.contains(".") && !hostHasDomainSettings) { // Stop checking if we run out of `.` or if we already know that `hostHasDomainSettings` is `true`. + while (hostName.contains(".") && !domainSettingsApplied) { // Stop checking if we run out of `.` or if we already know that `domainSettingsApplied` is `true`. if (domainSettingsSet.contains("*." + hostName)) { // Check the host name prepended by `*.`. - hostHasDomainSettings = true; + domainSettingsApplied = true; domainNameInDatabase = "*." + hostName; } @@ -2014,7 +2216,10 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation } } - if (hostHasDomainSettings) { // The url we are loading has custom domain settings. + // Get a handle for the shared preference. `this` references the current context. + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + + if (domainSettingsApplied) { // The url we are loading has custom domain settings. // Get a cursor for the current host and move it to the first position. Cursor currentHostDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase); currentHostDomainSettingsCursor.moveToFirst(); @@ -2025,8 +2230,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation thirdPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1); domStorageEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1); saveFormDataEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1); - String userAgentString = (currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT))); - int fontSize = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE))); + String userAgentString = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT)); + int fontSize = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE)); + displayWebpageImagesInt = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES)); // Close `currentHostDomainSettingsCursor`. currentHostDomainSettingsCursor.close(); @@ -2055,9 +2261,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Set a green background on `urlTextBox` to indicate that custom domain settings are being used. We have to use the deprecated `.getDrawable()` until the minimum API >= 21. urlAppBarRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_green)); } else { // The URL we are loading does not have custom domain settings. Load the defaults. - // Get the shared preference values. `this` references the current context. - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - // Store the values from `sharedPreferences` in variables. javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false); firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false); @@ -2105,6 +2308,10 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Close `domainsDatabaseHelper`. domainsDatabaseHelper.close(); + // Remove the `onTheFlyDisplayImagesSet` flag and set the display webpage images mode. `true` indicates that custom domain settings are applied. + onTheFlyDisplayImagesSet = false; + setDisplayWebpageImages(); + // Update the privacy icons, but only if `mainMenu` has already been populated. if (mainMenu != null) { updatePrivacyIcons(true); @@ -2112,212 +2319,65 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation } } - public void findPreviousOnPage(View view) { - // Go to the previous highlighted phrase on the page. `false` goes backwards instead of forwards. - mainWebView.findNext(false); - } - - public void findNextOnPage(View view) { - // Go to the next highlighted phrase on the page. `true` goes forwards instead of backwards. - mainWebView.findNext(true); - } - - public void closeFindOnPage(View view) { - // Delete the contents of `find_on_page_edittext`. - findOnPageEditText.setText(null); - - // Clear the highlighted phrases. - mainWebView.clearMatches(); - - // Hide the Find on Page `RelativeLayout`. - findOnPageLinearLayout.setVisibility(View.GONE); - - // Show the URL app bar. - supportAppBar.setVisibility(View.VISIBLE); - - // Hide the keyboard so we can see the webpage. `0` indicates no additional flags. - inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); - } - - private void applyAppSettings() { - // Get the shared preference values. `this` references the current context. - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - - // Store the values from `sharedPreferences` in variables. - String homepageString = sharedPreferences.getString("homepage", "https://duckduckgo.com"); - String torHomepageString = sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"); - String torSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); - String torSearchCustomURLString = sharedPreferences.getString("tor_search_custom_url", ""); - String searchString = sharedPreferences.getString("search", "https://duckduckgo.com/html/?q="); - String searchCustomURLString = sharedPreferences.getString("search_custom_url", ""); - adBlockerEnabled = sharedPreferences.getBoolean("block_ads", true); - incognitoModeEnabled = sharedPreferences.getBoolean("incognito_mode", false); - boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false); - boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); - fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false); - hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false); - translucentNavigationBarOnFullscreen = sharedPreferences.getBoolean("translucent_navigation_bar", true); - swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh", false); - - // Set the homepage, search, and proxy options. - if (proxyThroughOrbot) { // Set the Tor options. - // Set `torHomepageString` as `homepage`. - homepage = torHomepageString; - - // If formattedUrlString is null assign the homepage to it. - if (formattedUrlString == null) { - formattedUrlString = homepage; - } - - // Set the search URL. - if (torSearchString.equals("Custom URL")) { // Get the custom URL string. - searchURL = torSearchCustomURLString; - } else { // Use the string from the pre-built list. - searchURL = torSearchString; - } - - // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. - OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); - - // Display a message to the user if we are waiting on Orbot. - if (!orbotStatus.equals("ON")) { - // Set `waitingForOrbot`. - waitingForOrbot = true; - - // Load a waiting page. `null` specifies no encoding, which defaults to ASCII. - mainWebView.loadData(waitingForOrbotHTMLString, "text/html", null); - } - } else { // Set the non-Tor options. - // Set `homepageString` as `homepage`. - homepage = homepageString; - - // If formattedUrlString is null assign the homepage to it. - if (formattedUrlString == null) { - formattedUrlString = homepage; - } - - // Set the search URL. - if (searchString.equals("Custom URL")) { // Get the custom URL string. - searchURL = searchCustomURLString; - } else { // Use the string from the pre-built list. - searchURL = searchString; - } - - // Reset the proxy to default. The host is `""` and the port is `"0"`. - OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); - - // Reset `waitingForOrbot. - waitingForOrbot = false; - } - - // Set swipe to refresh. - swipeRefreshLayout.setEnabled(swipeToRefreshEnabled); - - // Set Do Not Track status. - if (doNotTrackEnabled) { - customHeaders.put("DNT", "1"); - } else { - customHeaders.remove("DNT"); - } - - // Apply the appropriate full screen mode the `SYSTEM_UI` flags. - if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) { - if (hideSystemBarsOnFullscreen) { // Hide everything. - // Remove the translucent navigation setting if it is currently flagged. - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); - - // Remove the translucent status bar overlay. - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - - // Remove the translucent status bar overlay on the `Drawer Layout`, which is special and needs its own command. - drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + private void setDisplayWebpageImages() { + if (!onTheFlyDisplayImagesSet) { + if (domainSettingsApplied) { // Custom domain settings are applied. + switch (displayWebpageImagesInt) { + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT: + mainWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImagesBoolean); + break; - /* SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen. - * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen. - * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically rehides them after they are shown. - */ - rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - } else { // Hide everything except the status and navigation bars. - // Add the translucent status flag if it is unset. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_ENABLED: + mainWebView.getSettings().setLoadsImagesAutomatically(true); + break; - if (translucentNavigationBarOnFullscreen) { - // Set the navigation bar to be translucent. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); - } else { - // Set the navigation bar to be black. - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_DISABLED: + mainWebView.getSettings().setLoadsImagesAutomatically(false); + break; } + } else { // Default settings are applied. + mainWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImagesBoolean); } - } else { // Switch to normal viewing mode. - // Reset `inFullScreenBrowsingMode` to `false`. - inFullScreenBrowsingMode = false; - - // Show the `appBar` if `findOnPageLinearLayout` is not visible. - if (findOnPageLinearLayout.getVisibility() == View.GONE) { - appBar.show(); - } - - // Show the `BannerAd` in the free flavor. - if (BuildConfig.FLAVOR.contentEquals("free")) { - // Reload the ad. Because the screen may have rotated, we need to use `reloadAfterRotate`. - BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); - - // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`. - adView = findViewById(R.id.adview); - } - - // Remove the translucent navigation bar flag if it is set. - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); - - // Add the translucent status flag if it is unset. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - - // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`. - rootCoordinatorLayout.setSystemUiVisibility(0); - - // Constrain `rootCoordinatorLayout` inside the status and navigation bars. - rootCoordinatorLayout.setFitsSystemWindows(true); } } private void updatePrivacyIcons(boolean runInvalidateOptionsMenu) { // Get handles for the icons. - MenuItem privacyIcon = mainMenu.findItem(R.id.toggleJavaScript); - MenuItem firstPartyCookiesIcon = mainMenu.findItem(R.id.toggleFirstPartyCookies); - MenuItem domStorageIcon = mainMenu.findItem(R.id.toggleDomStorage); - MenuItem formDataIcon = mainMenu.findItem(R.id.toggleSaveFormData); + MenuItem privacyIconMenuItem = mainMenu.findItem(R.id.toggle_javascript); + MenuItem firstPartyCookiesIconMenuItem = mainMenu.findItem(R.id.toggle_first_party_cookies); + MenuItem domStorageIconMenuItem = mainMenu.findItem(R.id.toggle_dom_storage); + MenuItem formDataIconMenuItem = mainMenu.findItem(R.id.toggle_save_form_data); // Update `privacyIcon`. if (javaScriptEnabled) { // JavaScript is enabled. - privacyIcon.setIcon(R.drawable.javascript_enabled); + privacyIconMenuItem.setIcon(R.drawable.javascript_enabled); } else if (firstPartyCookiesEnabled) { // JavaScript is disabled but cookies are enabled. - privacyIcon.setIcon(R.drawable.warning); + privacyIconMenuItem.setIcon(R.drawable.warning); } else { // All the dangerous features are disabled. - privacyIcon.setIcon(R.drawable.privacy_mode); + privacyIconMenuItem.setIcon(R.drawable.privacy_mode); } // Update `firstPartyCookiesIcon`. if (firstPartyCookiesEnabled) { // First-party cookies are enabled. - firstPartyCookiesIcon.setIcon(R.drawable.cookies_enabled); + firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_enabled); } else { // First-party cookies are disabled. - firstPartyCookiesIcon.setIcon(R.drawable.cookies_disabled); + firstPartyCookiesIconMenuItem.setIcon(R.drawable.cookies_disabled); } // Update `domStorageIcon`. if (javaScriptEnabled && domStorageEnabled) { // Both JavaScript and DOM storage are enabled. - domStorageIcon.setIcon(R.drawable.dom_storage_enabled); + domStorageIconMenuItem.setIcon(R.drawable.dom_storage_enabled); } else if (javaScriptEnabled) { // JavaScript is enabled but DOM storage is disabled. - domStorageIcon.setIcon(R.drawable.dom_storage_disabled); + domStorageIconMenuItem.setIcon(R.drawable.dom_storage_disabled); } else { // JavaScript is disabled, so DOM storage is ghosted. - domStorageIcon.setIcon(R.drawable.dom_storage_ghosted); + domStorageIconMenuItem.setIcon(R.drawable.dom_storage_ghosted); } // Update `formDataIcon`. if (saveFormDataEnabled) { // Form data is enabled. - formDataIcon.setIcon(R.drawable.form_data_enabled); + formDataIconMenuItem.setIcon(R.drawable.form_data_enabled); } else { // Form data is disabled. - formDataIcon.setIcon(R.drawable.form_data_disabled); + formDataIconMenuItem.setIcon(R.drawable.form_data_disabled); } // `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`. `this` references the current activity. diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java index 9c82f070..075d5ece 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java @@ -21,12 +21,12 @@ package com.stoutner.privacybrowser.activities; import android.os.Bundle; import android.preference.PreferenceFragment; +import android.support.v4.app.NavUtils; import android.support.v7.app.AppCompatActivity; import com.stoutner.privacybrowser.fragments.SettingsFragment; public class SettingsActivity extends AppCompatActivity { - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java index bdd0302d..4416d301 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java @@ -41,6 +41,7 @@ import android.widget.Switch; import android.widget.TextView; import com.stoutner.privacybrowser.R; +import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; public class DomainSettingsFragment extends Fragment { @@ -85,6 +86,8 @@ public class DomainSettingsFragment extends Fragment { final TextView userAgentTextView = (TextView) domainSettingsView.findViewById(R.id.domain_settings_user_agent_textview); final EditText customUserAgentEditText = (EditText) domainSettingsView.findViewById(R.id.domain_settings_custom_user_agent_edittext); Spinner fontSizeSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_font_size_spinner); + final ImageView displayWebpageImagesImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_display_webpage_images_imageview); + Spinner displayWebpageImagesSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_display_webpage_images_spinner); // Initialize the database handler. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. // The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`. @@ -103,20 +106,24 @@ public class DomainSettingsFragment extends Fragment { int formDataEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)); final String currentUserAgentString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT)); int fontSizeInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE)); + int displayImagesInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES)); // Create `ArrayAdapters` for the `Spinners`and their `entry values`. ArrayAdapter userAgentArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entries, android.R.layout.simple_spinner_item); final ArrayAdapter userAgentEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entry_values, android.R.layout.simple_spinner_item); ArrayAdapter fontSizeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.default_font_size_entries, android.R.layout.simple_spinner_item); ArrayAdapter fontSizeEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.default_font_size_entry_values, android.R.layout.simple_spinner_item); + final ArrayAdapter displayImagesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.display_website_images_array, android.R.layout.simple_spinner_item); // Set the drop down style for the `ArrayAdapters`. userAgentArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); fontSizeArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + displayImagesArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Set the `ArrayAdapters` for the `Spinners`. userAgentSpinner.setAdapter(userAgentArrayAdapter); fontSizeSpinner.setAdapter(fontSizeArrayAdapter); + displayWebpageImagesSpinner.setAdapter(displayImagesArrayAdapter); // Set the domain name from the the database cursor. domainNameEditText.setText(domainNameString); @@ -179,16 +186,16 @@ public class DomainSettingsFragment extends Fragment { domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_disabled)); } } else { // JavaScript is disabled. - // Set the status of DOM storage, but disable it. + // Set the checked status of DOM storage. if (domStorageEnabledInt == 1) { // DOM storage is enabled but JavaScript is disabled. domStorageEnabledSwitch.setChecked(true); - domStorageEnabledSwitch.setEnabled(false); - domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_ghosted)); } else { // Both JavaScript and DOM storage are disabled. domStorageEnabledSwitch.setChecked(false); - domStorageEnabledSwitch.setEnabled(false); - domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_ghosted)); } + + // Disable `domStorageEnabledSwitch` and set the icon to be ghosted. + domStorageEnabledSwitch.setEnabled(false); + domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_ghosted)); } // Set the form data status. Once minimum API >= 21 we can use a selector as the tint mode instead of specifying different icons. @@ -246,6 +253,29 @@ public class DomainSettingsFragment extends Fragment { int fontSizeArrayPosition = fontSizeEntryValuesArrayAdapter.getPosition(String.valueOf(fontSizeInt)); fontSizeSpinner.setSelection(fontSizeArrayPosition); + // Set the selected display website images mode. + displayWebpageImagesSpinner.setSelection(displayImagesInt); + + // Set the display website images icon. + switch (displayImagesInt) { + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT: + if (MainWebViewActivity.displayWebpageImagesBoolean) { + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled)); + } else { + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled)); + } + break; + + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_ENABLED: + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled)); + break; + + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_DISABLED: + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled)); + break; + } + + // Set the `javaScriptEnabledSwitch` `OnCheckedChangeListener()`. javaScriptEnabledSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override @@ -389,6 +419,36 @@ public class DomainSettingsFragment extends Fragment { } }); + // Set the `displayImagesSwitch` `onItemClickListener()`. + displayWebpageImagesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + // Update the icon. + switch (position) { + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT: + if (MainWebViewActivity.displayWebpageImagesBoolean) { + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled)); + } else { + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled)); + } + break; + + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_ENABLED: + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled)); + break; + + case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_DISABLED: + displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled)); + break; + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + // Do nothing. + } + }); + return domainSettingsView; } } diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index dcc54893..2ca68461 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -67,6 +67,7 @@ public class SettingsFragment extends PreferenceFragment { final Preference defaultFontSizePreference = findPreference("default_font_size"); final Preference swipeToRefreshPreference = findPreference("swipe_to_refresh"); final Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons"); + final Preference displayWebpageImagesPreference = findPreference("display_webpage_images"); // Set dependencies. domStoragePreference.setDependency("javascript_enabled"); @@ -288,7 +289,7 @@ public class SettingsFragment extends PreferenceFragment { translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled); } } - } else { // `fullScreenBrwosingModeBoolean` is false. + } else { // `fullScreenBrowsingModeBoolean` is false. fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled); hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted); translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted); @@ -308,6 +309,14 @@ public class SettingsFragment extends PreferenceFragment { displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled); } + // Set the `displayWebpageImagesPreference` icon. + if (savedPreferences.getBoolean("display_webpage_images", true)) { + displayWebpageImagesPreference.setIcon(R.drawable.images_enabled); + } else { + displayWebpageImagesPreference.setIcon(R.drawable.images_disabled); + } + + // Listen for preference changes. preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override @@ -639,6 +648,15 @@ public class SettingsFragment extends PreferenceFragment { } break; + case "display_webpage_images": + // Update the icon. + if (sharedPreferences.getBoolean("display_webpage_images", true)) { + displayWebpageImagesPreference.setIcon(R.drawable.images_enabled); + } else { + displayWebpageImagesPreference.setIcon(R.drawable.images_disabled); + } + break; + default: // If no match, do nothing. break; diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java index 0e1448b4..f6bd47ad 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java @@ -26,7 +26,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DomainsDatabaseHelper extends SQLiteOpenHelper { - private static final int SCHEMA_VERSION = 1; + private static final int SCHEMA_VERSION = 2; private static final String DOMAINS_DATABASE = "domains.db"; private static final String DOMAINS_TABLE = "domains"; @@ -39,6 +39,11 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { public static final String ENABLE_FORM_DATA = "enableformdata"; public static final String USER_AGENT = "useragent"; public static final String FONT_SIZE = "fontsize"; + public static final String DISPLAY_IMAGES = "displayimages"; + + public static final int DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT = 0; + public static final int DISPLAY_WEBPAGE_IMAGES_ENABLED = 1; + public static final int DISPLAY_WEBPAGE_IMAGES_DISABLED = 2; // Initialize the database. The lint warnings for the unused parameters are suppressed. public DomainsDatabaseHelper(Context context, @SuppressWarnings("UnusedParameters") String name, SQLiteDatabase.CursorFactory cursorFactory, @SuppressWarnings("UnusedParameters") int version) { @@ -49,15 +54,16 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { public void onCreate(SQLiteDatabase domainsDatabase) { // Setup the SQL string to create the `domains` table. final String CREATE_DOMAINS_TABLE = "CREATE TABLE " + DOMAINS_TABLE + " (" + - _ID + " integer primary key, " + - DOMAIN_NAME + " text, " + - ENABLE_JAVASCRIPT + " boolean, " + - ENABLE_FIRST_PARTY_COOKIES + " boolean, " + - ENABLE_THIRD_PARTY_COOKIES + " boolean, " + - ENABLE_DOM_STORAGE + " boolean, " + - ENABLE_FORM_DATA + " boolean, " + - USER_AGENT + " text, " + - FONT_SIZE + " integer);"; + _ID + " INTEGER PRIMARY KEY, " + + DOMAIN_NAME + " TEXT, " + + ENABLE_JAVASCRIPT + " BOOLEAN, " + + ENABLE_FIRST_PARTY_COOKIES + " BOOLEAN, " + + ENABLE_THIRD_PARTY_COOKIES + " BOOLEAN, " + + ENABLE_DOM_STORAGE + " BOOLEAN, " + + ENABLE_FORM_DATA + " BOOLEAN, " + + USER_AGENT + " TEXT, " + + FONT_SIZE + " INTEGER, " + + DISPLAY_IMAGES + " INTEGER);"; // Create the `domains` table if it doesn't exist. domainsDatabase.execSQL(CREATE_DOMAINS_TABLE); @@ -65,7 +71,13 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase domainsDatabase, int oldVersion, int newVersion) { - // Code for upgrading the database will be added here when the schema version > 1. + // Upgrade `DOMAINS_TABLE`. + switch (oldVersion) { + // Upgrade from `SCHEMA_VERSION` 1. + case 1: + // Add the `DISPLAY_IMAGES` column. + domainsDatabase.execSQL("ALTER TABLE " + DOMAINS_TABLE + " ADD COLUMN " + DISPLAY_IMAGES + " INTEGER"); + } } public Cursor getDomainNameCursorOrderedByDomain() { @@ -132,6 +144,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { domainContentValues.put(ENABLE_FORM_DATA, false); domainContentValues.put(USER_AGENT, "PrivacyBrowser/1.0"); domainContentValues.put(FONT_SIZE, "100"); + domainContentValues.put(DISPLAY_IMAGES, 0); // Get a writable database handle. SQLiteDatabase domainsDatabase = this.getWritableDatabase(); @@ -143,7 +156,8 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { domainsDatabase.close(); } - public void saveDomain(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled, boolean formDataEnabled, String userAgent, int fontSize) { + public void saveDomain(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled, boolean formDataEnabled, String userAgent, int fontSize, + int displayImages) { // Store the domain data in a `ContentValues`. ContentValues domainContentValues = new ContentValues(); @@ -156,6 +170,7 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { domainContentValues.put(ENABLE_FORM_DATA, formDataEnabled); domainContentValues.put(USER_AGENT, userAgent); domainContentValues.put(FONT_SIZE, fontSize); + domainContentValues.put(DISPLAY_IMAGES, displayImages); // Get a writable database handle. SQLiteDatabase domainsDatabase = this.getWritableDatabase(); diff --git a/app/src/main/res/drawable/images_disabled.xml b/app/src/main/res/drawable/images_disabled.xml new file mode 100644 index 00000000..bd8526c0 --- /dev/null +++ b/app/src/main/res/drawable/images_disabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/images_enabled.xml b/app/src/main/res/drawable/images_enabled.xml new file mode 100644 index 00000000..ee3387bc --- /dev/null +++ b/app/src/main/res/drawable/images_enabled.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/layout/domain_settings.xml b/app/src/main/res/layout/domain_settings.xml index 6878c15f..cdda48e8 100644 --- a/app/src/main/res/layout/domain_settings.xml +++ b/app/src/main/res/layout/domain_settings.xml @@ -40,7 +40,7 @@ + android:orientation="vertical" > + android:orientation="horizontal" > + android:orientation="horizontal" > + android:labelFor="@+id/domain_settings_custom_user_agent_edittext" /> + android:textSize="13sp" /> + android:layout_marginBottom="14dp" /> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/webview_options_menu.xml b/app/src/main/res/menu/webview_options_menu.xml index d2d57432..df62da64 100644 --- a/app/src/main/res/menu/webview_options_menu.xml +++ b/app/src/main/res/menu/webview_options_menu.xml @@ -25,59 +25,59 @@ tools:context=".activities.MainWebViewActivity"> @@ -85,49 +85,49 @@ @@ -135,33 +135,40 @@ + + - + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dfff1a27..b7109d2e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -121,10 +121,11 @@ 150% 175% 200% - Find on Page + Display Images Share - Add to Home Screen + Find on Page Print + Add to Home Screen Privacy Browser Web Page Refresh @@ -194,6 +195,11 @@ Domain settings saved Domain deleted *. may be prepended to a domain to include all subdomains (eg. *.stoutner.com) + + System default + Images enabled + Images disabled + Privacy Browser Guide @@ -331,6 +337,8 @@ Some websites don’t work well if swipe to refresh is enabled. Display additional app bar icons Display icons for toggling cookies, DOM storage, and form data in the app bar if there is room. + Display webpage images + Disable to conserve bandwidth. Orbot proxy will not work unless Orbot is installed. diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 194aa4d3..87b2eac2 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -189,5 +189,11 @@ android:title="@string/display_additional_app_bar_icons" android:summary="@string/display_additional_app_bar_icons_summary" android:defaultValue="false" /> + + \ No newline at end of file -- 2.45.2 From 0c865fd72ca80ba5c1452501ea667bbe30b41b2c Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Thu, 25 May 2017 10:45:41 -0700 Subject: [PATCH 07/16] Fix loading of new intents failing due to display images code. --- .../activities/MainWebViewActivity.java | 64 +++++++++++-------- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values-es/strings.xml | 8 +++ app/src/main/res/values-it/strings.xml | 22 +++++-- app/src/main/res/values-zh-rTW/strings.xml | 12 +++- app/src/main/res/values/strings.xml | 4 +- 6 files changed, 75 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 0c80f526..107a9cee 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -205,7 +205,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation private boolean adBlockerEnabled; // `privacyBrowserRuntime` is used in `onCreate()` and `applyAppSettings()`. - Runtime privacyBrowserRuntime; + private Runtime privacyBrowserRuntime; // `incognitoModeEnabled` is used in `onCreate()` and `applyAppSettings()`. private boolean incognitoModeEnabled; @@ -237,6 +237,9 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // `onTheFlyDisplayImagesSet` is used in `applyDomainSettings()` and `setDisplayWebpageImages()`. private boolean onTheFlyDisplayImagesSet; + // `loadingNewIntentBoolean` is used in `onNewIntent()` and `onRestart()`. + private boolean loadingNewIntentBoolean; + // `waitingForOrbotData` is used in `onCreate()` and `applyAppSettings()`. private String waitingForOrbotHTMLString; @@ -906,6 +909,32 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation } } + @Override + protected void onNewIntent(Intent intent) { + // Set `loadingNewIntentBoolean`. + loadingNewIntentBoolean = true; + + // 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); + + if (intent.getData() != null) { + // Get the intent data and convert it to a string. + final Uri intentUriData = intent.getData(); + formattedUrlString = intentUriData.toString(); + } + + // Close the navigation drawer if it is open. + if (drawerLayout.isDrawerVisible(GravityCompat.START)) { + drawerLayout.closeDrawer(GravityCompat.START); + } + + // Load the website. + loadUrl(formattedUrlString); + + // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it. + mainWebView.requestFocus(); + } + @Override public void onRestart() { super.onRestart(); @@ -919,8 +948,14 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Set the display webpage images mode. setDisplayWebpageImages(); - // Reload the webpage to remove images if `setDisplayWebpageImages` has turned them off. - mainWebView.reload(); + // Only reload `mainWebView` if not loading a new intent. + if (!loadingNewIntentBoolean) { + // Reload the webpage to remove images if `setDisplayWebpageImages` has turned them off. + mainWebView.reload(); + } else { + // Reset `loadingNewIntentBoolean`. + loadingNewIntentBoolean = false; + } } // `onResume()` runs after `onStart()`, which runs after `onCreate()` and `onRestart()`. @@ -956,29 +991,6 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation super.onPause(); } - @Override - protected void onNewIntent(Intent intent) { - // 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); - - if (intent.getData() != null) { - // Get the intent data and convert it to a string. - final Uri intentUriData = intent.getData(); - formattedUrlString = intentUriData.toString(); - } - - // Close the navigation drawer if it is open. - if (drawerLayout.isDrawerVisible(GravityCompat.START)) { - drawerLayout.closeDrawer(GravityCompat.START); - } - - // Load the website. - loadUrl(formattedUrlString); - - // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it. - mainWebView.requestFocus(); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 0ab6a131..f6cf1220 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -85,7 +85,7 @@ URL URL: - + Navigationspanel Navigation Startseite @@ -100,7 +100,7 @@ Infos Leeren und verlassen - + JavaScript Erstanbieter-Cookies Drittanbieter-Cookies diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3d19033b..bc3caf9e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -117,6 +117,7 @@ 150% 175% 200% + Mostrar imágenes Buscar en página Compartir Añadir a la ventana de inicio @@ -189,6 +190,11 @@ Configuración de dominio guardada Dominio eliminado *. puede ser añadido a un dominio para incluir todos los subdominios (p.ej. *.stoutner.com) + + Por defecto del sistema + Imágenes habilitadas + Imágenes deshabilitadas + Guía de Navegador Privado @@ -283,6 +289,8 @@ Algunas webs no funcionan bien si la opción deslizar para actualizar está habilitada. Mostrar iconos adicionales en la barra de aplicación Mostrar iconos para alternar entre cookies, almacenamiento DOM, y datos de formulario en la barra de aplicación, si hay espacio. + Mostrar imágenes de la página web + Deshabilitar para conservar ancho de banda. Enviar a través de Orbot no funcionará a menos que se instale Orbot. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 2a811071..3c6a05d4 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -86,7 +86,7 @@ URL URL: - + Menù di navigazione Navigazione Home @@ -101,16 +101,16 @@ Informazioni Elimina dati ed esci - + JavaScript Cookies proprietari Cookies di terze parti - DOM Storage + DOM storage Dati dei moduli - Elimina Cookies - Elimina DOM Storage + Elimina cookies + Elimina DOM storage Elimina dati dei moduli - Dimensione Font + Dimensione font 25% 50% 75% @@ -119,11 +119,12 @@ 150% 175% 200% + Mostra immagini Cerca nella pagina Condividi Aggiungi collegamento Stampa - Pagina Web di Privacy Browser + Pagina web di Privacy Browser Aggiorna @@ -191,6 +192,11 @@ Impostazioni Domini Salvate Dominio Eliminato è possibile anteporre *. a un dominio per includere tutti i sottodomini (es. *.stoutner.com) + + Impostazioni di default + Abilita Immagini + Disabilita Immagini + Guida di Privacy Browser @@ -285,6 +291,8 @@ Alcuni siti non funzionano correttamente se questa opzione è abilitata. Mostra icone addizionali nella barra dell\'applicazione Mostra le icone per l\'abilitazione dei cookies, del DOM storage, e dei dati dei moduli nella barra dell\'applicazione se c\'è spazio disponibile. + Mostra immagini delle pagine web + Disabilita per ridurre il consumo di dati. Il Proxy con Orbot funziona solo se è installato Orbot. diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index aed97ad5..d03678fa 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -88,7 +88,7 @@ URL URL: - + Navigation Drawer Navigation Home @@ -103,7 +103,7 @@ About Clear and Exit - + JavaScript First-Party Cookies Third-Party Cookies @@ -121,6 +121,7 @@ 150% 175% 200% + Display Images Find on Page Share Add to Home Screen @@ -193,6 +194,11 @@ Domain settings saved Domain deleted *. may be prepended to a domain to include all subdomains (eg. *.stoutner.com) + + System default + Images enabled + Images disabled + Privacy Browser Guide @@ -287,6 +293,8 @@ Some websites don\'t work well if swipe to refresh is enabled. Display additional app bar icons Display icons for toggling cookies, DOM storage, and form data in the app bar if there is room. + Display webpage images + Disable to conserve bandwidth. Orbot proxy will not work unless Orbot is installed. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b7109d2e..5d1b86ae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,7 +88,7 @@ URL URL: - + Navigation Drawer Navigation Home @@ -103,7 +103,7 @@ About Clear and Exit - + JavaScript First-Party Cookies Third-Party Cookies -- 2.45.2 From 2cdd895bb2d560cbad438d159a4c264a39eb6eee Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Thu, 25 May 2017 15:34:51 -0700 Subject: [PATCH 08/16] Prepare to release 2.3. --- .idea/misc.xml | 2 +- app/src/main/assets/de/about_changelog.html | 13 ++++ app/src/main/assets/en/about_changelog.html | 13 ++++ app/src/main/assets/es/about_changelog.html | 13 ++++ app/src/main/assets/it/about_changelog.html | 13 ++++ app/src/main/assets/it/about_licenses.html | 65 +++++++++--------- .../main/assets/zh-rTW/about_changelog.html | 13 ++++ .../activities/MainWebViewActivity.java | 7 +- .../04 - Options Menu - de.png | Bin 171438 -> 181013 bytes .../tenInchScreenshots/01 - Domains - de.png | Bin 155075 -> 183112 bytes .../metadata/android/en/changelogs/23.txt | 8 +++ .../en/phoneScreenshots/04 - Options Menu.png | Bin 170762 -> 179794 bytes .../en/tenInchScreenshots/01 - Domains.png | Bin 154697 -> 183637 bytes .../metadata/android/es/changelogs/23.txt | 8 +++ .../04 - Options Menu - es.png | Bin 165661 -> 176065 bytes .../tenInchScreenshots/01 - Domains - es.png | Bin 158302 -> 187940 bytes .../04 - Options Menu - it.png | Bin 169817 -> 177347 bytes .../tenInchScreenshots/01 - Domains - it.png | Bin 150969 -> 180106 bytes 18 files changed, 118 insertions(+), 37 deletions(-) create mode 100644 fastlane/metadata/android/en/changelogs/23.txt create mode 100644 fastlane/metadata/android/es/changelogs/23.txt diff --git a/.idea/misc.xml b/.idea/misc.xml index 95f0f031..1caa1363 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/app/src/main/assets/de/about_changelog.html b/app/src/main/assets/de/about_changelog.html index e26c76fd..52707d7b 100644 --- a/app/src/main/assets/de/about_changelog.html +++ b/app/src/main/assets/de/about_changelog.html @@ -32,6 +32,19 @@ +

2.3 (version code 23)

+

26 May 2017 - minimum API 19, target API 25

+ +

2.2 (version code 22)

27 April 2017 - minimum API 19, target API 25