]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/commitdiff
Colorize the logcat. https://redmine.stoutner.com/issues/378
authorSoren Stoutner <soren@stoutner.com>
Sat, 30 Mar 2024 00:19:01 +0000 (17:19 -0700)
committerSoren Stoutner <soren@stoutner.com>
Sat, 30 Mar 2024 00:19:01 +0000 (17:19 -0700)
18 files changed:
app/src/main/assets/css/theme.css
app/src/main/assets/de/guide_local_storage.html
app/src/main/assets/en/guide_local_storage.html
app/src/main/assets/en/guide_tracking_ids.html
app/src/main/assets/en/guide_user_agent.html
app/src/main/assets/es/guide_local_storage.html
app/src/main/assets/fr/guide_local_storage.html
app/src/main/assets/it/guide_local_storage.html
app/src/main/assets/pt-rBR/guide_local_storage.html
app/src/main/assets/ru/guide_local_storage.html
app/src/main/assets/tr/guide_local_storage.html
app/src/main/assets/zh-rCN/guide_local_storage.html
app/src/main/java/com/stoutner/privacybrowser/activities/GuideActivity.kt
app/src/main/java/com/stoutner/privacybrowser/activities/LogcatActivity.kt
app/src/main/java/com/stoutner/privacybrowser/backgroundtasks/GetHeadersBackgroundTask.kt
app/src/main/java/com/stoutner/privacybrowser/fragments/GuideWebViewFragment.kt
app/src/main/res/layout/logcat_bottom_appbar.xml
app/src/main/res/layout/logcat_top_appbar.xml

index aa6f4fdf61e85f2641e6ee618810886d7bd1c62b..a2f28084530970a1bfff3004b8044612b6d3a9e1 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 2017-2020,2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2017-2020, 2022 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
  *
  * 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
index 4161bfe8316cbd0193207659a3574b5bd985a186..b9f6c93fd28ecb05b5f2c542a2771408aa7d8c07 100644 (file)
@@ -1,11 +1,11 @@
 <!--
-  Copyright © 2016-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2019,2021-2022 Bernhard G. Keller.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2019, 2021-2022 Bernhard G. Keller.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
   Translation 2016 Aaron Gerlach <aaron@gerlach.com>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="de">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -56,7 +57,8 @@
             wodurch sie ggf. von der Website abgemeldet werden.
             Diese Einschränkung wird mit <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> in den Versionen 4.x von Privacy Browser behoben werden.</p>
 
-        <p>Wenn Cookies aktiviert sind, aber JavaScript deaktiviert ist, wird das Privatsphären-Icon <img class="inline" src="../shared_images/warning.svg"> zur Warnung in gelb dargestellt.</p>
+        <p>Wenn Cookies aktiviert sind, aber JavaScript deaktiviert ist, wird das Privatsphären-Icon <img class="inline" src="../shared_images/warning.svg" alt="Warning"> zur Warnung in gelb dargestellt.</p>
+
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Drittanbieter-Cookies</h3>
 
@@ -64,6 +66,7 @@
             Es gibt eigentlich keinen guten Grund, solche Cookies überhaupt zuzulassen. Ab Privacy Browser Version 3.8 wurde die Option daher entfernt und selbst Google plant,
             <a href="https://www.theverge.com/2020/1/14/21064698/google-third-party-cookies-chrome-two-years-privacy-safari-firefox">Drittanbieter-Cookies in Zukunft zu deaktivieren</a>.</p>
 
+
         <h3><svg class="header"><use href="../shared_images/web.svg#icon"/></svg> DOM-Speicher</h3>
 
         <p>Der Document-Object-Model-Speicher - auch als Web-Speicher bekannt - funktioniert wie "gedopte" Cookies.
             Die gespeicherten Daten werden dabei - im Gegensatz zu Cookies - nicht bei jeder Anfrage zur Gänze im Header mitgeschickt,
             sondern mittels JavaScript gelesen und geschrieben, sodass diese Form der Datenspeicherung nicht funktioniert, wenn JavaScript deaktiviert ist.</p>
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Formulardaten</h3>
-
-        <p>Formulardaten enthalten Informationen, die in Web-Formulare eingegeben wurden (wie z.B. Benutzernamen, Adressen, Telefonnummern, usw.) und werden bei späteren Besuchen in Auswahl-Dialogen angezeigt.
-            Im Gegensatz zu in Cookies und im DOM-Speicher gespeicherten Daten werden diese Informationen nur nach Benutzer-Interaktion an den Webserver gesandt. Ab Android Oreo (Version 8.0, API 26) wurden
-            WebViews Formulardaten durch <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">Googles Autofill-Service</a> ersetzt.
-            Daher erscheinen Formulardaten auf neueren Android-Geräten nicht mehr.</p>
-
 
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Bereinigen und Schließen</h3>
 
@@ -87,4 +83,4 @@
             danach werden alle <code>App-WebView-</code> und <code>Cache-</code> Verzeichnisse gelöscht.
             Das Verhalten von "Bereinigen und Schließen" kann in den Einstellungen konfiguriert werden.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index a1ccf604e502a8b6fc1da9e353f89fa8f9dfb74e..55764cbeaddfea9a59893aa428f282aa32c58694 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright © 2016-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="en">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -49,7 +50,7 @@
             If the background tab makes a request, for example, to see if there is updated information, that request will be sent without cookies, which will cause the website to log you out.
             This is a limitation that will be removed with the release of <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> in the 4.x series.</p>
 
-        <p>If cookies are enabled but JavaScript is disabled, the privacy icon will be yellow <img class="inline" src="../shared_images/warning.svg"> as a warning.</p>
+        <p>If cookies are enabled but JavaScript is disabled, the privacy icon will be yellow <img class="inline" src="../shared_images/warning.svg" alt="Warning"> as a warning.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Third-Party Cookies</h3>
             Rather, it uses JavaScript to read and write data, which means it does not function when JavaScript is disabled.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Form Data</h3>
-
-        <p>Form data contains information typed into web forms, like usernames, addresses, phone numbers, etc., and lists them in a drop-down box on future visits.
-            Unlike the other forms of local storage, form data is not sent to the web server without specific user interaction. Beginning in Android Oreo (version 8.0, API 26),
-            WebView’s form data was replaced by the <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">Autofill service</a>.
-            As such, controls for form data no longer appear on newer Android devices.</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Clear and Exit</h3>
 
         <p>Clear and Exit runs every time the last tab is closed or Clear and Exit is selected from the navigation menu.
             By default it clears the cookies, DOM storage, form data, the logcat, and the WebView cache. Then it manually deletes the entire <code>app_webview</code> and <code>cache</code> directories.
             The behavior of Clear and Exit can be configured in the settings.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index 9b12a1c42b6f2ce5675403ad454c5d29725638ce..d3faf0886edffc6a644139f3948da9cb143cee1d 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright 2016-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="en">
     <head>
         <meta charset="UTF-8">
+        <title>Tracking IDs</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
index 3e7e0f493c394d4573d24757c3abcc0fdbc0f462..e762bb387445e6fb3de0db67783c2e887a28fcbb 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright 2016-2020,2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2020, 2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="en">
     <head>
         <meta charset="UTF-8">
+        <title>User Agent</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -41,7 +42,7 @@
             The screenshot below shows a Pixel 2 XL running Android 10 with Android System WebView 84.0.4147.125 installed.
             Most web servers will recognize this as a mobile browser and will display the mobile version of the site if they have one.</p>
 
-        <img class="center" src="images/user_agent.png">
+        <img class="center" src="images/user_agent.png" alt="User Agent">
 
         <p>There is enough information in the user agent that sometimes only a few visitors to a website will be the same.
             If the user agent is combined with another piece of non-unique identifying information, often it results in a unique fingerprint.
index 23351e5d8b46a644d35698bff729d52f0cba45c3..ca9bc9ef9fe4977693de82a407288c8974343f90 100644 (file)
@@ -1,9 +1,9 @@
 <!--
-  Copyright © 2016-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2017-2018,2021 Jose A. León.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2017-2018, 2021 Jose A. León.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="es">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -52,7 +53,7 @@
             Si la pestaña en segundo plano hace una petición, por ejemplo, para ver si hay información actualizada, esa petición se enviará sin cookies, lo que hará que el sitio web cierre la sesión.
             Esta es una limitación que se eliminará con el lanzamiento de <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> en la serie 4.x.</p>
 
-        <p>Si las cookies están activadas pero JavaScript está desactivado, el icono de privacidad será amarillo <img class="inline" src="../shared_images/warning.svg"> como advertencia.</p>
+        <p>Si las cookies están activadas pero JavaScript está desactivado, el icono de privacidad será amarillo <img class="inline" src="../shared_images/warning.svg" alt="Warning"> como advertencia.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Cookies de terceros</h3>
             Más bien, utiliza JavaScript para leer y escribir datos, lo que significa que no funciona cuando JavaScript está desactivado.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Datos de formulario</h3>
-
-        <p>Los datos de formulario contienen la información introducida en los formularios web, como los nombres de los usuarios, las direcciones, los números de teléfono, etc.,
-            y los listan en un cuadro desplegable en futuras visitas.
-            A diferencia de las otras formas de almacenamiento local, los datos de los formularios no se envían al servidor web sin una interacción específica del usuario.
-            A partir de Android Oreo (versión 8.0, API 26), los datos de formulario de WebView fueron sustituidos por el
-            <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">servicio Autofill o Autorelleno</a>.
-            Por ello, los controles para los datos de los formularios ya no aparecen en los dispositivos Android más nuevos.</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Borrar y Salir</h3>
 
         <p>Borrar y salir se ejecuta cada vez que se cierra la última pestaña o se selecciona Borrar y salir en el menú de navegación.
@@ -87,4 +78,4 @@
             Luego borra manualmente los directorios <code>app_webview</code> y <code>cache</code>.
             El comportamiento de Borrar y Salir se puede configurar en los ajustes.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index 985b6792292d3ab015af48b26aef56c1a4a1be1d..208cf6308d3aeecbda61c7c436a468348b42ddb5 100644 (file)
@@ -1,9 +1,9 @@
 <!--
-  Copyright © 2016-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2019,2021-2022 Kévin L. <kevinliste@framalistes.org>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2019, 2021-2022 Kévin L. <kevinliste@framalistes.org>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="fr">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -54,7 +55,7 @@
             Si l'onglet d'arrière-plan fait une demande, par exemple, pour voir s'il y a des informations mises à jour, cette demande sera envoyée sans cookies, ce qui fera que le site web vous déconnectera.
             Il s'agit d'une limitation qui sera supprimée avec la sortie de <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> dans la série 4.x.</p>
 
-        <p>Si les cookies sont activés mais que JavaScript est désactivé, l'icône de confidentialité sera jaune <img class="inline" src="../shared_images/warning.svg"> en guise d'avertissement.</p>
+        <p>Si les cookies sont activés mais que JavaScript est désactivé, l'icône de confidentialité sera jaune <img class="inline" src="../shared_images/warning.svg" alt="Warning"> en guise d'avertissement.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Cookies tiers</h3>
             Il utilise plutôt JavaScript pour lire et écrire les données, ce qui signifie qu'il ne fonctionne pas lorsque JavaScript est désactivé.</p>
 
 
-        <h3> <svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Données de formulaire</h3>
-
-        <p>Les données de formulaire contiennent les informations saisies dans les formulaires web, comme les noms d'utilisateur, les adresses, les numéros de téléphone,
-            etc. et les répertorient dans une boîte déroulante lors de visites ultérieures.
-            Contrairement aux autres formes de stockage local, les données de formulaire ne sont pas envoyées au serveur web sans interaction spécifique de l'utilisateur.
-            À partir d'Android Oreo (version 8.0, API 26), les données de formulaire de WebView ont été remplacées par le
-            <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">service Autofill</a>.
-            Ainsi, les contrôles des données de formulaire n'apparaissent plus sur les appareils Android plus récents.</p>
-
-
-        <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Nettoyer et Quitter<</h3>
+        <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Nettoyer et Quitter</h3>
 
         <p>La fonction Nettoyer et Quitter s'exécute chaque fois que le dernier onglet est fermé ou que Nettoyer et Quitter est sélectionnée dans le menu de navigation.
             Par défaut, elle efface les cookies, le stockage DOM, les données de formulaire, le logcat et le cache WebView.
             Ensuite, elle supprime manuellement l'ensemble des répertoires <code>app_webview</code> et <code>cache</code>. Le comportement de Nettoyer et Quitter peut être configuré dans les paramètres.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index fa5cd590a8f8b3de2f715d6fecb4af5cb03ef374..efaf8f69df955ba82e1c935418f47fdb875216bb 100644 (file)
@@ -1,9 +1,9 @@
 <!--
-  Copyright © 2017-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2017-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2017-2018,2021-2022 Francesco Buratti.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2017-2018, 2021-2022 Francesco Buratti.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="it">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -54,7 +55,7 @@
             quella richiesta sarà inviata senza cookie e questo provocherà il log out dal sito.
             Questa è una limitazione che sarà rimossa con il rilascio di <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> nella serie 4.x.</p>
 
-        <p>Se i cookies sono abilitati ma JavaScript è disabilitato, l'icona della privacy sarà gialla <img class="inline" src="../shared_images/warning.svg"> come avvertimento.</p>
+        <p>Se i cookies sono abilitati ma JavaScript è disabilitato, l'icona della privacy sarà gialla <img class="inline" src="../shared_images/warning.svg" alt="Warning"> come avvertimento.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Cookies di terze parti</h3>
             Al contrario utilizza JavaScript per leggere e scrivere i dati, il che significa che non può funzionare se JavaScript è disabilitato.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Dati dei moduli</h3>
-
-        <p>I dati dei moduli contengono informazioni che sono digitate nei web forms, come il nome dell'utente, gli indirizzi, numeri di telefono, ecc.,
-            e li elenca in un menù a tendina in caso di accessi futuri.
-            A differenza delle altre modalità di memorizzazione locale, i dati dei moduli non vengono inviati ai web server senza che ci sia una interazione con l'utente.
-            A partire da Android Oreo (versione 8.0, API 26), i dati dei moduli di WebView sono stati sostituiti dal
-            <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">servizio Autofill</a>.
-            Per questo motivo i controlli dei dati dei moduli non sono presenti nei dispositivi Android più recenti.</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Elimina dati ed esci</h3>
 
         <p>Elimina dati ed esci viene eseguito ogni volta che viene chiusa l'ultima scheda oppure quando viene selezionato il comando Elimina dati ed esci dal menù di navigazione.
             Di default questo comando cancella i cookie, il DOM storage, i dati dei moduli, il logcat e la cache di WebView.
             In sostanza elimina completamente le cartelle <code>app_webview</code> e <code>cache</code>. Il comportamento di Elimina dati ed esci può essere configurato nelle impostazioni.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index 4525208e73e67abe181ad5ea09f49ba5108b4d11..5d318724e30ebfa2ef05a98fdbc7a2d9843d45cc 100644 (file)
@@ -1,9 +1,9 @@
 <!--
-  Copyright © 2016-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
   Translation 2021 Thiago Nazareno Conceição Silva de Jesus <mochileiro2006-trilhas@yahoo.com.br>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="pt">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -52,7 +53,7 @@
             Se a guia em segundo plano fizer uma solicitação, por exemplo, para ver se há informações atualizadas, essa solicitação será enviada sem cookies, oque fará com que o site desconecte você.
             Esta é uma limitação que será removida com o lançamento do <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> no 4.x série.</p>
 
-        <p>Se os cookies estiverem habilitados, mas o JavaScript estiver desabilitado, o ícone de privacidade ficará amarelo <img class="inline" src="../shared_images/warning.svg"> como um aviso.</p>
+        <p>Se os cookies estiverem habilitados, mas o JavaScript estiver desabilitado, o ícone de privacidade ficará amarelo <img class="inline" src="../shared_images/warning.svg" alt="Warning"> como um aviso.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Cookies de terceiros</h3>
             Em vez disso, ele usa JavaScript para ler e gravar dados, o que significa que não funciona quando o JavaScript está desabilitado.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Dados do Formulário</h3>
-
-        <p>Os dados do formulário contêm informações digitadas em formulários da web, como nomes de usuário, endereços, números de telefone, etc., e os relaciona em uma caixa suspensa em visitas futuras.
-            Ao contrário de outras formas de armazenamento local, os dados do formulário não são enviados ao servidor da web sem interação específica do usuário.
-            A partir do Android Oreo (versão 8.0, API 26), os dados do formulário WebView foram substituídos pelo
-            <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">Autofill service</a>.
-            Como tal, os controles para dados de formulário não aparecem mais em dispositivos Android mais recentes.</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Limpar e fechar</h3>
 
         <p>Limpar e Fechar é executado sempre que a última guia é fechada ou Limpar e Fechar é selecionado no menu de navegação.
             Por padrão, ele limpa os cookies, o armazenamento DOM, os dados do formulário, o logcat e o cache do WebView.
             Em seguida, ele exclui manualmente todos os diretórios <code>app_webview</code> e <code>cache</code>. O comportamento de Limpar e Fechar pode ser configurado nas configurações.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index 118812032453fcd39ee99b12d1828fd929a87519..5848332656f0c9d6440f817c3522178f47f06b46 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright © 2016-2018,2020-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2018, 2020-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="ru">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -50,7 +51,7 @@
             Если фоновая вкладка делает запрос, например, чтобы узнать, есть ли обновленная информация, этот запрос будет отправлен без файлов cookie, что приведет к разлогиниванию.
             Это ограничение будет устранено с выходом <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> в версии 4.x.</p>
 
-        <p>Если cookie включены и при этом JavaScript отключен, то значок конфиденциальности будет желтого цвета <img class="inline" src="../shared_images/warning.svg"> в качестве предупреждения.</p>
+        <p>Если cookie включены и при этом JavaScript отключен, то значок конфиденциальности будет желтого цвета <img class="inline" src="../shared_images/warning.svg" alt="Warning"> в качестве предупреждения.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Сторонние файлы cookie</h3>
             Вместо этого оно использует JavaScript для чтения и записи данных, а это означает, что оно не работает, когда JavaScript отключен.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Данные форм</h3>
-
-        <p>Данные форм содержат информацию, введенную в веб-формы, такую как имена пользователей, адреса, номера телефонов и т.д., и отображаются в выпадающем списке при последующих посещениях.
-            В отличие от других форм локального хранилища, данные форм не передаются на веб-сервер без определенного взаимодействия с пользователем. Начиная с Android Oreo (версия 8.0, API 26),
-            данные форм WebView были заменены <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">сервисом автозаполнения</a>.
-            Таким образом, элементы управления данными формы больше не отображаются на новых Android-устройствах.</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Очистить и выйти</h3>
 
         <p>Функция Очистить и выйти запускается каждый раз при закрытии последней вкладки или выборе Очистить и выйти из меню навигации.
             По умолчанию очищаются cookie, DOM-хранилище, данные формы, logcat и кэш WebView. Затем происходит ручное удаление всех каталогов <code>app_webview</code> и <code>cache</code>.
             Поведение опции Очистить и выйти можно настроить в настройках.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index ce88b64292b0cde4da3f6f20a6c971383b86cccb..1a2c451a5897b961031d82f6da87c39b19b22604 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright © 2016-2022 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2022, 2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="tr">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -50,7 +51,7 @@
             If the background tab makes a request, for example, to see if there is updated information, that request will be sent without cookies, which will cause the website to log you out.
             This is a limitation that will be removed with the release of <a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">Privacy WebView</a> in the 4.x series.</p>
 
-        <p>If cookies are enabled but JavaScript is disabled, the privacy icon will be yellow <img class="inline" src="../shared_images/warning.svg"> as a warning.</p>
+        <p>If cookies are enabled but JavaScript is disabled, the privacy icon will be yellow <img class="inline" src="../shared_images/warning.svg" alt="Warning"> as a warning.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Üçüncü Taraf Çerezler</h3>
             Rather, it uses JavaScript to read and write data, which means it does not function when JavaScript is disabled.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Form Verisi</h3>
-
-        <p>Form data contains information typed into web forms, like usernames, addresses, phone numbers, etc., and lists them in a drop-down box on future visits.
-            Unlike the other forms of local storage, form data is not sent to the web server without specific user interaction. Beginning in Android Oreo (version 8.0, API 26),
-            WebView’s form data was replaced by the <a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">Autofill service</a>.
-            As such, controls for form data no longer appear on newer Android devices.</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> Clear and Exit</h3>
 
         <p>Clear and Exit runs every time the last tab is closed or Clear and Exit is selected from the navigation menu.
             By default it clears the cookies, DOM storage, form data, the logcat, and the WebView cache. Then it manually deletes the entire <code>app_webview</code> and <code>cache</code> directories.
             The behavior of Clear and Exit can be configured in the settings.</p>
     </body>
-</html>
\ No newline at end of file
+</html>
index a0a608b753934dcc2072eb11bef0c1bd8d5364fd..373d752cdacf05b1c9bb026f7bce0f69d0c44254 100644 (file)
@@ -1,9 +1,9 @@
 <!--
-  Copyright 2016-2018,2020-2023 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2016-2018, 2020-2024 Soren Stoutner <soren@stoutner.com>.
 
   Translation 2023 Xin.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
   You should have received a copy of the GNU General Public License
   along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<html>
+<html lang="zh">
     <head>
         <meta charset="UTF-8">
+        <title>Local Storage</title>
 
         <link rel="stylesheet" href="../css/theme.css">
 
@@ -43,7 +44,7 @@
             如果你在后台有一个页面需要cookies来登录,而你在一个页面里关闭了cookies,所有页面的cookies都会被关闭。如果在后台的页面发出请求,例如,看有没有新消息,而在没有cookies的情况下需要你重新登录。
             这个限制会在<a href="https://www.stoutner.com/category/privacy-browser-android-roadmap/">隐私浏览器</a> 4.x系列中移除。</p>
 
-        <p>如果cookies允许,而JavaScript不允许,隐私盾牌会变成黄色<img class="inline" src="../shared_images/warning.svg">来示警</p>
+        <p>如果cookies允许,而JavaScript不允许,隐私盾牌会变成黄色<img class="inline" src="../shared_images/warning.svg" alt="Warning">来示警</p>
 
 
         <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> 第三方Cookies</h3>
             不像cookies,DOM储存不在请求头中发送数据,相反,它使用JavaScript来读写数据,意味着在禁用JavaScript时DOM不能工作。</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> 表单数据</h3>
-
-        <p>表单数据包含输入到web表单中的信息,包括用户名。地址,电话等等,并且在表中罗列。不像其他本地存储的表单,没有特定的用户需求,表单不会发送到web中。
-            从Android Oreo (version 8.0, API 26)开始,WebView的表单数据被<a href="https://medium.com/@bherbst/getting-androids-autofill-to-work-for-you-21435debea1">Autofill service</a>取代。
-            因此表单数据控件不会在新的安卓设备中出现</p>
-
-
         <h3><svg class="header"><use href="../shared_images/delete_forever.svg#icon"/></svg> 清除并退出</h3>
 
         <p>清除并退出会在最后一个页面退出或在导航栏选中时运行,默认清除cookies,DOM储存,表单数据,日志和WebView缓存。然后需要手动删除app_webview和cache目录。可以在设置中配置清除并退出的行为。</p>
index 49f3fd6083fa4735e1cdf858f536059474b6056c..624ba5afa95f920c702b36583e9aee6998d06d48 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 2016-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2016-2024 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
  *
  * 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
@@ -43,19 +43,17 @@ class GuideActivity : AppCompatActivity() {
         val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
 
         // Disable screenshots if not allowed.
-        if (!allowScreenshots) {
+        if (!allowScreenshots)
             window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
-        }
 
         // Run the default commands.
         super.onCreate(savedInstanceState)
 
         // Set the content view.
-        if (bottomAppBar) {
+        if (bottomAppBar)
             setContentView(R.layout.guide_bottom_appbar)
-        } else {
+        else
             setContentView(R.layout.guide_top_appbar)
-        }
 
         // Get handles for the views.
         val toolbar = findViewById<Toolbar>(R.id.guide_toolbar)
index 4005443ae1c0d0e637c48dd7639713093b91c1b0..c12c74ecb4302c403067724b84ddcf35ec77c011 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2019-2024 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
  *
  * 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
@@ -24,12 +24,12 @@ import android.content.ClipboardManager
 import android.os.Build
 import android.os.Bundle
 import android.provider.OpenableColumns
+import android.util.Base64
 import android.util.TypedValue
 import android.view.Menu
 import android.view.MenuItem
 import android.view.WindowManager
-import android.widget.TextView
-import android.widget.ScrollView
+import android.webkit.WebView
 
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.appcompat.app.AppCompatActivity
@@ -50,29 +50,25 @@ import kotlinx.coroutines.withContext
 import java.io.BufferedReader
 import java.io.IOException
 import java.io.InputStreamReader
-import java.lang.Exception
+
 import java.nio.charset.StandardCharsets
 
 // Define the class constants.
-private const val SCROLLVIEW_POSITION = "scrollview_position"
+private const val SCROLL_Y = "A"
 
 class LogcatActivity : AppCompatActivity() {
-    // Define the class variables.
-    private var scrollViewYPositionInt = 0
+    // Declare the class variables.
+    private lateinit var logcatPlainTextStringBuilder: StringBuilder
 
-    // Define the class views.
+    // Declare the class views.
     private lateinit var swipeRefreshLayout: SwipeRefreshLayout
-    private lateinit var logcatScrollView: ScrollView
-    private lateinit var logcatTextView: TextView
+    private lateinit var logcatWebView: WebView
 
     // Define the save logcat activity result launcher.  It must be defined before `onCreate()` is run or the app will crash.
     private val saveLogcatActivityResultLauncher = registerForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { fileUri ->
         // Only save the file if the URI is not null, which happens if the user exited the file picker by pressing back.
         if (fileUri != null) {
             try {
-                // Get the logcat string.
-                val logcatString = logcatTextView.text.toString()
-
                 // Open an output stream.
                 val outputStream = contentResolver.openOutputStream(fileUri)!!
 
@@ -80,7 +76,7 @@ class LogcatActivity : AppCompatActivity() {
                 CoroutineScope(Dispatchers.Main).launch {
                     withContext(Dispatchers.IO) {
                         // Write the logcat string to the output stream.
-                        outputStream.write(logcatString.toByteArray(StandardCharsets.UTF_8))
+                        outputStream.write(logcatPlainTextStringBuilder.toString().toByteArray(StandardCharsets.UTF_8))
 
                         // Close the output stream.
                         outputStream.close()
@@ -100,10 +96,10 @@ class LogcatActivity : AppCompatActivity() {
                 contentResolverCursor.close()
 
                 // Display a snackbar with the saved logcat information.
-                Snackbar.make(logcatTextView, getString(R.string.saved, fileNameString), Snackbar.LENGTH_SHORT).show()
+                Snackbar.make(logcatWebView, getString(R.string.saved, fileNameString), Snackbar.LENGTH_SHORT).show()
             } catch (exception: Exception) {
                 // Display a snackbar with the error message.
-                Snackbar.make(logcatTextView, getString(R.string.error_saving_logcat, exception.toString()), Snackbar.LENGTH_INDEFINITE).show()
+                Snackbar.make(logcatWebView, getString(R.string.error_saving_logcat, exception.toString()), Snackbar.LENGTH_INDEFINITE).show()
             }
         }
     }
@@ -117,25 +113,22 @@ class LogcatActivity : AppCompatActivity() {
         val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
 
         // Disable screenshots if not allowed.
-        if (!allowScreenshots) {
+        if (!allowScreenshots)
             window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
-        }
 
         // Run the default commands.
         super.onCreate(savedInstanceState)
 
         // Set the content view.
-        if (bottomAppBar) {
+        if (bottomAppBar)
             setContentView(R.layout.logcat_bottom_appbar)
-        } else {
+        else
             setContentView(R.layout.logcat_top_appbar)
-        }
 
         // Get handles for the views.
         val toolbar = findViewById<Toolbar>(R.id.toolbar)
         swipeRefreshLayout = findViewById(R.id.swiperefreshlayout)
-        logcatScrollView = findViewById(R.id.scrollview)
-        logcatTextView = findViewById(R.id.logcat_textview)
+        logcatWebView = findViewById(R.id.logcat_webview)
 
         // Set the toolbar as the action bar.
         setSupportActionBar(toolbar)
@@ -148,8 +141,8 @@ class LogcatActivity : AppCompatActivity() {
 
         // Implement swipe to refresh.
         swipeRefreshLayout.setOnRefreshListener {
-            // Get the current logcat.
-            getLogcat()
+            // Populate the current logcat.
+            populateLogcat()
         }
 
         // Set the swipe refresh color scheme according to the theme.
@@ -167,14 +160,15 @@ class LogcatActivity : AppCompatActivity() {
         // Set the swipe refresh background color.
         swipeRefreshLayout.setProgressBackgroundColorSchemeColor(colorBackgroundInt)
 
-        // Check to see if the activity has been restarted.
-        if (savedInstanceState != null) {
-            // Get the saved scrollview position.
-            scrollViewYPositionInt = savedInstanceState.getInt(SCROLLVIEW_POSITION)
-        }
+        // Restore the WebView scroll position if the activity has been restarted.
+        if (savedInstanceState != null)
+            logcatWebView.scrollY = savedInstanceState.getInt(SCROLL_Y)
+
+        // Allow loading of file:// URLs.
+        logcatWebView.settings.allowFileAccess = true
 
-        // Get the logcat.
-        getLogcat()
+        // Populate the logcat.
+        populateLogcat()
     }
 
     override fun onCreateOptionsMenu(menu: Menu): Boolean {
@@ -193,14 +187,14 @@ class LogcatActivity : AppCompatActivity() {
                 val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
 
                 // Save the logcat in a clip data.
-                val logcatClipData = ClipData.newPlainText(getString(R.string.logcat), logcatTextView.text)
+                val logcatClipData = ClipData.newPlainText(getString(R.string.logcat), logcatPlainTextStringBuilder)
 
                 // Place the clip data on the clipboard.
                 clipboardManager.setPrimaryClip(logcatClipData)
 
                 // Display a snackbar if the API <= 32 (Android 12L).  Beginning in Android 13 the OS displays a notification that covers up the snackbar.
                 if (Build.VERSION.SDK_INT <= 32)
-                    Snackbar.make(logcatTextView, R.string.logcat_copied, Snackbar.LENGTH_SHORT).show()
+                    Snackbar.make(logcatWebView, R.string.logcat_copied, Snackbar.LENGTH_SHORT).show()
 
                 // Consume the event.
                 true
@@ -222,11 +216,8 @@ class LogcatActivity : AppCompatActivity() {
                     // Wait for the process to finish.
                     process.waitFor()
 
-                    // Reset the scroll view Y position int.
-                    scrollViewYPositionInt = 0
-
                     // Reload the logcat.
-                    getLogcat()
+                    populateLogcat()
                 } catch (exception: Exception) {
                     // Do nothing.
                 }
@@ -246,14 +237,11 @@ class LogcatActivity : AppCompatActivity() {
         // Run the default commands.
         super.onSaveInstanceState(savedInstanceState)
 
-        // Get the scrollview Y position.
-        val scrollViewYPositionInt = logcatScrollView.scrollY
-
-        // Store the scrollview Y position in the bundle.
-        savedInstanceState.putInt(SCROLLVIEW_POSITION, scrollViewYPositionInt)
+        // Store the scroll Y position in the bundle.
+        savedInstanceState.putInt(SCROLL_Y, logcatWebView.scrollY)
     }
 
-    private fun getLogcat() {
+    private fun populateLogcat() {
         try {
             // Get the logcat.  `-b all` gets all the buffers (instead of just crash, main, and system).  `-v long` produces more complete information.  `-d` dumps the logcat and exits.
             val getLogcatProcess = Runtime.getRuntime().exec("logcat -b all -v long -d")
@@ -261,8 +249,83 @@ class LogcatActivity : AppCompatActivity() {
             // Wrap the logcat in a buffered reader.
             val logcatBufferedReader = BufferedReader(InputStreamReader(getLogcatProcess.inputStream))
 
-            // Display the logcat.
-            logcatTextView.text = logcatBufferedReader.readText()
+            // Reset the logcat plain text string.
+            logcatPlainTextStringBuilder = StringBuilder()
+
+            // Create a logcat HTML string builder.
+            val logcatHtmlStringBuilder = StringBuilder()
+
+            // Populate the initial HTML.
+            logcatHtmlStringBuilder.append("<html>")
+            logcatHtmlStringBuilder.append("<head>")
+            logcatHtmlStringBuilder.append("<style>")
+
+            // Set the word break so that lines never exceed the width of the screen.
+            logcatHtmlStringBuilder.append("body { word-break: break-word; }")
+
+            // Set the colors.
+            logcatHtmlStringBuilder.append("@media (prefers-color-scheme: dark) { body { color: #C1C1C1;  /* Gray 350 */ background-color: #303030;  /* Gray 860 */ } }")
+            logcatHtmlStringBuilder.append("span.header { color: #0D47A1;  /* Blue 900 */ } @media (prefers-color-scheme: dark) { span.header { color: #8AB4F8;  /* Violet 500 */ } }")
+            logcatHtmlStringBuilder.append("strong.crash { color: #B71C1C;  /* Red 900. */ } @media (prefers-color-scheme: dark) { strong.crash { color: #E24B4C;  /* Red Night. */ } }")
+            logcatHtmlStringBuilder.append("span.crash { color: #EF5350;  /* Red 400. */ } @media (prefers-color-scheme: dark) { span.crash { color: #EF9A9A;  /* Red Night. */ } }")
+
+            // Close the style tag.
+            logcatHtmlStringBuilder.append("</style>")
+
+            // Respect dark mode.
+            logcatHtmlStringBuilder.append("<meta name=\"color-scheme\" content=\"light dark\">")
+
+            // Start the HTML body.
+            logcatHtmlStringBuilder.append("</head>")
+            logcatHtmlStringBuilder.append("<body>")
+
+            // Create a logcat line string.
+            var logcatLineString: String?
+
+            while (logcatBufferedReader.readLine().also { logcatLineString = it } != null) {
+                // Populate the logcat plain text string builder.
+                logcatPlainTextStringBuilder.append(logcatLineString)
+
+                // Add a line break.
+                logcatPlainTextStringBuilder.append("\n")
+
+                // Trim the string, which is necessary for correct detection of lines that start with `at`.
+                logcatLineString = logcatLineString!!.trim()
+
+                // Apply syntax highlighting to the logcat.
+                if (logcatLineString!!.contains("crash") || logcatLineString!!.contains("Exception") ) {  // Colorize crashes.
+                    logcatHtmlStringBuilder.append("<strong class=\"crash\">")
+                    logcatHtmlStringBuilder.append(logcatLineString)
+                    logcatHtmlStringBuilder.append("</strong>")
+                } else if (logcatLineString!!.startsWith("at") || logcatLineString!!.startsWith("Process:") || logcatLineString!!.contains("FATAL")) {  // Colorize lines relating to crashes.
+                    logcatHtmlStringBuilder.append("<span class=\"crash\">")
+                    logcatHtmlStringBuilder.append(logcatLineString)
+                    logcatHtmlStringBuilder.append("</span>")
+                } else if (logcatLineString!!.startsWith("-")) {  // Colorize the headers.
+                    logcatHtmlStringBuilder.append("<span class=\"header\">")
+                    logcatHtmlStringBuilder.append(logcatLineString)
+                    logcatHtmlStringBuilder.append("</span>")
+                } else if (logcatLineString!!.startsWith("[ ")) {  // Colorize the time stamps.
+                    logcatHtmlStringBuilder.append("<span style=color:gray>")
+                    logcatHtmlStringBuilder.append(logcatLineString)
+                    logcatHtmlStringBuilder.append("</span>")
+                } else {  // Display the standard lines.
+                    logcatHtmlStringBuilder.append(logcatLineString)
+                }
+
+                // Add a line break.
+                logcatHtmlStringBuilder.append("<br>")
+            }
+
+            // Close the HTML.
+            logcatHtmlStringBuilder.append("</body>")
+            logcatHtmlStringBuilder.append("</html>")
+
+            // Encode the logcat HTML.
+            val base64EncodedLogcatHtml: String = Base64.encodeToString(logcatHtmlStringBuilder.toString().toByteArray(Charsets.UTF_8), Base64.NO_PADDING)
+
+            // Load the encoded logcat.
+            logcatWebView.loadData(base64EncodedLogcatHtml, "text/html", "base64")
 
             // Close the buffered reader.
             logcatBufferedReader.close()
@@ -270,12 +333,6 @@ class LogcatActivity : AppCompatActivity() {
             // Do nothing.
         }
 
-        // Update the scroll position after the text is populated.
-        logcatTextView.post {
-            // Set the scroll position.
-            logcatScrollView.scrollY = scrollViewYPositionInt
-        }
-
         // Stop the swipe to refresh animation if it is displayed.
         swipeRefreshLayout.isRefreshing = false
     }
index 634e4f6529463a4a7aa72b42005d5ffbc2babfbc..cd91ecba4d062c2cefc24209bb73b69843b45823 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 2017-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2017-2024 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
  *
  * 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
@@ -102,7 +102,7 @@ class GetHeadersBackgroundTask {
                 // Create a buffered string reader for the content data.
                 val bufferedReader = BufferedReader(InputStreamReader(contentResolver.openInputStream(contentUri)))
 
-                // Create a buffered string reader for the content data.
+                // Create a content line string.
                 var contentLineString: String?
 
                 // Get the data from the buffered reader one line at a time.
index 5c8425cc328d34861515075e4246f8a77af83969..a8cc844880076ed1d93d450933f15afd25d53fb6 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 2016-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2016-2024 Soren Stoutner <soren@stoutner.com>.
  *
- * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
  *
  * 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
@@ -40,8 +40,8 @@ import androidx.webkit.WebViewFeature
 import com.stoutner.privacybrowser.R
 
 // Define the class constants.
-private const val TAB_NUMBER = "tab_number"
-private const val SCROLL_Y = "scroll_y"
+private const val TAB_NUMBER = "A"
+private const val SCROLL_Y = "B"
 
 class GuideWebViewFragment : Fragment() {
     // Define the class variables.
@@ -135,7 +135,7 @@ class GuideWebViewFragment : Fragment() {
             9 -> tabWebView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.android_asset_path) + "/guide_interface.html")
         }
 
-        // Scroll the WebView if the saved instance state is not null.
+        // Restore the WebView scroll position if the activity has been restarted.
         if (savedInstanceState != null) {
             tabWebView.post {
                 tabWebView.scrollY = savedInstanceState.getInt(SCROLL_Y)
index 69b04087056f8b8f08517778e13392d44b0ce57f..cc34fb3cc29875d95949cdea83386e6c57c81a56 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright 2018-2023 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2018-2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
             android:layout_width="match_parent"
             android:layout_weight="1" >
 
-            <ScrollView
-                android:id="@+id/scrollview"
+            <WebView
+                android:id="@+id/logcat_webview"
                 android:layout_height="wrap_content"
-                android:layout_width="match_parent" >
-
-                <TextView
-                    android:id="@+id/logcat_textview"
-                    android:layout_height="wrap_content"
-                    android:layout_width="match_parent"
-                    android:layout_margin="10dp"
-                    android:textIsSelectable="true" />
-            </ScrollView>
+                android:layout_width="match_parent" />
         </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
 
         <!-- The app bar theme must be specified here because the activity uses a `NoActionBar` theme. -->
index 10f487d7f663bd11b108d9f8d259c538761989b9..1eb6a675a47e5810ec30ee34bbc8ec92ba2e3fb4 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright 2018-2023 Soren Stoutner <soren@stoutner.com>.
+  Copyright 2018-2024 Soren Stoutner <soren@stoutner.com>.
 
-  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
+  This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android/>.
 
   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
             android:layout_height="match_parent"
             android:layout_width="match_parent" >
 
-            <ScrollView
-                android:id="@+id/scrollview"
+            <WebView
+                android:id="@+id/logcat_webview"
                 android:layout_height="wrap_content"
-                android:layout_width="match_parent" >
-
-                <TextView
-                    android:id="@+id/logcat_textview"
-                    android:layout_height="wrap_content"
-                    android:layout_width="match_parent"
-                    android:layout_margin="10dp"
-                    android:textIsSelectable="true" />
-            </ScrollView>
+                android:layout_width="match_parent" />
         </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
     </LinearLayout>
 </androidx.coordinatorlayout.widget.CoordinatorLayout>