From a4ec41c79f5050006fd4c8dd6454f3ec8a7f99ab Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Thu, 27 Aug 2020 08:18:50 -0700 Subject: [PATCH] Fix app initialization when the theme is set to the opposite of the OS theme. https://redmine.stoutner.com/issues/605 --- app/build.gradle | 2 +- .../activities/MainWebViewActivity.java | 45 +++++++++++++------ .../activities/RequestsActivity.java | 15 ++++--- .../adapters/RequestsArrayAdapter.java | 27 ++++------- .../asynctasks/PopulateBlocklists.java | 41 +++++++++++++++++ .../res/layout/requests_item_linearlayout.xml | 2 + .../metadata/android/it-IT/changelogs/50.txt | 18 ++++---- 7 files changed, 103 insertions(+), 47 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ce410bde..d5a734d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -87,7 +87,7 @@ dependencies { implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.viewpager:viewpager:1.0.0' - implementation 'androidx.webkit:webkit:1.2.0' + implementation 'androidx.webkit:webkit:1.3.0' // Include the Kotlin standard libraries implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72" 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 14a2264e..b2d9afa3 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -46,6 +46,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.http.SslCertificate; import android.net.http.SslError; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -177,7 +178,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook PinnedMismatchDialog.PinnedMismatchListener, PopulateBlocklists.PopulateBlocklistsListener, SaveDialog.SaveWebpageListener, StoragePermissionDialog.StoragePermissionDialogListener, UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener { - // The executor service handles background tasks. It is accessed from `ViewSourceActivity`. TODO. Change the number of threads, or create a single thread executor. + // The executor service handles background tasks. It is accessed from `ViewSourceActivity`. public static ExecutorService executorService = Executors.newFixedThreadPool(4); // `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`, `onResume()`, and `applyProxy()`. @@ -239,6 +240,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook private TabLayout tabLayout; private ViewPager webViewPager; + // Define the class variables. + @SuppressWarnings("rawtypes") + AsyncTask populateBlocklists; + // The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`, // `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxy()`, and `applyDomainSettings()`. private NestedScrollWebView currentWebView; @@ -440,7 +445,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook applyAppSettings(); // Populate the blocklists. - new PopulateBlocklists(this, this).execute(); + populateBlocklists = new PopulateBlocklists(this, this).execute(); } @Override @@ -730,6 +735,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook bookmarksDatabaseHelper.close(); } + // Stop populating the blocklists if the AsyncTask is running in the background. + if (populateBlocklists != null) { + populateBlocklists.cancel(true); + } + // Run the default commands. super.onDestroy(); } @@ -3374,7 +3384,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook tab.select(); }; - // Select the tab layout after 150 milliseconds, which leaves enough time for a new tab to be inflated. + // Select the tab layout after 150 milliseconds, which leaves enough time for a new tab to be inflated. TODO. selectTabHandler.postDelayed(selectTabRunnable, 150); } } @@ -3940,9 +3950,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook String defaultFontSizeString = sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)); String defaultUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value)); boolean defaultSwipeToRefresh = sharedPreferences.getBoolean("swipe_to_refresh", true); + String webViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value)); boolean wideViewport = sharedPreferences.getBoolean("wide_viewport", true); boolean displayWebpageImages = sharedPreferences.getBoolean("display_webpage_images", true); + // Get the WebView theme entry values string array. + String[] webViewThemeEntryValuesStringArray = getResources().getStringArray(R.array.webview_theme_entry_values); + // Get a handle for the cookie manager. CookieManager cookieManager = CookieManager.getInstance(); @@ -4141,16 +4155,25 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set the WebView theme. switch (webViewThemeInt) { case DomainsDatabaseHelper.SYSTEM_DEFAULT: - // // Ge the current system theme status. - int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - - // Set the WebView theme according to the current system theme status. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { // The system is in day mode. + // Set the WebView theme. A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant. + if (webViewTheme.equals(webViewThemeEntryValuesStringArray[1])) { // The light theme is selected. // Turn off the WebView dark mode. WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF); - } else { // The system is in night mode. + } else if (webViewTheme.equals(webViewThemeEntryValuesStringArray[2])) { // The dark theme is selected. // Turn on the WebView dark mode. WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON); + } else { // The system default theme is selected. + // Get the current system theme status. + int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + + // Set the WebView theme according to the current system theme status. + if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { // The system is in day mode. + // Turn off the WebView dark mode. + WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_OFF); + } else { // The system is in night mode. + // Turn on the WebView dark mode. + WebSettingsCompat.setForceDark(nestedScrollWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON); + } } break; @@ -4219,7 +4242,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRALIST, sharedPreferences.getBoolean("ultralist", true)); nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRAPRIVACY, sharedPreferences.getBoolean("ultraprivacy", true)); nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, sharedPreferences.getBoolean("block_all_third_party_requests", false)); - String webViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value)); // Apply the default first-party cookie setting. cookieManager.setAcceptCookie(nestedScrollWebView.getAcceptFirstPartyCookies()); @@ -4283,9 +4305,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[userAgentArrayPosition]); } - // Get the WebView theme entry values string array. - String[] webViewThemeEntryValuesStringArray = getResources().getStringArray(R.array.webview_theme_entry_values); - // Apply the WebView theme if supported by the installed WebView. if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { // Set the WebView theme. A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant. diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java index eb6fb4fe..0b9be790 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java @@ -175,6 +175,9 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi Spinner appBarSpinner = findViewById(R.id.spinner); appBarSpinner.setAdapter(spinnerCursorAdapter); + // Get a handle for the context. + Context context = this; + // Handle clicks on the spinner dropdown. appBarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override @@ -182,7 +185,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi switch ((int) id) { case 0: // All requests. // Get an adapter for all the request. - ArrayAdapter allResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allResourceRequests); + ArrayAdapter allResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allResourceRequests); // Display the adapter in the list view. requestsListView.setAdapter(allResourceRequestsArrayAdapter); @@ -190,7 +193,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi case 1: // Default requests. // Get an adapter for the default requests. - ArrayAdapter defaultResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), defaultResourceRequests); + ArrayAdapter defaultResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, defaultResourceRequests); // Display the adapter in the list view. requestsListView.setAdapter(defaultResourceRequestsArrayAdapter); @@ -198,7 +201,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi case 2: // Allowed requests. // Get an adapter for the allowed requests. - ArrayAdapter allowedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allowedResourceRequests); + ArrayAdapter allowedResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allowedResourceRequests); // Display the adapter in the list view. requestsListView.setAdapter(allowedResourceRequestsArrayAdapter); @@ -206,7 +209,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi case 3: // Third-party requests. // Get an adapter for the third-party requests. - ArrayAdapter thirdPartyResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), thirdPartyResourceRequests); + ArrayAdapter thirdPartyResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, thirdPartyResourceRequests); //Display the adapter in the list view. requestsListView.setAdapter(thirdPartyResourceRequestsArrayAdapter); @@ -214,7 +217,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi case 4: // Blocked requests. // Get an adapter fo the blocked requests. - ArrayAdapter blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), blockedResourceRequests); + ArrayAdapter blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, blockedResourceRequests); // Display the adapter in the list view. requestsListView.setAdapter(blockedResourceRequestsArrayAdapter); @@ -229,7 +232,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi }); // Create an array adapter with the list of the resource requests. - ArrayAdapter resourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allResourceRequests); + ArrayAdapter resourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allResourceRequests); // Populate the list view with the resource requests adapter. requestsListView.setAdapter(resourceRequestsArrayAdapter); diff --git a/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java b/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java index fcccba48..49634bae 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java +++ b/app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java @@ -90,10 +90,10 @@ public class RequestsArrayAdapter extends ArrayAdapter { dispositionTextView.setText(requestAllowed); // Set the background color. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) { - linearLayout.setBackgroundColor(context.getResources().getColor(R.color.blue_700_50)); - } else { + if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { linearLayout.setBackgroundColor(context.getResources().getColor(R.color.blue_100)); + } else { + linearLayout.setBackgroundColor(context.getResources().getColor(R.color.blue_700_50)); } break; @@ -105,10 +105,10 @@ public class RequestsArrayAdapter extends ArrayAdapter { dispositionTextView.setText(requestThirdParty); // Set the background color. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) { - linearLayout.setBackgroundColor(context.getResources().getColor(R.color.yellow_700_50)); - } else { + if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { linearLayout.setBackgroundColor(context.getResources().getColor(R.color.yellow_100)); + } else { + linearLayout.setBackgroundColor(context.getResources().getColor(R.color.yellow_700_50)); } break; @@ -121,10 +121,10 @@ public class RequestsArrayAdapter extends ArrayAdapter { dispositionTextView.setText(requestBlocked); // Set the background color. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) { - linearLayout.setBackgroundColor(context.getResources().getColor(R.color.red_700_40)); - } else { + if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { linearLayout.setBackgroundColor(context.getResources().getColor(R.color.red_100)); + } else { + linearLayout.setBackgroundColor(context.getResources().getColor(R.color.red_700_40)); } break; } @@ -132,15 +132,6 @@ public class RequestsArrayAdapter extends ArrayAdapter { // Set the URL text. urlTextView.setText(entryStringArray[1]); - // Set the text color. For some unexplained reason, `android:textColor="?android:textColorPrimary"` doesn't work in the layout file. Probably some bug relating to array adapters. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) { - dispositionTextView.setTextColor(context.getResources().getColor(R.color.gray_200)); - urlTextView.setTextColor(context.getResources().getColor(R.color.gray_200)); - } else { - dispositionTextView.setTextColor(context.getResources().getColor(R.color.black)); - urlTextView.setTextColor(context.getResources().getColor(R.color.black)); - } - // Return the modified view. return view; } diff --git a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/PopulateBlocklists.java b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/PopulateBlocklists.java index 75306368..4474285f 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/PopulateBlocklists.java +++ b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/PopulateBlocklists.java @@ -88,6 +88,11 @@ public class PopulateBlocklists extends AsyncTask>> doInBackground(Void... none) { + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + // Get a handle for the context. Context context = contextWeakReference.get(); @@ -105,6 +110,11 @@ public class PopulateBlocklists extends AsyncTask> easyList = blocklistHelper.parseBlocklist(context.getAssets(), "blocklists/easylist.txt"); + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + // Update the progress. publishProgress(context.getString(R.string.loading_easyprivacy)); @@ -112,6 +122,12 @@ public class PopulateBlocklists extends AsyncTask> easyPrivacy = blocklistHelper.parseBlocklist(context.getAssets(), "blocklists/easyprivacy.txt"); + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + + // Update the progress. publishProgress(context.getString(R.string.loading_fanboys_annoyance_list)); @@ -119,6 +135,12 @@ public class PopulateBlocklists extends AsyncTask> fanboysAnnoyanceList = blocklistHelper.parseBlocklist(context.getAssets(), "blocklists/fanboy-annoyance.txt"); + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + + // Update the progress. publishProgress(context.getString(R.string.loading_fanboys_social_blocking_list)); @@ -126,6 +148,12 @@ public class PopulateBlocklists extends AsyncTask> fanboysSocialList = blocklistHelper.parseBlocklist(context.getAssets(), "blocklists/fanboy-social.txt"); + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + + // Update the progress. publishProgress(context.getString(R.string.loading_ultralist)); @@ -133,12 +161,25 @@ public class PopulateBlocklists extends AsyncTask> ultraList = blocklistHelper.parseBlocklist(context.getAssets(), "blocklists/ultralist.txt"); + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + + + // Update the progress. publishProgress(context.getString(R.string.loading_ultraprivacy)); // Populate UltraPrivacy. ArrayList> ultraPrivacy = blocklistHelper.parseBlocklist(context.getAssets(), "blocklists/ultraprivacy.txt"); + // Exit the AsyncTask if the app has been restarted. + if (isCancelled()) { + return null; + } + + // Populate the combined array list. combinedBlocklists.add(easyList); diff --git a/app/src/main/res/layout/requests_item_linearlayout.xml b/app/src/main/res/layout/requests_item_linearlayout.xml index aacdca0e..c1faead8 100644 --- a/app/src/main/res/layout/requests_item_linearlayout.xml +++ b/app/src/main/res/layout/requests_item_linearlayout.xml @@ -30,6 +30,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="10dp" + android:textColor="?android:attr/textColorPrimary" android:textSize="16sp" /> diff --git a/fastlane/metadata/android/it-IT/changelogs/50.txt b/fastlane/metadata/android/it-IT/changelogs/50.txt index 3595a6ea..ea439eb6 100644 --- a/fastlane/metadata/android/it-IT/changelogs/50.txt +++ b/fastlane/metadata/android/it-IT/changelogs/50.txt @@ -1,12 +1,12 @@ -• Implement Android’s relatively new Day/Night theme. -• Switch to using WebView relatively new built-in dark theme. -• Save and restore the state if Privacy Browser is restarted in the background by the OS. -• Use the Content-Disposition header to get file names for downloads. -• Fix uploading files to some sites. -• Add Mojeek and remove Qwant and Searx from the list of search engines. -• Fix a bug that sometimes caused swipe-to-refresh to operate even when disabled. -• Reorder the context menus. -• Apply custom headers to links loaded from the WebView. +• Implementazione del relativamente nuovo tema Giorno e Notte di Android. +• Passaggio all'utilizzo del relativamente nuovo tema scuro nativo di Webview. +• Salvataggio e ripristino dello stato nel caso in cui Privacy Browser venga riavviato in background dal sistema operativo. +• Utilizzo del "Content-Disposition header" per ottenere i nomi dei file nei download. +• Sistemazione dell'upload dei file verso alcuni siti web. +• Aggiunta di Mojeek ed eliminazione di Qwant e Searx dalla lista dei motori di ricerca. +• Correzione di un baco che talvolta provocava il funzionamento dello swipe per aggiornare la pagina anche se disabilitato. +• Riordino dei menu contestuali. +• Applicazione di intestazioni personalizzate ai collegamenti caricati da Webview. • Aggiornamento della traduzione Italiana fornita da Francesco Buratti. • Aggiornamento della traduzione Francese fornita da Kévin LE FLOHIC. • Aggiornamento della traduzione in Russo. -- 2.45.2