]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.kt
First wrong button text in View Headers in night theme. https://redmine.stoutner...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / dialogs / HttpAuthenticationDialog.kt
index 7c94fcfbfdd72f52a2df00054dbea60cd0fee0ec..1f2f1f2fc51b42b75d81ff60b5968a9e00a7dfd8 100644 (file)
@@ -1,27 +1,26 @@
 /*
- * Copyright © 2017-2020 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2023 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
  *
- * Privacy Browser is free software: you can redistribute it and/or modify
+ * Privacy Browser Android is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
- * Privacy Browser is distributed in the hope that it will be useful,
+ * Privacy Browser Android is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
  */
+
 package com.stoutner.privacybrowser.dialogs
 
-import android.annotation.SuppressLint
 import android.app.Dialog
 import android.content.DialogInterface
-import android.content.res.Configuration
 import android.os.Bundle
 import android.text.SpannableStringBuilder
 import android.text.Spanned
@@ -41,22 +40,13 @@ import com.stoutner.privacybrowser.R
 import com.stoutner.privacybrowser.activities.MainWebViewActivity
 import com.stoutner.privacybrowser.views.NestedScrollWebView
 
-// Declare the class constants.
+// Define the class constants.
 private const val HOST = "host"
 private const val REALM = "realm"
 private const val WEBVIEW_FRAGMENT_ID = "webview_fragment_id"
 
-class HttpAuthenticationDialog: DialogFragment() {
-    // Define the class variables.
-    private var dismissDialog: Boolean = false
-
-    // Define the class views.
-    private lateinit var usernameEditText: EditText
-    private lateinit var passwordEditText: EditText
-
+class HttpAuthenticationDialog : DialogFragment() {
     companion object {
-        // `@JvmStatic` will no longer be required once all the code has transitioned to Kotlin.  Also, the function can then be moved out of a companion object and just become a package-level function.
-        @JvmStatic
         fun displayDialog(host: String, realm: String, webViewFragmentId: Long): HttpAuthenticationDialog {
             // Create an arguments bundle.
             val argumentsBundle = Bundle()
@@ -77,8 +67,13 @@ class HttpAuthenticationDialog: DialogFragment() {
         }
     }
 
-    // `@SuppressLint("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
-    @SuppressLint("InflateParams")
+    // Define the class variables.
+    private var httpAuthHandler: HttpAuthHandler? = null
+
+    // Declare the class views.
+    private lateinit var usernameEditText: EditText
+    private lateinit var passwordEditText: EditText
+
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         // Get a handle for the arguments.
         val arguments = requireArguments()
@@ -91,10 +86,10 @@ class HttpAuthenticationDialog: DialogFragment() {
         // Try to populate the alert dialog.
         try {  // Getting the WebView tab fragment will fail if Privacy Browser has been restarted.
             // Get the current position of this WebView fragment.
-            val webViewPosition = MainWebViewActivity.webViewPagerAdapter.getPositionForId(webViewFragmentId)
+            val webViewPosition = MainWebViewActivity.webViewStateAdapter!!.getPositionForId(webViewFragmentId)
 
             // Get the WebView tab fragment.
-            val webViewTabFragment = MainWebViewActivity.webViewPagerAdapter.getPageFragment(webViewPosition)
+            val webViewTabFragment = MainWebViewActivity.webViewStateAdapter!!.getPageFragment(webViewPosition)
 
             // Get the fragment view.
             val fragmentView = webViewTabFragment.requireView()
@@ -103,45 +98,35 @@ class HttpAuthenticationDialog: DialogFragment() {
             val nestedScrollWebView = fragmentView.findViewById<NestedScrollWebView>(R.id.nestedscroll_webview)
 
             // Get a handle for the HTTP authentication handler.
-            val httpAuthHandler = nestedScrollWebView.httpAuthHandler
+            httpAuthHandler = nestedScrollWebView.httpAuthHandler
 
             // Use an alert dialog builder to create the alert dialog.
-            val dialogBuilder = AlertDialog.Builder(requireActivity(), R.style.PrivacyBrowserAlertDialog)
-
-            // Get the current theme status.
-            val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+            val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
 
-            // Set the icon according to the theme.
-            if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                dialogBuilder.setIcon(R.drawable.lock_day)
-            } else {
-
-                dialogBuilder.setIcon(R.drawable.lock_night)
-            }
+            // Set the icon.
+            dialogBuilder.setIcon(R.drawable.lock)
 
             // Set the title.
             dialogBuilder.setTitle(R.string.http_authentication)
 
-            // Get the activity's layout inflater.
-            val layoutInflater = requireActivity().layoutInflater
-
-            // Set the layout.  The parent view is `null` because it will be assigned by the alert dialog.
-            dialogBuilder.setView(layoutInflater.inflate(R.layout.http_authentication_dialog, null))
+            // Set the view.
+            dialogBuilder.setView(R.layout.http_authentication_dialog)
 
             // Set the close button listener.
             dialogBuilder.setNegativeButton(R.string.close) { _: DialogInterface?, _: Int ->
-                // Cancel the HTTP authentication request.
-                httpAuthHandler.cancel()
+                if (httpAuthHandler != null) {
+                    // Cancel the HTTP authentication request.
+                    httpAuthHandler!!.cancel()
 
-                // Reset the HTTP authentication handler.
-                nestedScrollWebView.resetHttpAuthHandler()
-            }// Set the proceed button listener.
+                    // Reset the HTTP authentication handler.
+                    nestedScrollWebView.resetHttpAuthHandler()
+                }
+            }
+
+            // Set the proceed button listener.
             dialogBuilder.setPositiveButton(R.string.proceed) { _: DialogInterface?, _: Int ->
                 // Send the login information
-                login(httpAuthHandler)
-
-                // Reset the HTTP authentication handler.
-                nestedScrollWebView.resetHttpAuthHandler()
+                login(httpAuthHandler, nestedScrollWebView)
             }
 
             // Create an alert dialog from the alert dialog builder.
@@ -151,7 +136,7 @@ class HttpAuthenticationDialog: DialogFragment() {
             val dialogWindow = alertDialog.window!!
 
             // Get a handle for the shared preferences.
-            val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
+            val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
 
             // Get the screenshot preference.
             val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
@@ -177,20 +162,11 @@ class HttpAuthenticationDialog: DialogFragment() {
             realmTextView.text = httpAuthRealm
 
             // Initialize the host label and the spannable string builder.
-            val hostLabel = getString(R.string.host) + "  "
+            val hostLabel = getString(R.string.host)
             val hostStringBuilder = SpannableStringBuilder(hostLabel + httpAuthHost)
 
-            // Create a blue foreground color span.
-            val blueColorSpan: ForegroundColorSpan
-
-            // Set the blue color span according to the theme.  The deprecated `getColor()` must be used until API >= 23.
-            blueColorSpan = if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-                @Suppress("DEPRECATION")
-                ForegroundColorSpan(resources.getColor(R.color.blue_700))
-            } else {
-                @Suppress("DEPRECATION")
-                ForegroundColorSpan(resources.getColor(R.color.violet_500))
-            }
+            // Set the blue color span.
+            val blueColorSpan = ForegroundColorSpan(requireContext().getColor(R.color.blue_text))
 
             // Setup the span to display the host name in blue.  `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
             hostStringBuilder.setSpan(blueColorSpan, hostLabel.length, hostStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
@@ -203,7 +179,7 @@ class HttpAuthenticationDialog: DialogFragment() {
                 // Check the key code and event.
                 if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN) {  // The enter key was pressed.
                     // Send the login information.
-                    login(httpAuthHandler)
+                    login(httpAuthHandler, nestedScrollWebView)
 
                     // Manually dismiss the alert dialog.
                     alertDialog.dismiss()
@@ -220,7 +196,7 @@ class HttpAuthenticationDialog: DialogFragment() {
                 // Check the key code and event.
                 if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN) {  // The enter key was pressed.
                     // Send the login information.
-                    login(httpAuthHandler)
+                    login(httpAuthHandler, nestedScrollWebView)
 
                     // Manually dismiss the alert dialog.
                     alertDialog.dismiss()
@@ -235,32 +211,34 @@ class HttpAuthenticationDialog: DialogFragment() {
             // Return the alert dialog.
             return alertDialog
         } catch (exception: Exception) {  // Privacy Browser was restarted and the HTTP auth handler no longer exists.
-            // Use an alert dialog builder to create an empty alert dialog.
-            val dialogBuilder = AlertDialog.Builder(requireActivity(), R.style.PrivacyBrowserAlertDialog)
+            // Dismiss this new instance of the dialog as soon as it is displayed.
+            dismiss()
 
-            // Create an empty alert dialog from the alert dialog builder.
-            val alertDialog = dialogBuilder.create()
-
-            // Set the flag to dismiss the dialog as soon as it is resumed.
-            dismissDialog = true
+            // Use an alert dialog builder to create an empty alert dialog.
+            val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
 
             // Return the alert dialog.
-            return alertDialog
+            return dialogBuilder.create()
         }
     }
 
-    override fun onResume() {
-        // Run the default command.
-        super.onResume()
+    override fun onSaveInstanceState(outState: Bundle) {
+        // Run the default commands.
+        super.onSaveInstanceState(outState)
 
-        // Dismiss the alert dialog if the activity was restarted and the HTTP auth handler no longer exists.
-        if (dismissDialog) {
-            dialog!!.dismiss()
-        }
+        // Cancel the request if the SSL error handler is not null.  This resets the WebView so it is not waiting on a response to the error handler if it is restarted in the background.
+        // Otherwise, after restart, the dialog is no longer displayed, but the error handler is still pending and there is no way to cause the dialog to redisplay for that URL in that tab.
+        if (httpAuthHandler != null)
+            httpAuthHandler!!.cancel()
     }
 
-    private fun login(httpAuthHandler: HttpAuthHandler) {
-        // Send the login information.
-        httpAuthHandler.proceed(usernameEditText.text.toString(), passwordEditText.text.toString())
+    private fun login(httpAuthHandler: HttpAuthHandler?, nestedScrollWebView: NestedScrollWebView) {
+        if (httpAuthHandler != null) {
+            // Send the login information.
+            httpAuthHandler.proceed(usernameEditText.text.toString(), passwordEditText.text.toString())
+
+            // Reset the HTTP authentication handler.
+            nestedScrollWebView.resetHttpAuthHandler()
+        }
     }
-}
\ No newline at end of file
+}