Allow View Source to connect to untrusted SSL certificates. https://redmine.stoutner...
authorSoren Stoutner <soren@stoutner.com>
Thu, 13 May 2021 23:27:28 +0000 (16:27 -0700)
committerSoren Stoutner <soren@stoutner.com>
Thu, 13 May 2021 23:27:28 +0000 (16:27 -0700)
55 files changed:
app/src/main/assets/css/theme.css
app/src/main/assets/de/guide_domain_settings.html
app/src/main/assets/de/guide_tracking_ids.html
app/src/main/assets/en/guide_domain_settings.html
app/src/main/assets/en/guide_tracking_ids.html
app/src/main/assets/es/guide_domain_settings.html
app/src/main/assets/es/guide_tracking_ids.html
app/src/main/assets/fr/guide_domain_settings.html
app/src/main/assets/fr/guide_tracking_ids.html
app/src/main/assets/it/guide_domain_settings.html
app/src/main/assets/it/guide_tracking_ids.html
app/src/main/assets/pt-rBR/guide_domain_settings.html
app/src/main/assets/pt-rBR/guide_javascript.html
app/src/main/assets/pt-rBR/guide_local_storage.html
app/src/main/assets/pt-rBR/guide_overview.html
app/src/main/assets/pt-rBR/guide_proxies.html
app/src/main/assets/pt-rBR/guide_requests.html
app/src/main/assets/pt-rBR/guide_ssl_certificates.html
app/src/main/assets/pt-rBR/guide_tracking_ids.html
app/src/main/assets/pt-rBR/guide_user_agent.html
app/src/main/assets/pt-rBR/images/domain_settings.png
app/src/main/assets/pt-rBR/images/pinned_mismatch.png
app/src/main/assets/pt-rBR/images/pinned_ssl_certificate.png
app/src/main/assets/pt-rBR/images/request_details.png
app/src/main/assets/pt-rBR/images/user_agent.png
app/src/main/assets/ru/guide_domain_settings.html
app/src/main/assets/ru/guide_tracking_ids.html
app/src/main/assets/shared_images/green_url_bar.png
app/src/main/assets/tr/guide_domain_settings.html
app/src/main/assets/tr/guide_tracking_ids.html
app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java [deleted file]
app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.kt [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/ViewSourceActivity.kt
app/src/main/java/com/stoutner/privacybrowser/backgroundtasks/GetSourceBackgroundTask.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/AboutViewSourceDialog.kt
app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.kt
app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.kt
app/src/main/java/com/stoutner/privacybrowser/dialogs/UntrustedSslCertificateDialog.kt [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/viewmodelfactories/WebViewSourceFactory.kt
app/src/main/java/com/stoutner/privacybrowser/viewmodels/WebViewSource.kt
app/src/main/res/values-de/strings.xml
app/src/main/res/values-es/strings.xml
app/src/main/res/values-it/strings.xml
app/src/main/res/values-night-v23/styles.xml
app/src/main/res/values-night-v27/styles.xml
app/src/main/res/values-night/styles.xml
app/src/main/res/values-pt-rBR/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-v23/styles.xml
app/src/main/res/values-v27/styles.xml
app/src/main/res/values/attrs.xml
app/src/main/res/values/strings.xml
app/src/main/res/values/styles.xml
build.gradle

index 22d34ebd1460ea5703ceb641bf64c627e466e2b8..7527682e8d100f039f1b774f893466e73fa83897 100644 (file)
@@ -163,4 +163,13 @@ img.center {
   margin-right: auto;
   height: 720;
   width: 360;
+}
+
+/* Centered screenshot images with a 2.16 aspect ratio.  An image must be a block to be centered. */
+img.center216 {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+  height: 780;
+  width: 360;
 }
\ No newline at end of file
index ffabdebc275dbf5af7a9ac90636212081dd73bb5..c8fe430b165d98e69f278fa9f046eca26ccd16af 100644 (file)
@@ -39,6 +39,6 @@
 
         <p>Wenn Sie ein Seite besuchen, für die zuvor bereits entsprechende Einstellungen getätigt wurden, wird der Hintergrund der URL-Textbox grün dargestellt.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png"/>
+        <img class="center216" src="../shared_images/green_url_bar.png"/>
     </body>
 </html>
\ No newline at end of file
index 8c0379d62b3d97dd62ccd14a750aa88e838f4816..75ae25e10170018bb74e070ca380a892f233a1d9 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2019 Bernhard G. Keller.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2019,2021 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>.
 
@@ -38,7 +38,8 @@
             Dies wird über den <a href="https://de.wikipedia.org/wiki/Do_Not_Track_(Software)">DNT-Header (Do-Not-Track-Header)</a> innerhalb von Ressourcen-Anfragen bewerkstelligt.</p>
 
         <p>Der DNT-Header bewirkt jedoch de facto so gut wie keine Privatsphäre, da er von den meisten Webservern schlicht ignoriert wird.
-            So ignorieren zum Beispiel mit Yahoo, Google, Microsoft und Facebook so gut wie alle grossen Internet-Anbieter zumindest einige DNT-Header.</p>
+            So ignorieren zum Beispiel mit Yahoo, Google, Microsoft und Facebook so gut wie alle grossen Internet-Anbieter zumindest einige DNT-Header.
+            Ab Version 3.8 ist die Option zum Senden des DNT-Headers im Privacy Browser nicht mehr verfügbar.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> URL-Bereinigung</h3>
index 28d90e2b2f323bf9d356eff834b7aac2068444f2..264b742e23c3d94dca09cd60c9d43c4615bb8a15 100644 (file)
@@ -37,6 +37,6 @@
 
         <p>When visiting a domain that has domain settings specified, the background of the URL text box is green.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png">
+        <img class="center216" src="../shared_images/green_url_bar.png">
     </body>
 </html>
\ No newline at end of file
index ce93eca91173e54e3762796f95647395620d9b70..80eb884ac17955f8b271a56f629f6cc8e63b7e38 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-  Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -32,7 +32,8 @@
         <p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
             This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.</p>
 
-        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
+        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.
+            Beginning with version 3.8, Privacy Browser no longer has the option to send a DNT header.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> URL Modification</h3>
index 906057df5089b6858dcac4db0f4145b28316304e..cc1d1f9da4085681115f81e2241d099565fd544c 100644 (file)
@@ -39,6 +39,6 @@
 
         <p>Al visitar un dominio que tiene la configuración de dominio especificada, el fondo de la casilla de texto de la URL es verde.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png"/>
+        <img class="center216" src="../shared_images/green_url_bar.png"/>
     </body>
 </html>
\ No newline at end of file
index 23cd656923270e7f3a7472cd6fa42c406bd3f6de..63371e2a614e41f1e73fb3629e1b8ed5cd185ebd 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright © 2017-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017-2021 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2017,2019 Jose A. León.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2017,2019,2021 Jose A. León.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -35,7 +35,7 @@
             Esto se logra incluyendo un <a href="https://en.wikipedia.org/wiki/Do_Not_Track">encabezado DNT (Do Not Track o No Rastrear)</a> con las solicitudes web.</p>
 
         <p>El encabezado DNT no provee realmente de mucha privacidad porque la mayoría de servidores web lo ignoran. Por ejemplo, Yahoo, Google, Microsoft y Facebook,
-            todos ellos ignoran al menos algunos encabezados DNT.</p>
+            todos ellos ignoran al menos algunos encabezados DNT. A partir de la versión 3.8, Navegador Privado ya no tiene la opción de enviar una cabecera DNT.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> Modificación de URL</h3>
index ac7d1192038c91f61ab62835e042840336cd3ed5..191f56becf4233e820836994e46fa44ff5055a17 100644 (file)
@@ -39,6 +39,6 @@
 
         <p>Lors de la visite d'un domaine pour lequel des paramètres de domaine sont spécifiés, l'arrière-plan de la zone de texte de l'URL est vert.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png"/>
+        <img class="center216" src="../shared_images/green_url_bar.png"/>
     </body>
 </html>
index a4d52634a8c05937b2510ce3afbd53c211324c4c..0e091841ef8a38a44221a7794b3f0ad316865938 100644 (file)
@@ -1,7 +1,7 @@
 <!--
   Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2019 Kévin L. <kevinliste@framalistes.org>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2019,2021 Kévin L. <kevinliste@framalistes.org>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -35,7 +35,8 @@
              Ceci est réalisé en incluant un <a href="https://en.wikipedia.org/wiki/Do_Not_Track"> en-tête DNT (Ne pas suivre)</a> avec les requêtes Web.</p>
 
         <p>L'en-tête DNT ne fournit pas vraiment de confidentialité car la plupart des serveurs Web l'ignorent.
-            Par exemple, Yahoo, Google, Microsoft et Facebook ignorent tous au moins certains en-têtes DNT.</p>
+            Par exemple, Yahoo, Google, Microsoft et Facebook ignorent tous au moins certains en-têtes DNT.
+            Beginning with version 3.8, Privacy Browser no longer has the option to send a DNT header.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> Modification d'URLs</h3>
index 0455b8df8c0a142f3bc060dde564a6a82137725f..ce7f928fdd3a397f4b8eeeed7616e3d88bfb1ad9 100644 (file)
@@ -39,6 +39,6 @@
 
         <p>Quando si accede a un dominio per cui sono state specificate impostazioni personalizzate la casella di testo dell'indirizzo URL si colora di verde.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png"/>
+        <img class="center216" src="../shared_images/green_url_bar.png"/>
     </body>
 </html>
\ No newline at end of file
index 5adbaf97646ccb873cdebb13a652cfcbbdf58c66..9caede98a94a7ac10c53085fc7c2d911900d2f60 100644 (file)
@@ -1,7 +1,7 @@
 <!--
-  Copyright © 2017-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017-2021 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2017,2019 Francesco Buratti.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2017,2019,2021 Francesco Buratti.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -35,7 +35,7 @@
             Questo è ottenuto attraverso l'inclusione nella richiesta al server di un header denominato: <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track)</a>.</p>
 
         <p>L'header DNT in realtà non garantisce nessuna privacy dal momento che la maggior parte dei web server lo ignora, come ad esempio Yahoo, Google, Microsoft e Facebook,
-            che ignorano tutti almeno alcuni degli header DNT.</p>
+            che ignorano tutti almeno alcuni degli header DNT. A partire dalla versione 3.8 in Privacy Browser non è più presente l'opzione per inviare intestazioni DNT.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> Modifica delle URL</h3>
index 4f4577bcf2b0a7279f9224f39ec6468868831231..71b0a97a9cedab848464ce1b5e7983cd5e46f0dd 100644 (file)
     <body>
         <h3><svg class="header"><use href="../shared_images/dns.svg#icon"/></svg> Secure Web Browsing</h3>
 
-        <p>Privacy Browser’s default is to browse with JavaScript, cookies, and DOM storage disabled.
-            However, some websites legitimately need these features enabled to function correctly.
-            Domain settings can automatically turn on a specified set of features when visiting a designated domain.</p>
+        <p>O padrão do Privacy Browser é navegar com JavaScript, cookies e armazenamento DOM desativados.
+            No entanto, alguns sites precisam legitimamente desses recursos ativados para funcionar corretamente.
+            As configurações de domínio podem ativar automaticamente um conjunto específico de recursos ao visitar um domínio designado.</p>
 
-        <img class="center" src="images/domain_settings.png">
+        <img class="center216" src="images/domain_settings.png">
 
-        <p>When visiting a domain that has domain settings specified, the background of the URL text box is green.</p>
+        <p>Ao visitar um domínio que possui configurações de domínio especificadas, o plano de fundo da caixa de texto do URL é verde.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png">
+        <img class="center216" src="../shared_images/green_url_bar.png">
     </body>
 </html>
\ No newline at end of file
index 90642efd0fdafe3d307d770c925c1080cbfb7810..a37ac65635d6021f49bf6b0d6d921c06d1d19865 100644 (file)
     </head>
 
     <body>
-        <h3><img class="header" src="../shared_images/privacy_browser.svg"/> JavaScript Is Powerful</h3>
+        <h3><img class="header" src="../shared_images/privacy_browser.svg"/> JavaScript É Poderoso</h3>
 
-        <p>Back in the early days of the internet, web pages were static, meaning they they contained text and images that were displayed on the screen but didn’t change or interact with the user.
-            Of course, only so much that is interesting can happen with static content. Several different technologies were developed to facilitate dynamic web pages.
-            JavaScript is one of these technologies.</p>
+        <p>Nos primórdios da internet, as páginas da web eram estáticas, o que significa que continham texto e imagens que eram exibidos na tela, mas não mudavam ou interagiam com o usuário.
+            Obviamente, somente o que é interessante pode acontecer com o conteúdo estático. Várias tecnologias diferentes foram desenvolvidas para facilitar páginas da web dinâmicas.
+            JavaScript é uma dessas tecnologias.</p>
 
-        <p>JavaScript is a programming language. Many web servers host programs written in JavaScript, which are sent to devices as part of the web page.
-            The device runs the JavaScript on its local processor and follows the commands of the program, which can animate images on the website, popup a menu, and do many other useful things.</p>
+        <p>JavaScript é uma linguagem de programação. Muitos servidores da web hospedam programas escritos em JavaScript, que são enviados aos dispositivos como parte da página da web.
+            O dispositivo executa o JavaScript em seu processador local e segue os comandos do programa, que pode animar imagens no site, abrir um menu e fazer muitas outras coisas úteis.</p>
 
 
-        <h3><img class="header" src="../shared_images/javascript_enabled.svg"/> JavaScript Is Dangerous</h3>
+        <h3><img class="header" src="../shared_images/javascript_enabled.svg"/> JavaScript É Perigoso</h3>
 
-        <p>Of course, the concept of running arbitrary programs from a website is potentially dangerous. So there are limitations placed on JavaScript to keep it from doing things like installing viruses.
-            However, it turns out that these limitations are overly broad.
-            Below is a screenshot from <a href="http://webkay.robinlinus.com">webkay</a>, which is a website that demonstrates the type of information that JavaScript can produce about a device.
-            <a href="http://www.browserleaks.com/">Browser Leaks</a> is another good resource.</p>
+        <p>Obviamente, o conceito de executar programas arbitrários a partir de um site é potencialmente perigoso. Portanto, existem limitações colocadas no JavaScript para impedi-lo de fazer coisas como instalar vírus.
+            No entanto, verifica-se que essas limitações são excessivamente amplas.
+            Abaixo está uma captura de tela do <a href="http://webkay.robinlinus.com">webkay</a>, no qual é um site que demonstra o tipo de informação que o JavaScript pode produzir sobre um dispositivo.
+            <a href="http://www.browserleaks.com/">Browser Leaks</a> é um outro bom recurso.</p>
 
         <p><img class="center" src="../shared_images/webkay.png"/></p>
 
-        <p>For privacy purposes, the ideal would be to browse the internet with JavaScript disabled.
-            However, there are some websites that legitimately require JavaScript to accomplish their purposes
-            and others that don’t work correctly without JavaScript even though they could be programmed to do so.
-            Privacy Browser addresses this by making it easy to toggle JavaScript on and off.
-            Tapping the privacy shield will toggle it between blue <img class="inline" src="../shared_images/privacy_browser.svg"/> or yellow <img class="inline" src="../shared_images/warning.svg"/>
-            (both of which indicate that JavaScript is disabled) and red <img class="inline" src="../shared_images/javascript_enabled.svg"/> (JavaScript enabled).
-            Looking at the different information <a href="http://webkay.robinlinus.com">webkay</a> can collect with JavaScript enabled and disabled is informative.</p>
-
-        <p>Browsing the internet with JavaScript disabled, and only enabling it if needed, goes a long way toward protecting privacy.
-            In addition, JavaScript is used to load much of the annoying advertisements and extra cruft that comes along with most modern websites.
-            With it disabled, websites will load faster, consume less network traffic, and use less CPU power, which leads to longer battery life.</p>
+        <p>Para fins de privacidade, o ideal seria navegar na internet com o JavaScript desabilitado.
+            No entanto, existem alguns sites que exigem legitimamente o JavaScript para cumprir seus objetivos
+            e outros que não funcionam corretamente sem JavaScript, embora possam ser programados para isso.
+            O Privacy Browser resolve isso facilitando a ativação e desativação do JavaScript.
+            Tocar no escudo de privacidade irá alterná-lo entre azul <img class="inline" src="../shared_images/privacy_browser.svg"/> ou amarelo <img class="inline" src="../shared_images/warning.svg"/>
+            (ambos indicam que o JavaScript está desativado) e vermelho <img class="inline" src="../shared_images/javascript_enabled.svg"/> (JavaScript ativado).
+            É informativo observar as diferentes informações que o <a href="http://webkay.robinlinus.com">webkay</a> pode coletar com o JavaScript ativado e desativado.</p>
+
+        <p>Navegar na Internet com o JavaScript desabilitado e habilitá-lo apenas se necessário ajuda muito a proteger a privacidade.
+            Além disso, o JavaScript é usado para carregar muitos dos anúncios irritantes e lixo extra que vem junto com a maioria dos sites modernos.
+            Com ele desabilitado, os sites carregam mais rápido, consomem menos tráfego de rede e usam menos energia da CPU, o que aumenta a vida útil da bateria.</p>
     </body>
 </html>
\ No newline at end of file
index a4db74a4d93afe0ba632ccf235844e9edaf5c9e5..d10f895c8237652c55f85ce95b74dbc9e5908af4 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> First-Party Cookies</h3>
+        <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Cookies primários</h3>
 
-        <p>First-party cookies are set by the website in the URL bar at the top of the page.</p>
+        <p>Os cookies primários são definidos pelo site na barra de URL na parte superior da página.</p>
 
-        <p>From the early days of the internet, it became obvious that it would be advantageous for websites to be able to store information on a computer for future access.
-            For example, a website that displays weather information could ask the user for a zip code, and then store it in a cookie.
-            The next time the user visited the website, weather information would automatically load for that zip code, without the user having to enter it again.</p>
+        <p>Desde os primórdios da Internet, tornou-se óbvio que seria vantajoso para os sites a capacidade de armazenar informações em um computador para acesso futuro.
+            Por exemplo, um site que exibe informações meteorológicas pode solicitar ao usuário um CEP e armazená-lo em um cookie.
+            Na próxima vez que o usuário visitar o site, as informações meteorológicas serão carregadas automaticamente para aquele CEP, sem que o usuário tenha que digitá-lo novamente.</p>
 
-        <p>Like everything else on the web, clever people figured out all types of ways to abuse cookies to do things that users would not approve of if they knew they were happening.
-            For example, a website can set a cookie with a unique serial number on a device.
-            Then, every time a user visits the website on that device, it can be linked to a unique profile the server maintains for that serial number,
-            even if the device connects from different IP addresses.</p>
+        <p>Como tudo na web, pessoas inteligentes descobriram todos os tipos de maneiras de abusar dos cookies para fazer coisas que os usuários não aprovariam se soubessem que estavam acontecendo.
+            Por exemplo, um site pode definir um cookie com um número de série exclusivo em um dispositivo.
+            Então, toda vez que um usuário visita o site nesse dispositivo, ele pode ser vinculado a um perfil exclusivo que o servidor mantém para aquele número de série,
+            mesmo se o dispositivo se conectar a partir de endereços IP diferentes.</p>
 
         <p>Almost all websites with logins require cookies to be enabled for a user to log in.
             That is how they make sure it is still you as you move from page to page on the site, and is, in my opinion, the only legitimate use for cookies.</p>
@@ -48,7 +48,7 @@
         <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>
 
 
-        <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Third-Party Cookies</h3>
+        <h3><svg class="header"><use href="../shared_images/cookie.svg#icon"/></svg> Cookies de terceiros</h3>
 
         <p>Third-party cookies are set by portions of a website that are loaded from servers different from the URL at the top of the page.
             There is no good reason to ever enable third-party cookies. Privacy Browser 3.8 removed the option, and even Google is planning to
             between first-party and third-party cookies</a>. Thus, enabling cookies will also enable third-party cookies.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/web.svg#icon"/></svg> DOM Storage</h3>
+        <h3><svg class="header"><use href="../shared_images/web.svg#icon"/></svg> Armazenamento DOM</h3>
 
-        <p>Document Object Model storage, also known as web storage, is like cookies on steroids. Whereas the maximum combined storage size for all cookies from a single URL is 4 kilobytes,
-            DOM storage can hold <a href="https://en.wikipedia.org/wiki/Web_storage#Features">megabytes per site</a>. Unlike cookies, DOM storage does not send all the data in the headers with every request.
+        <p>O armazenamento do Document Object Model, também conhecido como armazenamento na web, é como cookies com esteróides.
+            Considerando que o tamanho máximo de armazenamento combinado para todos os cookies de um único URL é de 4 kilobytes,
+            O armazenamento DOM pode conter <a href="https://en.wikipedia.org/wiki/Web_storage#Features">megabytes por site</a>.
+            Unlike cookies, DOM storage does not send all the data in the headers with every request.
             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>
+        <h3><svg class="header"><use href="../shared_images/subtitles.svg#icon"/></svg> Dados do Formulário</h3>
 
-        <p>Form data contains information typed into web forms, like user names, 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>
+        <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>
     </body>
 </html>
\ No newline at end of file
index 05e0c851d87245793ff740069334567b905a8395..6f2dd09cee51eb6a9e0e04fd8e3e63d99aae3501 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/visibility_off.svg#icon"/></svg> True Privacy</h3>
+        <h3><svg class="header"><use href="../shared_images/visibility_off.svg#icon"/></svg> Verdadeira Privacidade</h3>
 
-        <p>The only way to prevent data from being abused is to prevent it from being collected in the first place.
-            When a browser connects to a website, certain pieces of information which are necessary to facilitate the connection are transferred to the server.
-            For example, the server will receive your IP address and a port number, which are necessary for it to know where to send the response.
-            This information is often logged by the server, allowing the website developer to produce reports showing how often a webpage was loaded and how many different IP addresses accessed it.</p>
+        <p>A única maneira de evitar que os dados sejam abusados é impedir que eles sejam coletados em primeiro lugar.
+            Quando um navegador se conecta a um site, certas informações necessárias para facilitar a conexão são transferidas para o servidor.
+            Por exemplo, o servidor receberá seu endereço IP e um número de porta, necessários para saber para onde enviar a resposta.
+            Essas informações geralmente são registradas pelo servidor,
+            permitindo que o desenvolvedor do site produza relatórios que mostram com que frequência uma página da web foi carregada e quantos endereços IP diferentes a acessaram.</p>
 
-        <p>However, most website operators want more information about their visitors, including tracking their web browsing across multiple websites.
-            There are many different techniques, including requesting or placing extra information on a user’s device, that facilitate this tracking.
-            Almost all browsers will voluntarily participate in this tracking without informing the user they are doing so.
-            Privacy Browser is designed to let you take as much control of your privacy as possible while still browsing the internet.</p>
+        <p>No entanto, a maioria dos operadores de sites deseja mais informações sobre seus visitantes, incluindo o rastreamento de sua navegação na web em vários sites.
+            Existem muitas técnicas diferentes, incluindo solicitar ou colocar informações extras no dispositivo de um usuário, que facilitam esse rastreamento.
+            Quase todos os navegadores participarão voluntariamente desse rastreamento, sem informar ao usuário que estão fazendo isso.
+            O Privacy Browser foi projetado para permitir que você tenha o máximo de controle possível sobre sua privacidade enquanto navega na Internet.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/chrome_reader_mode.svg#icon"/></svg> Android’s WebView Limitations</h3>
+        <h3><svg class="header"><use href="../shared_images/chrome_reader_mode.svg#icon"/></svg> Limitações do WebView do Android</h3>
 
-        <p>Privacy Browser uses Android’s built-in WebView to render websites. There are some limitations in the controls WebView exposes for managing privacy settings.
-            For example, it isn’t possible to enable some JavaScript commands while disabling others.
-            In the future, Privacy Browser will switch to a custom WebView called <a href="https://www.stoutner.com/category/roadmap/">Privacy WebView</a>.</p>
+        <p>O Privacy Browser usa o WebView integrado do Android para renderizar sites. Existem algumas limitações nos controles que o WebView expõe para gerenciar as configurações de privacidade.
+            Por exemplo, não é possível habilitar alguns comandos JavaScript enquanto outros desabilitam.
+            No futuro, o Privacy Browser mudará para um WebView personalizado chamado <a href="https://www.stoutner.com/category/roadmap/">Privacy WebView</a>.</p>
     </body>
 </html>
\ No newline at end of file
index 8c8afd1bc397c2d24938001ba31c0564260c5b00..12f4629b1d039f50edcb354265a43c99112e974a 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/vpn_key.svg#icon"/></svg> Proxies and Their Limits</h3>
+        <h3><svg class="header"><use href="../shared_images/vpn_key.svg#icon"/></svg> Proxies e seus limites</h3>
 
-        <p>There are two general categories of bad actors that want to infringe on the privacy of the web:
-            malicious governments with access to ISPs (Internet Service Providers) and mega corporations that run social and advertising networks.
-            Proxies like TOR (The Onion Router) and I2P (the Invisible Internet Project) are useful in protecting privacy from malicious governments (which spy on traffic in transit)
-            but not from mega corporations (which embed malicious code on web servers).</p>
+        <p>Existem duas categorias gerais de agentes mal-intencionados que desejam violar a privacidade da web:
+            governos maliciosos com acesso a ISPs (Provedores de Serviços de Internet) e megacorporações que administram redes sociais e de publicidade.
+            Proxies como TOR (The Onion Router) e I2P (Invisible Internet Project) são úteis para proteger a privacidade de governos maliciosos (que espionam o tráfego em trânsito)
+            mas não de megacorporações (que incorporam código malicioso em servidores da web).</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/language.svg#icon"/></svg> Malicious Governments</h3>
+        <h3><svg class="header"><use href="../shared_images/language.svg#icon"/></svg> Governos Maliciosos</h3>
 
-        <p>Malicious governments often spy on their citizens to punish dissent or human rights activity.
-            They commonly either operate the local ISPs or they can force them to disclose information showing every IP address that is visited by each user.
-            Layered proxies are designed to defeat this infringement of privacy by encrypting the traffic from a user’s device and routing it through multiple servers on the internet
-            before sending it on to the final destination.
-            This means that no individual ISP, server, or website, can know both the <a href="https://ipleak.net">IP address of the user’s device</a> and the IP address of the final web server.
-            Malicious governments and the ISPs they control cannot tell which web servers a user is accessing, although they can tell that the user is using a layered proxy service.
-            In some parts of the world, using proxies could be construed as an evidence of illegal behavior (“If you didn’t have anything to hide you wouldn’t be encrypting your traffic”)
-            and users could be punished because governments assume they are doing something that is prohibited. Thus, proxies can be helpful, but they aren’t a panacea.</p>
+        <p>Governos mal-intencionados freqüentemente espionam seus cidadãos para punir dissidentes ou atividades de direitos humanos.
+            Eles geralmente operam os ISPs locais ou podem forçá-los a divulgar informações mostrando todos os endereços IP visitados por cada usuário.
+            Proxies em camadas são projetados para derrotar essa violação de privacidade criptografando o tráfego do dispositivo de um usuário e roteando-o por meio de vários servidores na Internet
+            antes de enviá-lo para o destino final.
+            Isso significa que nenhum ISP, servidor ou site individual pode saber o <a href="https://ipleak.net">endereço IP do dispositivo do usuário</a> e o endereço IP do servidor web final.
+            Governos mal-intencionados e os ISPs que eles controlam não podem dizer quais servidores da web um usuário está acessando,
+            embora possam dizer que o usuário está usando um serviço de proxy em camadas.
+            Em algumas partes do mundo, o uso de proxies pode ser interpretado como uma evidência de comportamento ilegal (“Se você não tivesse nada a esconder, não estaria criptografando seu tráfego”)
+            e os usuários podem ser punidos porque os governos presumem que eles estão fazendo algo que é proibido. Assim, os proxies podem ser úteis, mas não são uma panacéia.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/language.svg#icon"/></svg> Mega Corporations</h3>
+        <h3><svg class="header"><use href="../shared_images/language.svg#icon"/></svg> Mega Corporações</h3>
 
-        <p>When a user connects to a web server, the web server can see the user’s IP address.
-            Although it isn’t a perfect science, IP addresses can be turned into physical addresses with a <a href="https://www.whatismyip.com/">fair amount of accuracy</a>.
-            Small web servers typically rely on IP addresses to identify the location of the users visiting their site. Proxies are a good solution to mask the user’s location from these servers.
-            But large mega corporations that own social media and advertising networks use a whole profile of information that is designed to track users across devices and IP addresses.
-            These profiles employ a variety of techniques to identify users, including JavaScript, cookies, tracking IDs, and <a href="https://panopticlick.eff.org/">browser fingerprinting</a>.
-            Because the vast majority of the websites on the internet either load an ad from one of the major networks or embed social media icons with their associated JavaScript,
-            these corporations have built profiles for almost every online user and can track their internet activity across unrelated sites.</p>
+        <p>Quando um usuário se conecta a um servidor web, o servidor web pode ver o endereço IP do usuário.
+            Embora não seja uma ciência perfeita, os endereços IP podem ser transformados em endereços físicos com uma <a href="https://www.whatismyip.com/">quantidade razoável de precisão</a>.
+            Os pequenos servidores da web geralmente dependem de endereços IP para identificar a localização dos usuários que visitam seu site.
+            Os proxies são uma boa solução para mascarar a localização do usuário desses servidores.
+            Mas as grandes megacorporações que possuem mídia social e redes de publicidade usam todo um perfil de informações que é projetado para rastrear usuários em dispositivos e endereços IP.
+            Esses perfis empregam uma variedade de técnicas para identificar usuários,
+            incluindo JavaScript, cookies, IDs de rastreamento e <a href="https://panopticlick.eff.org/">impressão digital do navegador</a>.
+            Como a grande maioria dos sites na Internet carrega um anúncio de uma das principais redes ou incorpora ícones de mídia social com seu JavaScript associado,
+            essas empresas criaram perfis para quase todos os usuários on-line e podem rastrear suas atividades na Internet em sites não relacionados.</p>
 
-        <p>They track every site that is visited, everything that is purchased, every credit card that is used to make a purchase, every address that items are shipped to,
-            and the GPS metadata of every picture that is uploaded to the internet.
-            They build a profile of a user’s age, gender, marital status, address, political affiliations, religious affiliations, family circumstances, number of pets,
-            and everything else they can get their hands on.
-            They even buy up databases of credit card transactions at local stores, so they can track the off-line purchasing patterns of the users in their profiles.
-            Because they already have much more accurate address information about a user than an IP address discloses, proxies provides no real privacy protection against mega corporations.</p>
+        <p>Eles rastreiam cada site visitado, tudo o que é comprado, cada cartão de crédito usado para fazer uma compra, cada endereço para onde os itens são enviados,
+            e os metadados de GPS de cada imagem enviada para a Internet.
+            Eles constroem um perfil de idade, sexo, estado civil, endereço, afiliações políticas, afiliações religiosas, circunstâncias familiares, número de animais de estimação do usuário,
+            e tudo o mais que eles possam ter em suas mãos.
+            Eles até compram bancos de dados de transações de cartão de crédito em lojas locais, para que possam rastrear os padrões de compra off-line dos usuários em seus perfis.
+            Como eles já têm informações de endereço muito mais precisas sobre um usuário do que as divulgadas por um endereço IP, os proxies não oferecem proteção real à privacidade contra megacorporações.</p>
 
-        <p>The single best privacy protection against mega corporations is to browse the web with JavaScript disabled, followed by blocking ad networks, disabling cookies and DOM storage,
-            and using a browser that is difficult to fingerprint.</p>
+        <p>A melhor proteção de privacidade contra megacorporações é navegar na web com o JavaScript desabilitado, seguido pelo bloqueio de redes de anúncios, desabilitando cookies e armazenamento DOM,
+            e usando um navegador de difícil impressão digital.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/open_in_browser.svg#icon"/></svg> Using Proxies</h3>
+        <h3><svg class="header"><use href="../shared_images/open_in_browser.svg#icon"/></svg> Usando Proxies</h3>
 
-        <p>Despite their limitations, proxies can be useful in some circumstances.
-            <a href="https://play.google.com/store/apps/details?id=org.torproject.android">Tor</a> and <a href="https://f-droid.org/en/packages/net.i2p.android.router/">I2P</a>
-            have Android apps that make it easy to use their proxy networks. When proxying is turned on in Privacy Browser, the app bar will have a light blue background instead of the default light grey.
-            Because traffic is being routed through several proxy nodes, using a layered proxy is often much slower than connecting directly to the internet.</p>
+        <p>Apesar de suas limitações, os proxies podem ser úteis em algumas circunstâncias.
+            <a href="https://play.google.com/store/apps/details?id=org.torproject.android">Tor</a> e <a href="https://f-droid.org/en/packages/net.i2p.android.router/">I2P</a>
+            têm aplicativos Android que facilitam o uso de suas redes proxy. Quando o proxy está ativado no Navegador de privacidade, a barra de aplicativos terá um fundo azul claro em vez do cinza claro padrão.
+            Como o tráfego está sendo roteado por vários nós de proxy, usar um proxy em camadas costuma ser muito mais lento do que conectar-se diretamente à Internet.</p>
 
         <img class="center" src="images/tor.png"/>
     </body>
index c98e136a49ce68b35f76a835dd0ce184c5456250..4ec9b174aa88d02b11358dec584f6965a034bd82 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/local_activity.svg#icon"/></svg> Resource Requests</h3>
+        <h3><svg class="header"><use href="../shared_images/local_activity.svg#icon"/></svg> Solicitação de recursos</h3>
 
-        <p>When a URL is loaded, it typically makes a number of resource requests for CCS, JavaScript, image, and other files. Details about these requests can be viewed in the Requests activity.
-            The navigation drawer has a link to the Requests activity and also shows how many requests were blocked. Tapping on a request displays details about why it was allowed or blocked.</p>
+        <p>Quando um URL é carregado, ele normalmente faz várias solicitações de recursos para CCS, JavaScript, imagem e outros arquivos.
+            Os detalhes sobre essas solicitações podem ser visualizados na atividade Solicitações.
+            A gaveta de navegação possui um link para a atividade Solicitações e também mostra quantas solicitações foram bloqueadas.
+            Tocar em uma solicitação exibe detalhes sobre por que ela foi permitida ou bloqueada.</p>
 
-        <img class="center" src="images/request_details.png"/>
+        <img class="center216" src="images/request_details.png"/>
 
-        <p>Privacy Browser includes four <a href="https://easylist.to/">common blocklists</a> based on the <a href="https://adblockplus.org/filters">Adblock syntax</a>:
-            EasyList, EasyPrivacy, Fanboy’s Annoyance List, and Fanboy’s Social Blocking List.
-            These blocklists are processed by Privacy Browser into the following 22 sublists, which check resource requests in the order listed.</p>
+        <p>O Privacy Browser inclui quatro <a href="https://easylist.to/">listas de bloqueio comuns</a> com base na <a href="https://adblockplus.org/filters">sintaxe do Adblock</a>:
+            EasyList, EasyPrivacy, Fanboy’s Annoyance List e Fanboy’s Social Blocking List.
+            Essas listas de bloqueio são processadas pelo Privacy Browser nas seguintes 22 sublistas, que verificam as solicitações de recursos na ordem listada.</p>
 
         <ol>
-            <li>Main Whitelist</li>
-            <li>Final Whitelist</li>
-            <li>Domain Whitelist</li>
-            <li>Domain Initial Whitelist</li>
-            <li>Domain Final Whitelist</li>
-            <li>Third-Party Whitelist</li>
-            <li>Third-Party Domain Whitelist</li>
-            <li>Third-Party Domain Initial Whitelist</li>
-            <li>Main Blacklist</li>
-            <li>Initial Blacklist</li>
-            <li>Final Blacklist</li>
-            <li>Domain Blacklist</li>
-            <li>Domain Initial Blacklist</li>
-            <li>Domain Final Blacklist</li>
-            <li>Domain Regular Expression Blacklist</li>
-            <li>Third-Party Blacklist</li>
-            <li>Third-Party Initial Blacklist</li>
-            <li>Third-Party Domain Blacklist</li>
-            <li>Third-Party Domain Initial Blacklist</li>
-            <li>Third-Party Regular Expression Blacklist</li>
-            <li>Third-Party Domain Regular Expression Blacklist</li>
-            <li>Regular Expression Blacklist</li>
+            <li>Lista de permissão principal</li>
+            <li>Lista de permissões final</li>
+            <li>Lista de permissões de domínio</li>
+            <li>Lista de permissões inicial do domínio</li>
+            <li>Lista de permissões final de domínio</li>
+            <li>Lista de permissões de terceiros</li>
+            <li>Lista de permissões de domínios de terceiros</li>
+            <li>Lista de permissões iniciais de domínios de terceiros</li>
+            <li>Lista de restrições principal</li>
+            <li>Lista de restrições inicial</li>
+            <li>Lista de restrições final</li>
+            <li>Lista de restrições de domínios</li>
+            <li>Lista de restrições inicial do domínio</li>
+            <li>Lista de restrições final do domínio</li>
+            <li>Lista de restrições de expressões regulares de domínio</li>
+            <li>Lista de restrições de terceiros</li>
+            <li>Lista de restrições inicial de terceiros</li>
+            <li>Lista de restrições de domínios de terceiros</li>
+            <li>Lista de restrições inicial de domínios de terceiros</li>
+            <li>Lista de restrições de expressões regulares de terceiros</li>
+            <li>Lista de restrições de expressões regulares de domínios de terceiros</li>
+            <li>Lista de restrições de expressões regulares</li>
         </ol>
 
-        <p>Initial lists check against the beginning of the URL. Final lists check against the end of the URL. Domain lists only check against certain domains.
-            Third-party lists only apply if the root domain of the request is different than the root domain of the main URL.
-            Regular expression lists follow the <a href="https://en.wikipedia.org/wiki/Regular_expression">regular expression syntax</a>. Each sublist item has one or more entry.
-            In the case of domain sublists, the resource request is only checked against the item if the first entry matches the domain of the main URL.</p>
-
-        <p>Because of limitations in Android’s WebView, and to speed up processing of requests, Privacy Browser implements a simplified interpretation of the Adblock syntax.
-            This can sometimes lead to false positives, where resources are allowed or blocked in ways that weren’t intended by the original entry.
-            A more detailed description of how the blocklist entries are processed is available at <a href="https://www.stoutner.com/privacy-browser/blocklists/">stoutner.com</a>.</p>
-
-        <p>Privacy Browser has three additional blocklists.
-            <a href="https://www.stoutner.com/privacy-browser/blocklists/ultralist/">UltraList</a> and <a href="https://www.stoutner.com/privacy-browser/blocklists/ultraprivacy/">UltraPrivacy</a>
-            block ads and trackers that EasyList and EasyPrivacy do not. The third blocks all third-party requests.
-            A request is only considered third-party if the base domain of the request is different than the base domain of the URL.
-            For example, if <code>www.website.com</code> loads a picture from <code>images.website.com</code>,
-            this is not blocked as a third-party request because they both share the same base domain of <code>website.com</code>.
-            Blocking all third-party requests increases privacy, but this blocklist is disabled by default because it breaks a large number of websites.</p>
+        <p>As listas iniciais são comparadas ao início do URL. As listas finais são comparadas ao final do URL. As listas de domínio verificam apenas em alguns domínios.
+            As listas de terceiros só se aplicam se o domínio raiz da solicitação for diferente do domínio raiz do URL principal.
+            Listas de expressões regulares seguem a <a href="https://en.wikipedia.org/wiki/Regular_expression">sintaxe de expressão regular</a>. Cada item da sublista possui uma ou mais entradas.
+            No caso de sublistas de domínio, a solicitação de recurso só é verificada em relação ao item se a primeira entrada corresponder ao domínio do URL principal.</p>
+
+        <p>Por causa das limitações no WebView do Android e para acelerar o processamento de solicitações, o Privacy Browser implementa uma interpretação simplificada da sintaxe Adblock.
+            Isso às vezes pode levar a falsos positivos, em que os recursos são permitidos ou bloqueados de maneiras que não eram pretendidas pela entrada original.
+            Uma descrição mais detalhada de como as entradas da lista de bloqueio são processadas está disponível em <a href="https://www.stoutner.com/privacy-browser/blocklists/">stoutner.com</a>.</p>
+
+        <p>O Privacy Browser tem três listas de bloqueio adicionais.
+            <a href="https://www.stoutner.com/privacy-browser/blocklists/ultralist/">UltraList</a> e <a href="https://www.stoutner.com/privacy-browser/blocklists/ultraprivacy/">UltraPrivacy</a>
+            bloqueiam anúncios e rastreadores que EasyList e EasyPrivacy não bloqueiam. O terceiro bloqueia todas as solicitações de terceiros.
+            Uma solicitação só é considerada de terceiros se o domínio base da solicitação for diferente do domínio base da URL.
+            Por exemplo, se <code>www.website.com</code> carregar uma imagem de <code>images.website.com</code>,
+            isso não é bloqueado como uma solicitação de terceiros porque ambos compartilham o mesmo domínio base de <code>website.com</code>.
+            Bloquear todas as solicitações de terceiros aumenta a privacidade, mas essa lista de bloqueio é desabilitada por padrão porque quebra um grande número de sites.</p>
     </body>
 </html>
\ No newline at end of file
index 2eb815c5991c4f593d278d5df7de043830a5b064..ab985bd9daf5b655b6f79f62065359d1a57a33f9 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/vpn_lock.svg#icon"/></svg> Connect with Confidence</h3>
+        <h3><svg class="header"><use href="../shared_images/vpn_lock.svg#icon"/></svg> Conecte-se com Confiança</h3>
 
-        <p>When visiting an encrypted URL (one that begins with HTTPS), the webserver uses an SSL certificate to both encrypt the information sent to the browser and to identify the server.
-            The purpose of the server identification is to prevent a machine located between the browser and the webserver from pretending to be the server and decrypting the information in transit.
-            This type of attack is known as a Man In The Middle (MITM) attack.
-            SSL certificates are generated by certificate authorities: companies that verify a server’s identity and produce a certificate for a fee.
-            Android has a list of trusted certificate authorities, and will accept any of their certificates for any website.
-            It isn’t supposed to be possible for an organization to acquire an SSL certificate for a domain they do not control,
-            but in practice many governments and large corporations have been able to do so.</p>
+        <p>Ao visitar um URL criptografado (que começa com HTTPS), o servidor da web usa um certificado SSL para criptografar as informações enviadas para o navegador e para identificar o servidor.
+            O objetivo da identificação do servidor é evitar que uma máquina localizada entre o navegador e o servidor da web finja ser o servidor e descriptografe as informações em trânsito.
+            Esse tipo de ataque é conhecido como ataque Man In The Middle (MITM).
+            Os certificados SSL são gerados por autoridades de certificação: empresas que verificam a identidade de um servidor e produzem um certificado por uma taxa.
+            O Android tem uma lista de autoridades de certificação confiáveis e aceitará qualquer um de seus certificados para qualquer site.
+            Não deveria ser possível para uma organização adquirir um certificado SSL para um domínio que ela não controla,
+            mas, na prática, muitos governos e grandes corporações têm sido capazes de fazê-lo.</p>
 
-        <p>Pinning an SSL certificate tells the browser that only one specific SSL certificate is to be trusted for a particular domain. Any other certificate, even if it is valid, will be rejected.</p>
+        <p>Fixar um certificado SSL informa ao navegador que apenas um certificado SSL específico é confiável para um determinado domínio. Qualquer outro certificado, mesmo que seja válido, será rejeitado.</p>
 
-        <img class="center" src="images/pinned_mismatch.png"/>
+        <img class="center216" src="images/pinned_mismatch.png"/>
 
-        <p>SSL certificates expire on a specified date, so even pinned SSL certificates will legitimately need to be updated from time to time.
-            As a general rule, pinning SSL certificates probably isn’t needed in the majority of cases.
-            But for those who suspect that powerful organizations may be targeting them, SSL certificate pinning can detect and thwart a MITM attack.
-            Privacy Browser also has the ability to pin IP addresses.</p>
+        <p>Os certificados SSL expiram em uma data especificada, portanto, mesmo os certificados SSL fixados precisarão ser atualizados de vez em quando.
+            Como regra geral, fixar certificados SSL provavelmente não é necessário na maioria dos casos.
+            Mas, para aqueles que suspeitam que organizações poderosas podem estar almejando-os, a fixação de certificado SSL pode detectar e impedir um ataque MITM.
+            O Privacy Browser também tem a capacidade de fixar endereços IP.</p>
 
-        <img class="center" src="images/pinned_ssl_certificate.png"/>
+        <img class="center216" src="images/pinned_ssl_certificate.png"/>
 
-        <p>SSL certificates can be pinned in Domain Settings.
-            Besides protecting against MITM attacks,
-            pinning a self-signed certificate for a device like a wireless router or access point will remove the error message that is normally presented every time its website is loaded.
-            Tapping on the active tab displays the current website SSL certificate.</p>
+        <p>Os certificados SSL podem ser fixados nas configurações do domínio.
+            Além de proteger contra ataques MITM,
+            fixar um certificado autoassinado para um dispositivo como um roteador sem fio ou ponto de acesso removerá a mensagem de erro que normalmente é apresentada sempre que o site é carregado.
+            Tocar na guia ativa exibe o certificado SSL do site atual.</p>
     </body>
 </html>
\ No newline at end of file
index 131d546c9ed049eb34f8442690e5dc1c256887b1..959569a02d5d6fb63829f739460eea463d52cf3e 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/location_off.svg#icon"/></svg> Do Not Track</h3>
+        <h3><svg class="header"><use href="../shared_images/location_off.svg#icon"/></svg> Não Rastreie</h3>
 
-        <p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
-            This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.</p>
+        <p>Há alguns anos, o W3C (World Wide Web Consortium) criou um mecanismo para os navegadores informarem aos servidores web que eles não gostariam de ser rastreados.
+            Isso é feito incluindo um <a href="https://en.wikipedia.org/wiki/Do_Not_Track">cabeçalho DNT (Do Not Track)</a> com solicitações da web.</p>
 
-        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
+        <p>O cabeçalho DNT realmente não fornece nenhuma privacidade porque a maioria dos servidores da web o ignora.
+            Por exemplo, Yahoo, Google, Microsoft e Facebook ignoram pelo menos alguns cabeçalhos DNT.
+            Beginning with version 3.8, Privacy Browser no longer has the option to send a DNT header.</p>
 
 
-        <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> URL Modification</h3>
+        <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> Modificação de URL</h3>
 
-        <p>Privacy Browser removes tracking ID sections of URLs, like <code>?utm_</code> from <a href="https://support.google.com/analytics/answer/1033867">Google Analytics</a> and
-            <code>?fbclick=</code> from <a href="https://fbclid.com/">Facebook</a>. URL modification can be turned off in the settings if it is causing issues.</p>
+        <p>O Privacy Browser remove as seções de ID de rastreamento de URLs, como <code>?utm_</code> do <a href="https://support.google.com/analytics/answer/1033867">Google Analytics</a>
+            e <code>?fbclick=</code> do <a href="https://fbclid.com/">Facebook</a>. A modificação de URL pode ser desativada nas configurações se estiver causando problemas.</p>
     </body>
 </html>
\ No newline at end of file
index 2b37d050972c2ed7b4d466877cfbe94d336bcbf7..ef26a3c5e3d98dc731d9e60decafc5d6ff051fc4 100644 (file)
     </head>
 
     <body>
-        <h3><svg class="header"><use href="../shared_images/devices_other.svg#icon"/></svg> Browser Identification</h3>
+        <h3><svg class="header"><use href="../shared_images/devices_other.svg#icon"/></svg> Identificação do Navegador</h3>
 
-        <p>When web browsers connect to websites, they send a user agent, which identifies the browser and the rendering capabilities it possesses.
-            The web server can use this information to decide which version of the website to send to the browser.
-            For example, many websites have different versions for desktop and mobile browsers.</p>
+        <p>Quando os navegadores da web se conectam a sites, eles enviam um agente do usuário, que identifica o navegador e os recursos de renderização que possui.
+            O servidor da web pode usar essas informações para decidir qual versão do site enviar para o navegador.
+            Por exemplo, muitos sites têm versões diferentes para navegadores de desktop e móveis.</p>
 
-        <p>By default, Privacy Browser uses its own user agent, which is <code>PrivacyBrowser/1.0</code>. This sends a minimum of information to the web server.
-            Because web servers do not recognize this to be a mobile user agent, they typically display the desktop version of the site.</p>
+        <p>Por padrão, o Privacy Browser usa seu próprio agente de usuário, que é <code>PrivacyBrowser/1.0</code>. Isso envia um mínimo de informações para o servidor da web.
+            Como os servidores da web não reconhecem este como um agente de usuário móvel, eles geralmente exibem a versão desktop do site.</p>
 
-        <p>By comparison, WebView’s default user agent divulges a large amount of information about the hardware and software of the device.
-            On the <strong>Settings</strong> screen, selecting <strong>WebView Default</strong> as the <strong>User agent</strong> displays the user agent that will be sent.
-            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>
+        <p>Em comparação, o agente de usuário padrão do WebView divulga uma grande quantidade de informações sobre o hardware e software do dispositivo.
+            Na tela <strong>Configurações</strong>, selecionar <strong>WebView Padrão</strong> como o <strong>Agente do usuário</strong> exibe o agente do usuário que será enviado.
+            A captura de tela abaixo mostra um Pixel 5 rodando Android 11 com Android System WebView 90.0.4430.210 instalado.
+            A maioria dos servidores da web o reconhecerá como um navegador móvel e exibirá a versão móvel do site, se houver.</p>
 
-        <img class="center" src="images/user_agent.png">
+        <img class="center216" src="images/user_agent.png">
 
-        <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.
-            The Electronic Frontier Foundation created a tool called <a href="https://panopticlick.eff.org/">Panopticlick</a> to demonstrate how much information can be gleaned from these sources.
-            If this test is run with JavaScript enabled the amount of information that is disclosed increases greatly.
-            <a href="https://www.browserleaks.com">Browser Leaks</a> and <a href="https://amiunique.org/">Am I Unique</a> are also good sources of information on this topic.</p>
+        <p>Há informações suficientes no agente do usuário para queapenas para alguns visitantes de um site, às vezes, sejam os mesmos.
+            Se o agente do usuário for combinado com outra informação de identificação não exclusiva, geralmente resulta em uma impressão digital exclusiva.
+            A Electronic Frontier Foundation criou uma ferramenta chamada <a href="https://panopticlick.eff.org/">Panopticlick</a> para demonstrar quanta informação pode ser obtida dessas fontes.
+            Se este teste for executado com o JavaScript habilitado, a quantidade de informações divulgadas aumenta muito.
+            <a href="https://www.browserleaks.com">Browser Leaks</a> e <a href="https://amiunique.org/">Am I Unique</a> também são boas fontes de informações sobre este tópico.</p>
 
         <img class="center" src="../shared_images/panopticlick.png">
 
-        <p>There are several preset user agents that match common browsers and operating systems. For browser fingerprinting purposes, anything that is rare is easier to track.
-            If Privacy Browser becomes common and many people use <code>PrivacyBrowser/1.0</code> as their user agent, it will be a good choice for privacy.
-            Firefox or Chrome are the most common user agents, but they auto-update and their version numbers change so quickly that it is likely the user agents included in Privacy Browser
-            will often be out of step with the majority of user agents in the server logs.</p>
+        <p>Existem vários agentes de usuário predefinidos que correspondem a navegadores e sistemas operacionais comuns.
+            Para fins de impressão digital do navegador, qualquer coisa rara é mais fácil de rastrear.
+            Se o Privacy Browser se tornar comum e muitas pessoas usarem <code>PrivacyBrowser/1.0</code> como seu agente de usuário, será uma boa escolha para privacidade.
+            Firefox ou Chrome são os agentes de usuário mais comuns, mas eles se atualizam automaticamente e seus números de versão mudam tão rapidamente que provavelmente os agentes de usuário
+            incluídos no Privacy Browser frequentemente estará fora de sincronia com a maioria dos agentes de usuário nos logs do servidor.</p>
 
-        <p>Some websites <a href="https://www.stoutner.com/user-agent-problems/">do not function correctly</a> if they do not recognize the user agent.
-            Using domain settings to set the user agent to <strong>WebView Default</strong>, or another user agent that is commonly recognized, usually resolves the problem.
-            Android’s WebView does not allow the user agent to be blank. If it is, WebView simply sends the default user agent to the server.</p>
+        <p>Alguns sites <a href="https://www.stoutner.com/user-agent-problems/">não funcionam corretamente</a> se não reconhecem o agente do usuário.
+            Usar as configurações de domínio para definir o agente do usuário para <strong>WebView Padrão</strong>ou outro agente do usuário comumente reconhecido geralmente resolve o problema.
+            O WebView do Android não permite que o agente do usuário fique em branco. Se for, o WebView simplesmente envia o agente do usuário padrão para o servidor.</p>
     </body>
 </html>
\ No newline at end of file
index 2260078e4001e0efbb8ab88dfffd046a2a66de36..6d58b459a108792394798391cae9608a623becce 100644 (file)
Binary files a/app/src/main/assets/pt-rBR/images/domain_settings.png and b/app/src/main/assets/pt-rBR/images/domain_settings.png differ
index 4b4c4e695919a48a13dca56468116917f088dd0a..cc323249afb5c88b0c2e44cfce64b48d0360bdbd 100644 (file)
Binary files a/app/src/main/assets/pt-rBR/images/pinned_mismatch.png and b/app/src/main/assets/pt-rBR/images/pinned_mismatch.png differ
index 53dad09c268aaa08b139e76bdc4fec60c6a16eb3..f112b7f925f07802e0d5cc301850d895e5c77cff 100644 (file)
Binary files a/app/src/main/assets/pt-rBR/images/pinned_ssl_certificate.png and b/app/src/main/assets/pt-rBR/images/pinned_ssl_certificate.png differ
index f3265f60a23c0409ea202c6f6a5217c6f39117e2..aff29ff6650cc72417e7f5dbf22fa5c6b7a4eab7 100644 (file)
Binary files a/app/src/main/assets/pt-rBR/images/request_details.png and b/app/src/main/assets/pt-rBR/images/request_details.png differ
index 6233e803f365bebf7f007068c4b69d1a8cd9b5a0..92947f0942e7b0c0699095543c4d424f6276aa21 100644 (file)
Binary files a/app/src/main/assets/pt-rBR/images/user_agent.png and b/app/src/main/assets/pt-rBR/images/user_agent.png differ
index f1fc5b94aaafd21fd09f1c5857ceb0880a8757c8..ff41a90145398bb53a2da364ef5092cb360744b1 100644 (file)
@@ -36,6 +36,6 @@
 
         <p>При посещении домена, для которого определены настройки, фон поля URL становится зеленым.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png"/>
+        <img class="center216" src="../shared_images/green_url_bar.png"/>
     </body>
 </html>
\ No newline at end of file
index 9151924b40b2c01d19fcfa5a19fa1351c4f48fc6..038d16bb894081d5fb76f02e66d443a73f4fca05 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-  Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -33,7 +33,8 @@
             Это достигается путем включения <a href="https://en.wikipedia.org/wiki/Do_Not_Track"> заголовка DNT (Не отслеживать) </a> в веб-запросы.</p>
 
         <p>Заголовок DNT на самом деле не обеспечивает большую конфиденциальность, поскольку большинство веб-серверов его игнорируют.
-            Например, Yahoo, Google, Microsoft и Facebook игнорируют, по крайней мере, некоторые заголовки DNT.</p>
+            Например, Yahoo, Google, Microsoft и Facebook игнорируют, по крайней мере, некоторые заголовки DNT.
+            Beginning with version 3.8, Privacy Browser no longer has the option to send a DNT header.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> Модификация URL</h3>
index c457571ecf0eff6c23fb9d329306808da9eb57d8..2159de1d3c982ab36a54692de51a71bc275f8dcc 100644 (file)
Binary files a/app/src/main/assets/shared_images/green_url_bar.png and b/app/src/main/assets/shared_images/green_url_bar.png differ
index 1b9e24ae1a111f2d5b3b9f92292e67566885ed7f..b44d694962bc593edd46b0bc3f3a102a9dd63369 100644 (file)
@@ -37,6 +37,6 @@
 
         <p>Ayarları özelleştirilmiş bir domain ziyaret edilirken, URL metin kutusunun arka planı yeşil olur.</p>
 
-        <img class="center" src="../shared_images/green_url_bar.png"/>
+        <img class="center216" src="../shared_images/green_url_bar.png"/>
     </body>
 </html>
\ No newline at end of file
index 17d6628a1b5918903afb41bf3f0cb32b75e3b9a3..3875661e8aa53d0d47878a7c02735ae555059b37 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-  Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -33,7 +33,7 @@
             Bu mekanizma, web isteklerini içeren bir başlık <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) </a> ekleyerek çalışır.</p>
 
         <p>Fakat DNT(Takip Etme) başlığı, gerçekten herhangi bir gizlilik sağlamaz, çünkü çoğu web sunucusu bunu görmezden gelir.
-            Örneğin, Yahoo, Google, Microsoft ve Facebook, en azından bazı DNT başlıklarını yok sayar.</p>
+            Örneğin, Yahoo, Google, Microsoft ve Facebook, en azından bazı DNT başlıklarını yok sayar. Beginning with version 3.8, Privacy Browser no longer has the option to send a DNT header.</p>
 
 
         <h3><svg class="header"><use href="../shared_images/link_off.svg#icon"/></svg> URL Modifikasyonu</h3>
diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java
deleted file mode 100644 (file)
index 94801fb..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
- *
- * Privacy Browser is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.stoutner.privacybrowser.activities;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.WindowManager;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.DialogFragment;
-import androidx.viewpager.widget.ViewPager;
-
-import com.google.android.material.snackbar.Snackbar;
-import com.google.android.material.tabs.TabLayout;
-
-import com.stoutner.privacybrowser.adapters.AboutPagerAdapter;
-import com.stoutner.privacybrowser.R;
-import com.stoutner.privacybrowser.asynctasks.SaveAboutVersionImage;
-import com.stoutner.privacybrowser.dialogs.SaveDialog;
-import com.stoutner.privacybrowser.fragments.AboutVersionFragment;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-
-public class AboutActivity extends AppCompatActivity implements SaveDialog.SaveListener {
-    // Declare the class variables.
-    private AboutPagerAdapter aboutPagerAdapter;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        // Get a handle for the shared preferences.
-        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
-        // Get the screenshot preference.
-        boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
-
-        // Disable screenshots if not allowed.
-        if (!allowScreenshots) {
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
-        }
-
-        // Set the theme.
-        setTheme(R.style.PrivacyBrowser);
-
-        // Run the default commands.
-        super.onCreate(savedInstanceState);
-
-        // Get the intent that launched the activity.
-        Intent launchingIntent = getIntent();
-
-        // Store the blocklist versions.
-        String[] blocklistVersions = launchingIntent.getStringArrayExtra("blocklist_versions");
-
-        // Remove the incorrect lint warning below that the blocklist versions might be null.
-        assert blocklistVersions != null;
-
-        // Set the content view.
-        setContentView(R.layout.about_coordinatorlayout);
-
-        // Get handles for the views.
-        Toolbar toolbar = findViewById(R.id.about_toolbar);
-        TabLayout aboutTabLayout = findViewById(R.id.about_tablayout);
-        ViewPager aboutViewPager = findViewById(R.id.about_viewpager);
-
-        // Set the action bar.  `SupportActionBar` must be used until the minimum API is >= 21.
-        setSupportActionBar(toolbar);
-
-        // Get a handle for the action bar.
-        final ActionBar actionBar = getSupportActionBar();
-
-        // Remove the incorrect lint warning that the action bar might be null.
-        assert actionBar != null;  //
-
-        // Display the home arrow on action bar.
-        actionBar.setDisplayHomeAsUpEnabled(true);
-
-        // Initialize the about pager adapter.
-        aboutPagerAdapter = new AboutPagerAdapter(getSupportFragmentManager(), getApplicationContext(), blocklistVersions);
-
-        // Setup the ViewPager.
-        aboutViewPager.setAdapter(aboutPagerAdapter);
-
-        // Keep all the tabs in memory.  This prevents the memory usage updater from running multiple times.
-        aboutViewPager.setOffscreenPageLimit(10);
-
-        // Connect the tab layout to the view pager.
-        aboutTabLayout.setupWithViewPager(aboutViewPager);
-    }
-
-    // The activity result is called after browsing for a file in the save alert dialog.
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent returnedIntent) {
-        // Run the default commands.
-        super.onActivityResult(requestCode, resultCode, returnedIntent);
-
-        // Only do something if the user didn't press back from the file picker.
-        if (resultCode == Activity.RESULT_OK) {
-            // Get a handle for the save dialog fragment.
-            DialogFragment saveDialogFragment = (DialogFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.save_dialog));
-
-            // Only update the file name if the dialog still exists.
-            if (saveDialogFragment != null) {
-                // Get a handle for the save dialog.
-                Dialog saveDialog = saveDialogFragment.getDialog();
-
-                // Remove the lint warning below that the dialog might be null.
-                assert saveDialog != null;
-
-                // Get a handle for the dialog view.
-                EditText fileNameEditText = saveDialog.findViewById(R.id.file_name_edittext);
-
-                // Get the file name URI from the intent.
-                Uri fileNameUri = returnedIntent.getData();
-
-                // Get the file name string from the URI.
-                String fileNameString = fileNameUri.toString();
-
-                // Set the file name text.
-                fileNameEditText.setText(fileNameString);
-
-                // Move the cursor to the end of the file name edit text.
-                fileNameEditText.setSelection(fileNameString.length());
-            }
-        }
-    }
-
-    @Override
-    public void onSave(int saveType, DialogFragment dialogFragment) {
-        // Get a handle for the dialog.
-        Dialog dialog = dialogFragment.getDialog();
-
-        // Remove the lint warning below that the dialog might be null.
-        assert dialog != null;
-
-        // Get a handle for the file name edit text.
-        EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
-
-        // Get the file name string.
-        String fileNameString = fileNameEditText.getText().toString();
-
-        // Get a handle for the about version linear layout.
-        LinearLayout aboutVersionLinearLayout = findViewById(R.id.about_version_linearlayout);
-
-        // Save the file according to the type.
-        switch (saveType) {
-            case SaveDialog.SAVE_ABOUT_VERSION_TEXT:
-                try {
-                    // Get a handle for the about version fragment.
-                    AboutVersionFragment aboutVersionFragment = (AboutVersionFragment) aboutPagerAdapter.getTabFragment(0);
-
-                    // Get the about version text.
-                    String aboutVersionString = aboutVersionFragment.getAboutVersionString();
-
-                    // Create an input stream with the contents of about version.
-                    InputStream aboutVersionInputStream = new ByteArrayInputStream(aboutVersionString.getBytes(StandardCharsets.UTF_8));
-
-                    // Create an about version buffered reader.
-                    BufferedReader aboutVersionBufferedReader = new BufferedReader(new InputStreamReader(aboutVersionInputStream));
-
-                    // Open an output stream.
-                    OutputStream outputStream = getContentResolver().openOutputStream(Uri.parse(fileNameString));
-
-                    // Create a file buffered writer.
-                    BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
-
-                    // Create a transfer string.
-                    String transferString;
-
-                    // Use the transfer string to copy the about version text from the buffered reader to the buffered writer.
-                    while ((transferString = aboutVersionBufferedReader.readLine()) != null) {
-                        // Append the line to the buffered writer.
-                        bufferedWriter.append(transferString);
-
-                        // Append a line break.
-                        bufferedWriter.append("\n");
-                    }
-
-                    // Flush the buffered writer.
-                    bufferedWriter.flush();
-
-                    // Close the inputs and outputs.
-                    aboutVersionBufferedReader.close();
-                    aboutVersionInputStream.close();
-                    bufferedWriter.close();
-                    outputStream.close();
-
-                    // Display a snackbar with the saved about version information.
-                    Snackbar.make(aboutVersionLinearLayout, getString(R.string.file_saved) + "  " + fileNameString, Snackbar.LENGTH_SHORT).show();
-                } catch (Exception exception) {
-                    // Display a snackbar with the error message.
-                    Snackbar.make(aboutVersionLinearLayout, getString(R.string.error_saving_file) + "  " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show();
-                }
-                break;
-
-            case SaveDialog.SAVE_ABOUT_VERSION_IMAGE:
-                // Save the about version image.
-                new SaveAboutVersionImage(this, fileNameString, aboutVersionLinearLayout).execute();
-                break;
-        }
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.kt b/app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.kt
new file mode 100644 (file)
index 0000000..94023b3
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.activities
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.view.WindowManager
+import android.widget.EditText
+import android.widget.LinearLayout
+
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import androidx.fragment.app.DialogFragment
+import androidx.preference.PreferenceManager
+import androidx.viewpager.widget.ViewPager
+
+import com.google.android.material.snackbar.Snackbar
+import com.google.android.material.tabs.TabLayout
+
+import com.stoutner.privacybrowser.R
+import com.stoutner.privacybrowser.adapters.AboutPagerAdapter
+import com.stoutner.privacybrowser.asynctasks.SaveAboutVersionImage
+import com.stoutner.privacybrowser.dialogs.SaveDialog
+import com.stoutner.privacybrowser.dialogs.SaveDialog.SaveListener
+import com.stoutner.privacybrowser.fragments.AboutVersionFragment
+
+import java.io.ByteArrayInputStream
+import java.io.InputStream
+import java.lang.Exception
+import java.nio.charset.StandardCharsets
+
+class AboutActivity : AppCompatActivity(), SaveListener {
+    // Declare the class variables.
+    private lateinit var aboutPagerAdapter: AboutPagerAdapter
+
+    companion object {
+        // Define the companion object constants.  These can be move to being public constants once MainWebViewActivity has been converted to Kotlin.
+        const val BLOCKLIST_VERSIONS = "blocklist_versions"
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        // Get a handle for the shared preferences.
+        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
+
+        // Get the screenshot preference.
+        val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
+
+        // Disable screenshots if not allowed.
+        if (!allowScreenshots) {
+            window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+        }
+
+        // Set the theme.
+        setTheme(R.style.PrivacyBrowser)
+
+        // Run the default commands.
+        super.onCreate(savedInstanceState)
+
+        // Get the intent that launched the activity.
+        val launchingIntent = intent
+
+        // Store the blocklist versions.
+        val blocklistVersions = launchingIntent.getStringArrayExtra(BLOCKLIST_VERSIONS)!!
+
+        // Set the content view.
+        setContentView(R.layout.about_coordinatorlayout)
+
+        // Get handles for the views.
+        val toolbar = findViewById<Toolbar>(R.id.about_toolbar)
+        val aboutTabLayout = findViewById<TabLayout>(R.id.about_tablayout)
+        val aboutViewPager = findViewById<ViewPager>(R.id.about_viewpager)
+
+        // Set the action bar.  `SupportActionBar` must be used until the minimum API is >= 21.
+        setSupportActionBar(toolbar)
+
+        // Get a handle for the action bar.
+        val actionBar = supportActionBar!!
+
+        // Display the home arrow on action bar.
+        actionBar.setDisplayHomeAsUpEnabled(true)
+
+        // Initialize the about pager adapter.
+        aboutPagerAdapter = AboutPagerAdapter(supportFragmentManager, applicationContext, blocklistVersions)
+
+        // Set the view pager adapter.
+        aboutViewPager.adapter = aboutPagerAdapter
+
+        // Keep all the tabs in memory.  This prevents the memory usage updater from running multiple times.
+        aboutViewPager.offscreenPageLimit = 10
+
+        // Connect the tab layout to the view pager.
+        aboutTabLayout.setupWithViewPager(aboutViewPager)
+    }
+
+    // The activity result is called after browsing for a file in the save alert dialog.
+    public override fun onActivityResult(requestCode: Int, resultCode: Int, returnedIntent: Intent?) {
+        // Run the default commands.
+        super.onActivityResult(requestCode, resultCode, returnedIntent)
+
+        // Only do something if the user didn't press back from the file picker.
+        if (resultCode == RESULT_OK) {
+            // Get a handle for the save dialog fragment.
+            val saveDialogFragment = supportFragmentManager.findFragmentByTag(getString(R.string.save_dialog)) as DialogFragment?
+
+            // Only update the file name if the dialog still exists.
+            if (saveDialogFragment != null) {
+                // Get a handle for the save dialog.
+                val saveDialog = saveDialogFragment.dialog!!
+
+                // Get a handle for the file name edit text.
+                val fileNameEditText = saveDialog.findViewById<EditText>(R.id.file_name_edittext)
+
+                // Get the file name URI from the intent.
+                val fileNameUri = returnedIntent!!.data
+
+                // Get the file name string from the URI.
+                val fileNameString = fileNameUri.toString()
+
+                // Set the file name text.
+                fileNameEditText.setText(fileNameString)
+
+                // Move the cursor to the end of the file name edit text.
+                fileNameEditText.setSelection(fileNameString.length)
+            }
+        }
+    }
+
+    override fun onSave(saveType: Int, dialogFragment: DialogFragment) {
+        // Get a handle for the dialog.
+        val dialog = dialogFragment.dialog!!
+
+        // Get a handle for the file name edit text.
+        val fileNameEditText = dialog.findViewById<EditText>(R.id.file_name_edittext)
+
+        // Get the file name string.
+        val fileNameString = fileNameEditText.text.toString()
+
+        // Get a handle for the about version linear layout.
+        val aboutVersionLinearLayout = findViewById<LinearLayout>(R.id.about_version_linearlayout)
+
+        // Process the save event according to the type.
+        when (saveType) {
+            SaveDialog.SAVE_ABOUT_VERSION_TEXT -> try {
+                // Get a handle for the about version fragment.
+                val aboutVersionFragment = aboutPagerAdapter.getTabFragment(0) as AboutVersionFragment
+
+                // Get the about version text.
+                val aboutVersionString = aboutVersionFragment.aboutVersionString
+
+                // Create an input stream with the contents of about version.
+                val aboutVersionInputStream: InputStream = ByteArrayInputStream(aboutVersionString.toByteArray(StandardCharsets.UTF_8))
+
+                // Open an output stream.
+                val outputStream = contentResolver.openOutputStream(Uri.parse(fileNameString))!!
+
+                // Copy the input stream to the output stream.
+                aboutVersionInputStream.copyTo(outputStream, 2048)
+
+                // Close the streams.
+                aboutVersionInputStream.close()
+                outputStream.close()
+
+                // Display a snackbar with the saved about version information.
+                Snackbar.make(aboutVersionLinearLayout, getString(R.string.file_saved) + "  " + fileNameString, Snackbar.LENGTH_SHORT).show()
+            } catch (exception: Exception) {
+                // Display a snackbar with the error message.
+                Snackbar.make(aboutVersionLinearLayout, getString(R.string.error_saving_file) + "  " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show()
+            }
+
+            SaveDialog.SAVE_ABOUT_VERSION_IMAGE ->
+                // Save the about version image.
+                SaveAboutVersionImage(this, fileNameString, aboutVersionLinearLayout).execute()
+        }
+    }
+}
\ No newline at end of file
index ed25a37d28b3d7689ec18fa45285ff4ebe85de80..4861ae3af1d0a43682792784b95d9f80ceb9f739 100644 (file)
@@ -1392,7 +1392,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Update the menu checkbox.
             menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
 
-            // Update the staus of Fanboy's Social Blocking List.
+            // Update the status of Fanboy's Social Blocking List.
             optionsFanboysSocialBlockingListMenuItem.setEnabled(!currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
 
             // Reload the current WebView.
@@ -2115,7 +2115,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     ultraList.get(0).get(0)[0], ultraPrivacy.get(0).get(0)[0]};
 
             // Add the blocklist versions to the intent.
-            aboutIntent.putExtra("blocklist_versions", blocklistVersions);
+            aboutIntent.putExtra(AboutActivity.BLOCKLIST_VERSIONS, blocklistVersions);
 
             // Make it so.
             startActivity(aboutIntent);
@@ -5806,7 +5806,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     String[] ultraListResults = blocklistHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, ultraList);
 
                     // Process the UltraList results.
-                    if (ultraListResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched UltraLists's blacklist.
+                    if (ultraListResults[0].equals(BlocklistHelper.REQUEST_BLOCKED)) {  // The resource request matched UltraList's blacklist.
                         // Add the result to the resource requests.
                         nestedScrollWebView.addResourceRequest(new String[] {ultraListResults[0], ultraListResults[1], ultraListResults[2], ultraListResults[3], ultraListResults[4], ultraListResults[5]});
 
index 1df0515230041e988a88faddb294f2be2e77e987..eb8ba87cc0a3147738c6c7276eb1e1fb7d10211f 100644 (file)
@@ -50,6 +50,8 @@ import com.google.android.material.snackbar.Snackbar
 
 import com.stoutner.privacybrowser.R
 import com.stoutner.privacybrowser.dialogs.AboutViewSourceDialog
+import com.stoutner.privacybrowser.dialogs.UntrustedSslCertificateDialog
+import com.stoutner.privacybrowser.dialogs.UntrustedSslCertificateDialog.UntrustedSslCertificateListener
 import com.stoutner.privacybrowser.helpers.ProxyHelper
 import com.stoutner.privacybrowser.viewmodelfactories.WebViewSourceFactory
 import com.stoutner.privacybrowser.viewmodels.WebViewSource
@@ -60,13 +62,15 @@ import java.util.Locale
 const val CURRENT_URL = "current_url"
 const val USER_AGENT = "user_agent"
 
-class ViewSourceActivity: AppCompatActivity() {
+class ViewSourceActivity: AppCompatActivity(), UntrustedSslCertificateListener {
     // Declare the class variables.
     private lateinit var initialGrayColorSpan: ForegroundColorSpan
     private lateinit var finalGrayColorSpan: ForegroundColorSpan
     private lateinit var redColorSpan: ForegroundColorSpan
+    private lateinit var webViewSource: WebViewSource
 
     // Declare the class views.
+    private lateinit var urlEditText: EditText
     private lateinit var requestHeadersTitleTextView: TextView
     private lateinit var requestHeadersTextView: TextView
     private lateinit var responseMessageTitleTextView: TextView
@@ -118,7 +122,7 @@ class ViewSourceActivity: AppCompatActivity() {
         actionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
 
         // Get handles for the views.
-        val urlEditText = findViewById<EditText>(R.id.url_edittext)
+        urlEditText = findViewById(R.id.url_edittext)
         val progressBar = findViewById<ProgressBar>(R.id.progress_bar)
         val swipeRefreshLayout = findViewById<SwipeRefreshLayout>(R.id.view_source_swiperefreshlayout)
         requestHeadersTitleTextView = findViewById(R.id.request_headers_title_textview)
@@ -272,7 +276,7 @@ class ViewSourceActivity: AppCompatActivity() {
         val webViewSourceFactory: ViewModelProvider.Factory = WebViewSourceFactory(currentUrl, userAgent, localeString, proxy, contentResolver, MainWebViewActivity.executorService)
 
         // Instantiate the WebView source view model class.
-        val webViewSource = ViewModelProvider(this, webViewSourceFactory).get(WebViewSource::class.java)
+        webViewSource = ViewModelProvider(this, webViewSourceFactory).get(WebViewSource::class.java)
 
         // Create a source observer.
         webViewSource.observeSource().observe(this, { sourceStringArray: Array<SpannableStringBuilder> ->
@@ -294,7 +298,16 @@ class ViewSourceActivity: AppCompatActivity() {
         webViewSource.observeErrors().observe(this, { errorString: String ->
             // Display an error snackbar if the string is not `""`.
             if (errorString != "") {
-                Snackbar.make(swipeRefreshLayout, errorString, Snackbar.LENGTH_LONG).show()
+                if (errorString.startsWith("javax.net.ssl.SSLHandshakeException")) {
+                    // Instantiate the untrusted SSL certificate dialog.
+                    val untrustedSslCertificateDialog = UntrustedSslCertificateDialog()
+
+                    // Show the untrusted SSL certificate dialog.
+                    untrustedSslCertificateDialog.show(supportFragmentManager, getString(R.string.invalid_certificate))
+                } else {
+                    // Display a snackbar with the error message.
+                    Snackbar.make(swipeRefreshLayout, errorString, Snackbar.LENGTH_LONG).show()
+                }
             }
         })
 
@@ -313,7 +326,7 @@ class ViewSourceActivity: AppCompatActivity() {
             updateLayout(urlString)
 
             // Get the updated source.
-            webViewSource.updateSource(urlString)
+            webViewSource.updateSource(urlString, false)
         }
 
         // Set the go button on the keyboard to request new source data.
@@ -339,7 +352,7 @@ class ViewSourceActivity: AppCompatActivity() {
                 updateLayout(urlString)
 
                 // Get the updated source.
-                webViewSource.updateSource(urlString)
+                webViewSource.updateSource(urlString, false)
 
                 // Consume the key press.
                 return@setOnKeyListener true
@@ -351,7 +364,7 @@ class ViewSourceActivity: AppCompatActivity() {
     }
 
     override fun onCreateOptionsMenu(menu: Menu): Boolean {
-        // Inflate the menu.  This adds items to the action bar if it is present.
+        // Inflate the menu.
         menuInflater.inflate(R.menu.view_source_options_menu, menu)
 
         // Display the menu.
@@ -359,7 +372,7 @@ class ViewSourceActivity: AppCompatActivity() {
     }
 
     override fun onOptionsItemSelected(menuItem: MenuItem): Boolean {
-        // Get a handle for the about alert dialog.
+        // Instantiate the about dialog fragment.
         val aboutDialogFragment: DialogFragment = AboutViewSourceDialog()
 
         // Show the about alert dialog.
@@ -375,6 +388,11 @@ class ViewSourceActivity: AppCompatActivity() {
         NavUtils.navigateUpFromSameTask(this)
     }
 
+    override fun loadAnyway() {
+        // Load the URL anyway.
+        webViewSource.updateSource(urlEditText.text.toString(), true)
+    }
+
     private fun highlightUrlText() {
         // Get a handle for the URL edit text.
         val urlEditText = findViewById<EditText>(R.id.url_edittext)
index a79e6e74d7a5fed52ff04601d3b3e09aed9b71cb..92e543cececf2dca267eb962bfa7062de7810144 100644 (file)
@@ -19,6 +19,7 @@
 
 package com.stoutner.privacybrowser.backgroundtasks;
 
+import android.annotation.SuppressLint;
 import android.content.ContentResolver;
 import android.database.Cursor;
 import android.graphics.Typeface;
@@ -40,9 +41,18 @@ import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
 import java.net.Proxy;
 import java.net.URL;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
 
 public class GetSourceBackgroundTask {
-    public SpannableStringBuilder[] acquire(String urlString, String userAgent, String localeString, Proxy proxy, ContentResolver contentResolver, WebViewSource webViewSource) {
+    public SpannableStringBuilder[] acquire(String urlString, String userAgent, String localeString, Proxy proxy, ContentResolver contentResolver, WebViewSource webViewSource, boolean ignoreSslErrors) {
         // Initialize the spannable string builders.
         SpannableStringBuilder requestHeadersBuilder = new SpannableStringBuilder();
         SpannableStringBuilder responseMessageBuilder = new SpannableStringBuilder();
@@ -315,13 +325,54 @@ public class GetSourceBackgroundTask {
                 }
                 requestHeadersBuilder.append(":  gzip");
 
+                // Ignore SSL errors if requested.
+                if (ignoreSslErrors){
+                    // Create a new host name verifier.
+                    HostnameVerifier hostnameVerifier = (hostname, sslSession) -> {
+                        // Allow all host names.
+                        return true;
+                    };
+
+                    // Create a new trust manager.
+                    TrustManager[] trustManager = new TrustManager[] {
+                            new X509TrustManager() {
+                                @SuppressLint("TrustAllX509TrustManager")
+                                @Override
+                                public void checkClientTrusted(X509Certificate[] chain, String authType) {
+                                    // Do nothing, which trusts all client certificates.
+                                }
+
+                                @SuppressLint("TrustAllX509TrustManager")
+                                @Override
+                                public void checkServerTrusted(X509Certificate[] chain, String authType) {
+                                    // Do nothing, which trusts all server certificates.
+                                }
+
+                                @Override
+                                public X509Certificate[] getAcceptedIssuers() {
+                                    return null;
+                                }
+                            }
+                    };
+
+                    // Get an SSL context.  `TLS` provides a base instance available from API 1.  <https://developer.android.com/reference/javax/net/ssl/SSLContext>
+                    SSLContext sslContext = SSLContext.getInstance("TLS");
+
+                    // Initialize the SSL context with the blank trust manager.
+                    sslContext.init(null, trustManager, new SecureRandom());
+
+                    // Get the SSL socket factory with the blank trust manager.
+                    SSLSocketFactory socketFactory = sslContext.getSocketFactory();
+
+                    // Set the HTTPS URL Connection to use the blank host name verifier.
+                    ((HttpsURLConnection) httpUrlConnection).setHostnameVerifier(hostnameVerifier);
+
+                    // Set the HTTPS URL connection to use the socket factory with the blank trust manager.
+                    ((HttpsURLConnection) httpUrlConnection).setSSLSocketFactory(socketFactory);
+                }
 
                 // The actual network request is in a `try` bracket so that `disconnect()` is run in the `finally` section even if an error is encountered in the main block.
                 try {
-                    // Initialize the string builders.
-                    responseMessageBuilder = new SpannableStringBuilder();
-                    responseHeadersBuilder = new SpannableStringBuilder();
-
                     // Get the response code, which causes the connection to the server to be made.
                     int responseCode = httpUrlConnection.getResponseCode();
 
@@ -405,7 +456,7 @@ public class GetSourceBackgroundTask {
             }
         }
 
-        // Return the response body string as the result.
+        // Return the spannable string builders.
         return new SpannableStringBuilder[] {requestHeadersBuilder, responseMessageBuilder, responseHeadersBuilder, responseBodyBuilder};
     }
 }
\ No newline at end of file
index 5089fa22ca8104c121db09d5405f133b80a6aeaf..c219e4c37e72735f6602a7bffd7a4c70fb230b67 100644 (file)
@@ -43,7 +43,7 @@ class AboutViewSourceDialog : DialogFragment() {
         // Set the text.
         dialogBuilder.setMessage(R.string.about_view_source_message)
 
-        // Set a listener on the close button.  Using `null` as the listener closes the dialog without doing anything else.
+        // Set the close button listener.  Using `null` as the listener closes the dialog without doing anything else.
         dialogBuilder.setNegativeButton(R.string.close, null)
 
         // Create an alert dialog from the alert dialog builder.
index 42e43d91a4cfe1b00e618a8a28b6ae12d717ced8..0e8a08db715a5dd60ae8c71593a5527434b4fc57 100644 (file)
@@ -107,7 +107,7 @@ class HttpAuthenticationDialog : DialogFragment() {
             val httpAuthHandler = nestedScrollWebView.httpAuthHandler
 
             // Use an alert dialog builder to create the alert dialog.
-            val dialogBuilder = AlertDialog.Builder(requireActivity(), R.style.PrivacyBrowserAlertDialog)
+            val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
 
             // Set the icon according to the theme.
             dialogBuilder.setIconAttribute(R.attr.lockBlueIcon)
@@ -173,11 +173,8 @@ class HttpAuthenticationDialog : DialogFragment() {
             // Get the current theme status.
             val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
 
-            // 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) {
+            val blueColorSpan = if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
                 @Suppress("DEPRECATION")
                 ForegroundColorSpan(resources.getColor(R.color.blue_700))
             } else {
@@ -229,7 +226,7 @@ class HttpAuthenticationDialog : DialogFragment() {
             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)
+            val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
 
             // Create an empty alert dialog from the alert dialog builder.
             val alertDialog = dialogBuilder.create()
@@ -243,7 +240,7 @@ class HttpAuthenticationDialog : DialogFragment() {
     }
 
     override fun onResume() {
-        // Run the default command.
+        // Run the default commands.
         super.onResume()
 
         // Dismiss the alert dialog if the activity was restarted and the HTTP auth handler no longer exists.
index a4082552cf8354ccc093cb82fb5687723a52c412..e44e8026bf29e325985d5f55047f8f63eda8ccfa 100644 (file)
@@ -143,11 +143,7 @@ class SslCertificateErrorDialog : DialogFragment() {
         val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
 
         // Set the icon according to the theme.
-        if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
-            dialogBuilder.setIcon(R.drawable.ssl_certificate_enabled_day)
-        } else {
-            dialogBuilder.setIcon(R.drawable.ssl_certificate_enabled_night)
-        }
+        dialogBuilder.setIconAttribute(R.attr.sslCertificateBlueIcon)
 
         // Set the title.
         dialogBuilder.setTitle(R.string.ssl_certificate_error)
@@ -155,7 +151,7 @@ class SslCertificateErrorDialog : DialogFragment() {
         // Set the view.  The parent view is null because it will be assigned by the alert dialog.
         dialogBuilder.setView(layoutInflater.inflate(R.layout.ssl_certificate_error, null))
 
-        // Set a listener on the cancel button.
+        // Set the cancel button listener.
         dialogBuilder.setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int ->
             // Check to make sure the SSL error handler is not null.  This might happen if multiple dialogs are displayed at once.
             if (sslErrorHandler != null) {
@@ -167,7 +163,7 @@ class SslCertificateErrorDialog : DialogFragment() {
             }
         }
 
-        // Set a listener on the proceed button.
+        // Set the proceed button listener.
         dialogBuilder.setPositiveButton(R.string.proceed) { _: DialogInterface?, _: Int ->
             // Check to make sure the SSL error handler is not null.  This might happen if multiple dialogs are displayed at once.
             if (sslErrorHandler != null) {
diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/UntrustedSslCertificateDialog.kt b/app/src/main/java/com/stoutner/privacybrowser/dialogs/UntrustedSslCertificateDialog.kt
new file mode 100644 (file)
index 0000000..7b71746
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.dialogs
+
+import android.app.Dialog
+import android.content.Context
+import android.content.DialogInterface
+import android.os.Bundle
+import android.view.WindowManager
+
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import androidx.preference.PreferenceManager
+
+import com.stoutner.privacybrowser.R
+
+class UntrustedSslCertificateDialog : DialogFragment() {
+    // Declare the class variables.
+    private lateinit var untrustedSslCertificateListener: UntrustedSslCertificateListener
+    private var dismissDialog: Boolean = false
+
+    // The public interface is used to send information back to the parent activity.
+    interface UntrustedSslCertificateListener {
+        fun loadAnyway()
+    }
+
+    override fun onAttach(context: Context) {
+        // Run the default commands.
+        super.onAttach(context)
+
+        // Get a handle for the listener form the launching context.
+        untrustedSslCertificateListener = context as UntrustedSslCertificateListener
+    }
+
+    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+        // Check to see if the app has been restarted.
+        if (savedInstanceState == null) {  // The app has not been restarted.
+            // Use a builder to create the alert dialog.
+            val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
+
+            // Set the icon according to the theme.
+            dialogBuilder.setIconAttribute(R.attr.sslCertificateBlueIcon)
+
+            // Set the title.
+            dialogBuilder.setTitle(R.string.ssl_certificate_error)
+
+            // Set the text.
+            dialogBuilder.setMessage(R.string.untrusted_ssl_certificate)
+
+            // Set the cancel button listener.  Using `null` as the listener closes the dialog without doing anything else.
+            dialogBuilder.setNegativeButton(R.string.cancel, null)
+
+            // Set the load anyway button listener.
+            dialogBuilder.setPositiveButton(R.string.load_anyway) { _: DialogInterface, _: Int ->
+                // Instruct the parent activity to load the URL anyway.
+                untrustedSslCertificateListener.loadAnyway()
+            }
+
+            // Create an alert dialog from the builder.
+            val alertDialog = dialogBuilder.create()
+
+            // Get a handle for the shared preferences.
+            val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
+
+            // Get the screenshot preference.
+            val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots), false)
+
+            // Disable screenshots if not allowed.
+            if (!allowScreenshots) {
+                alertDialog.window!!.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
+            }
+
+            // Return the alert dialog.
+            return alertDialog
+        } else {  // The app has been restarted.  Close the dialog as a new one will automatically be created by GetSourceBackgroundTask.
+            // Use an alert dialog builder to create an empty alert dialog.
+            val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
+
+            // 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
+
+            // Return the alert dialog.
+            return alertDialog
+        }
+    }
+
+    override fun onResume() {
+        // Run the default commands.
+        super.onResume()
+
+        // Dismiss the alert dialog if the activity was restarted as a new one will automatically be created by GetSourceBackgroundTask.
+        if (dismissDialog) {
+            dialog!!.dismiss()
+        }
+    }
+}
\ No newline at end of file
index e44e74d81847d2d2be16f4741249459fbd9c5751..8da413918bc9307d74c058ceed4386b789714329 100644 (file)
@@ -20,6 +20,7 @@
 package com.stoutner.privacybrowser.viewmodelfactories
 
 import android.content.ContentResolver
+
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 
index 1b9d9e1203dd15399c1efba4f05e5e6337115c13..3251d92048038fe6cc9f90d75ad85454741dfd26 100644 (file)
@@ -43,7 +43,8 @@ class WebViewSource(private val urlString: String, private val userAgent: String
         val getSourceBackgroundTask = GetSourceBackgroundTask()
 
         // Get the source.
-        executorService.execute { mutableLiveDataSourceStringArray.postValue(getSourceBackgroundTask.acquire(urlString, userAgent, localeString, proxy, contentResolver, this)) }
+        executorService.execute { mutableLiveDataSourceStringArray.postValue(getSourceBackgroundTask.acquire(urlString, userAgent, localeString, proxy, contentResolver, this,
+            false)) }
     }
 
     // The source observer.
@@ -65,7 +66,7 @@ class WebViewSource(private val urlString: String, private val userAgent: String
     }
 
     // The workhorse that gets the source.
-    fun updateSource(urlString: String) {
+    fun updateSource(urlString: String, ignoreSslErrors: Boolean) {
         // Reset the mutable live data error string.  This prevents the snackbar from displaying later if the activity restarts.
         mutableLiveDataErrorString.postValue("")
 
@@ -73,6 +74,7 @@ class WebViewSource(private val urlString: String, private val userAgent: String
         val getSourceBackgroundTask = GetSourceBackgroundTask()
 
         // Get the source.
-        executorService.execute { mutableLiveDataSourceStringArray.postValue(getSourceBackgroundTask.acquire(urlString, userAgent, localeString, proxy, contentResolver, this)) }
+        executorService.execute { mutableLiveDataSourceStringArray.postValue(getSourceBackgroundTask.acquire(urlString, userAgent, localeString, proxy, contentResolver, this,
+            ignoreSslErrors)) }
     }
 }
\ No newline at end of file
index d31e741cba3d83e0e3683fc2020aed5b83c2fb0e..2a7cfd6e4e43bbdac1d8342719d7f4f9655c2d9c 100644 (file)
     <string name="response_message">Status-Code</string>
     <string name="response_headers">Antwortkopfzeilen</string>
     <string name="response_body">Antwortinhalt</string>
+    <string name="content_metadata">Content-Metadaten</string>
+    <string name="content_data">Content-Daten</string>
     <string name="about_view_source">Über Quelltext</string>
     <string name="about_view_source_message">Weil Androids WebView keine Quelltext-Informationen zur Verfügung stellt, muss eine separate a separate Serveranfrage mit system tools gestellt werden,
         die hier dargestellten Daten erhält. Deshalb können Unterschiede zwischen diesen Daten und der mit WebView dargestellten Webseite auftreten.
index 5d93c0a982e536eaf21341ea9a1559d2b845c138..ac18568f3aa7656118ebad64d3ecd72c32ccc58e 100644 (file)
     <string name="response_message">Mensaje de respuesta</string>
     <string name="response_headers">Cabeceras de respuesta</string>
     <string name="response_body">Cuerpo de respuesta</string>
+    <string name="content_metadata">Metadatos del contenido</string>
+    <string name="content_data">Datos del contenido</string>
     <string name="about_view_source">Acerca de ver la fuente</string>
     <string name="about_view_source_message">Debido a que WebView de Android no expone la información fuente,
         se hizo una solicitud por separado utilizando las herramientas del sistema para recopilar la información mostrada en esta actividad.
index c60d40466b6f0a66a8d0e2cbdd109086408b9fd2..ca7baf3b58d936c4158ddbdaaee2cd3aab79a245 100644 (file)
     <string name="response_message">Messaggio di Risposta</string>
     <string name="response_headers">Risposta Intestazioni</string>
     <string name="response_body">Testo della Risposta</string>
+    <string name="content_metadata">Content - Metadati</string>
+    <string name="content_data">Content - Dati</string>
     <string name="about_view_source">Informazioni sulla visualizzazione della sorgente</string>
     <string name="about_view_source_message">Dal momento che la WebView di Android non fornisce indicazioni sulla sorgente è stata effettuata una richiesta separata utilizzando i system tools in modo da
         ottenere le informazioni mostrate. Potrebbero esserci alcune differenze tra questi dati e quelli utilizzati da WebView.
index 55b22074468f64c33905861a7ea36892462fe13b..ef8831ef94d0e4ffa23b5b7833919a49e2bf48c7 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -68,6 +68,7 @@
         <item name="domainsBlueIcon">@drawable/domains_night</item>
         <item name="fontSizeBlueIcon">@drawable/font_size_night</item>
         <item name="lockBlueIcon">@drawable/lock_night</item>
+        <item name="sslCertificateBlueIcon">@drawable/ssl_certificate_enabled_night</item>
     </style>
 
     <style name="PrivacyBrowserAppBar" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" >
index 09599e6df8e5fd07e73e913431adb9e97a3e47ee..188c005d7eac9b7bae9edae541738a3f75281309 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -70,6 +70,7 @@
         <item name="domainsBlueIcon">@drawable/domains_night</item>
         <item name="fontSizeBlueIcon">@drawable/font_size_night</item>
         <item name="lockBlueIcon">@drawable/lock_night</item>
+        <item name="sslCertificateBlueIcon">@drawable/ssl_certificate_enabled_night</item>
     </style>
 
     <style name="PrivacyBrowserAppBar" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" >
index becf6a0f843b5cc8539cc8de0d3205e670a19be3..0de44f4027f355fa86ebfb710eb367ae1da01a10 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -66,6 +66,7 @@
         <item name="domainsBlueIcon">@drawable/domains_night</item>
         <item name="fontSizeBlueIcon">@drawable/font_size_night</item>
         <item name="lockBlueIcon">@drawable/lock_night</item>
+        <item name="sslCertificateBlueIcon">@drawable/ssl_certificate_enabled_night</item>
     </style>
 
     <style name="PrivacyBrowserAppBar" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" >
index 320b0d3a6a9fca50a79ba118b79e3fce732676b9..4ca8d7c81048c60207fa5bed7d45828f03efec54 100644 (file)
@@ -3,7 +3,7 @@
 <!--
   Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
-  Translation 2020 Thiago Nazareno Conceição Silva de Jesus <mochileiro2006-trilhas@yahoo.com.br>.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+  Translation 2020-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 <https://www.stoutner.com/privacy-browser>.
 
@@ -31,6 +31,8 @@
     <string name="privacy_mode">Modo Privado</string>
     <string name="javascript_enabled">JavaScript ativado</string>
     <string name="javascript_disabled">JavaScript desativado</string>
+    <string name="cookies_enabled">Cookies ativados</string>
+    <string name="cookies_disabled">Cookies desativados</string>
     <string name="dom_storage_enabled">Armazenamento DOM ativado</string>
     <string name="dom_storage_disabled">Armazenamento DOM desativado</string>
     <string name="form_data_enabled">Dados de formulário habilitados</string>  <!-- The form data strings can be removed once the minimum API >= 26. -->
         <string name="clear_history">Limpar Histórico</string>
     <string name="open">Abrir</string>
     <string name="downloads">Downloads</string>
+        <string name="no_file_manager_detected">O sistema não pode detectar um gerenciador de arquivos compatível.</string>
     <string name="settings">Configurações</string>
     <string name="import_export">Importar/Exportar</string>
     <string name="logcat">Logcat</string>
     <string name="javascript">JavaScript</string>
     <string name="refresh">Atualizar</string>
     <string name="stop">Parar</string>
+    <string name="cookies">Cookies</string>
     <string name="dom_storage">Armazenamento DOM</string>
     <string name="form_data">Dados do formulário</string>  <!-- The form data strings can be removed once the minimum API >= 26. -->
     <string name="clear_data">Limpar dados</string>
     <string name="previous">Anterior</string>
     <string name="next">Próximo</string>
 
+    <!-- Open Dialog. -->
+    <string name="file_is_mht">Este é um arquivo MHT da web.</string>
+    <string name="mht_checkbox_explanation">Às vezes, os arquivos da web MIME Encapsulated HTML (MHT) precisam ser especificados manualmente para serem abertos corretamente.</string>
+
     <!-- Save Dialogs. -->
     <string name="save_url">Salvar URL</string>
     <string name="save_archive">Salvar Arquivo</string>
     <string name="saving_file">Salvando file:</string>
     <string name="file_saved">Arquivo Salvo:</string>
     <string name="processing_image">Processando imagem… :</string>
+    <string name="image_saved">Image saved:</string>
     <string name="error_saving_file">Erro ao salvar o arquivo:</string>
 
     <!-- View Source. -->
     <string name="response_message">Mensagem de Resposta</string>
     <string name="response_headers">Cabeçalhos de resposta</string>
     <string name="response_body">Corpo de Resposta</string>
+    <string name="content_metadata">Metadados de conteúdo</string>
+    <string name="content_data">Dados de conteúdo</string>
     <string name="about_view_source">Sobre Ver Fonte</string>
     <string name="about_view_source_message">Como o WebView do Android não expõe as informações de origem,
         uma solicitação separada foi feita usando ferramentas do sistema para reunir as informações exibidas nesta atividade.
     <!-- Bookmarks. -->
     <string name="bookmarks">Favoritos</string>
     <string name="database_view">Visualização do banco de dados</string>
+    <string name="bookmark_opened_in_background">O favorito foi aberto em uma aba em segundo plano.</string>
     <string name="create_bookmark">Criar marcador</string>
     <string name="create_folder">Criar pasta</string>
     <string name="current_bookmark_icon">Ícone de favorito atual</string>
         <string name="blocked_plural">Bloqueados</string>
     <string name="blocklist">Lista de bloqueios</string>
         <string name="sublist">Sublista</string>
-        <string name="main_whitelist">Lista branca principal</string>
+        <string name="main_whitelist">Lista de permissão principal</string>
         <string name="final_whitelist">Lista de permissões final</string>
         <string name="domain_whitelist">Lista de permissões de domínio</string>
         <string name="domain_initial_whitelist">Lista de permissões inicial do domínio</string>
         <string name="domain_final_whitelist">Lista de permissões final de domínio</string>
         <string name="third_party_whitelist">Lista de permissões de terceiros</string>
-        <string name="third_party_domain_whitelist">Lista de permissões de domínio de terceiros</string>
-        <string name="third_party_domain_initial_whitelist">Lista de permissões inicial de domínio de terceiros</string>
-        <string name="main_blacklist">Lista negra principal</string>
-        <string name="initial_blacklist">Lista negra inicial</string>
-        <string name="final_blacklist">Lista negra final</string>
-        <string name="domain_blacklist">Lista negra de domínio</string>
-        <string name="domain_initial_blacklist">Lista negra inicial do domínio</string>
-        <string name="domain_final_blacklist">Lista negra final do domínio</string>
-        <string name="domain_regular_expression_blacklist">Lista negra de expressões regulares de domínio</string>
-        <string name="third_party_blacklist">Lista negra de terceiros</string>
-        <string name="third_party_initial_blacklist">Lista negra inicial de terceiros</string>
-        <string name="third_party_domain_blacklist">Lista negra de domínios de terceiros</string>
-        <string name="third_party_domain_initial_blacklist">Lista negra inicial de domínios de terceiros</string>
-        <string name="third_party_regular_expression_blacklist">Lista negra de expressões regulares de terceiros</string>
-        <string name="third_party_domain_regular_expression_blacklist">Lista negra de expressões regulares de domínios de terceiros</string>
-        <string name="regular_expression_blacklist">Lista negra de expressões regulares</string>
+        <string name="third_party_domain_whitelist">Lista de permissões de domínios de terceiros</string>
+        <string name="third_party_domain_initial_whitelist">Lista de permissões iniciais de domínios de terceiros</string>
+        <string name="main_blacklist">Lista de restrições principal</string>
+        <string name="initial_blacklist">Lista de restrições inicial</string>
+        <string name="final_blacklist">Lista de restrições final</string>
+        <string name="domain_blacklist">Lista de restrições de domínios</string>
+        <string name="domain_initial_blacklist">Lista de restrições inicial do domínio</string>
+        <string name="domain_final_blacklist">Lista de restrições final do domínio</string>
+        <string name="domain_regular_expression_blacklist">Lista de restrições de expressões regulares de domínio</string>
+        <string name="third_party_blacklist">Lista de restrições de terceiros</string>
+        <string name="third_party_initial_blacklist">Lista de restrições inicial de terceiros</string>
+        <string name="third_party_domain_blacklist">Lista de restrições de domínios de terceiros</string>
+        <string name="third_party_domain_initial_blacklist">Lista de restrições inicial de domínios de terceiros</string>
+        <string name="third_party_regular_expression_blacklist">Lista de restrições de expressões regulares de terceiros</string>
+        <string name="third_party_domain_regular_expression_blacklist">Lista de restrições de expressões regulares de domínios de terceiros</string>
+        <string name="regular_expression_blacklist">Lista de restrições de expressões regulares</string>
     <string name="blocklist_entries">Entradas da lista de bloqueio</string>
     <string name="blocklist_original_entry">Entrada original da lista de bloqueio</string>
 
     <!-- Preferences. -->
     <string name="privacy">Privacidade</string>
         <string name="javascript_preference_summary">JavaScript permite que sites executem programas (scripts) no dispositivo.</string>
+        <string name="cookies_preference_summary">Cookies são uma configuração de nível de aplicativo.
+            Quando a guia ativa tem cookies habilitados, qualquer solicitação de rede feita em segundo plano por outra guia também tem cookies habilitados.</string>
         <string name="dom_storage_preference">Armazenamento DOM</string>
+        <string name="dom_storage_preference_summary">O JavaScript deve estar habilitado para que o armazenamento do Document Object Model funcione.</string>
         <string name="save_form_data_preference">Dados do formulário</string>  <!-- The form data strings can be removed once the minimum API >= 26. -->
         <string name="save_form_data_preference_summary">Dados de formulário salvos podem preencher campos automaticamente em sites.</string>
         <!-- The form data strings can be removed once the minimum API >= 26. -->
-        <string name="user_agent">Mimetizar o Navegador:</string>
+        <string name="user_agent">Agente do usuário</string>
         <string-array name="translated_user_agent_names">
             <item>Privacy Browser</item>
             <item>WebView Padrão</item>
             <item>Safari para macOS</item>
             <item>Personalizado</item>
         </string-array>
-        <string name="custom_user_agent">Agente de usuário personalizado</string>
+        <string name="custom_user_agent">Agente do usuário personalizado</string>
         <string name="incognito_mode">Modo de navegação anônima</string>
         <string name="incognito_mode_summary">Limpe o histórico e o cache após o término do carregamento de cada página da web. No modo de navegação anônima,
             volta para fechar a guia (ou o aplicativo, se houver apenas uma guia).</string>
         <!-- The form data part of this string can be removed once the minimum API >= 26. -->
         <string name="clear_everything_summary">Limpa cookies, armazenamento DOM, dados de formulário e cache do WebView. Em seguida, exclui manualmente todos os diretórios “app_webview” e “cache”.</string>
         <string name="clear_cookies_preference">Limpar cookies</string>
+        <string name="clear_cookies_summary">Limpar os cookies.</string>
         <string name="clear_dom_storage_preference">Limpar armazenamento DOM</string>
         <string name="clear_dom_storage_summary">Limpa o armazenamento DOM.</string>
         <string name="clear_form_data_preference">Limpar dados do formulário</string>  <!-- The form data strings can be removed once the minimum API >= 26. -->
         <string name="open_intents_in_new_tab_summary">Conteúdos são links enviados de outros aplicativos.</string>
         <string name="swipe_to_refresh">Deslize para atualizar</string>
         <string name="swipe_to_refresh_summary">Alguns sites não funcionam bem se deslizar para atualizar estiver habilitado.</string>
+        <string name="download_with_external_app">Download com aplicativo externo</string>
+        <string name="download_with_external_app_summary">Usar um aplicativo externo para baixar arquivos.</string>
         <string name="scroll_app_bar">Role a barra de aplicativos</string>
         <string name="scroll_app_bar_summary">Role a barra de aplicativos para fora da parte superior da tela quando o WebView rola para baixo.</string>
         <string name="display_additional_app_bar_icons">Exibir ícones adicionais da barra de aplicativos</string>
index c77b79a8e5b8a310c410636ff2c585f45ccaeabf..7bf9e192f6dce397b10cdf25356bc349db3d4f86 100644 (file)
     <string name="response_message">Ответное сообщение</string>
     <string name="response_headers">Заголовки ответа</string>
     <string name="response_body">Тело ответа</string>
+    <string name="content_metadata">Метаданные содержимого</string>
+    <string name="content_data">Данные содержимого</string>
     <string name="about_view_source">О просмотре исходного кода</string>
     <string name="about_view_source_message">Поскольку Android WebView не предоставляет исходные данные, для сбора информации, отображаемой в этом действии,
         был сделан отдельный запрос с помощью системных средств. Между этими данными и теми, которые используются в WebView, могут быть некоторые отличия.
index 2a907cc6fabd7bf17c0403a7a191afcd0ea63532..1844f98c055236da7886c9b56961d38b4b6688ad 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -68,6 +68,7 @@
         <item name="domainsBlueIcon">@drawable/domains_day</item>
         <item name="fontSizeBlueIcon">@drawable/font_size_day</item>
         <item name="lockBlueIcon">@drawable/lock_day</item>
+        <item name="sslCertificateBlueIcon">@drawable/ssl_certificate_enabled_day</item>
     </style>
 
     <style name="PrivacyBrowserAppBar" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" >
index ec11484abfa8dc491273f1f36486e704c2151f73..03e5e695648a6589ecba55a0528035c36c15fcd2 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -70,6 +70,7 @@
         <item name="domainsBlueIcon">@drawable/domains_day</item>
         <item name="fontSizeBlueIcon">@drawable/font_size_day</item>
         <item name="lockBlueIcon">@drawable/lock_day</item>
+        <item name="sslCertificateBlueIcon">@drawable/ssl_certificate_enabled_day</item>
     </style>
 
     <style name="PrivacyBrowserAppBar" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" >
index 79a60c8a17639bd714ea1ffdb4e007a34a347326..920e3bcd1a85cad2714c09c2f6c1f32b72282cc1 100644 (file)
@@ -67,4 +67,5 @@
     <attr name="domainsBlueIcon" format="reference" />
     <attr name="fontSizeBlueIcon" format="reference" />
     <attr name="lockBlueIcon" format="reference" />
+    <attr name="sslCertificateBlueIcon" format="reference" />
 </resources>
\ No newline at end of file
index 45a352d6eca0f0f208eb32f4fde6bb459e1f70f6..2afa9243cd28f4fbe4cc73d7bc45c19a4ab54301 100644 (file)
     <string name="response_body">Response Body</string>
     <string name="content_metadata">Content Metadata</string>
     <string name="content_data">Content Data</string>
+    <string name="untrusted_ssl_certificate">The SSL certificate is untrusted.</string>
+    <string name="load_anyway">Load anyway</string>
     <string name="about_view_source">About View Source</string>
     <string name="about_view_source_message">Because Android’s WebView does not expose the source information,
         a separate request was made using system tools to gather the information displayed in this activity.
     <!-- Preferences. -->
     <string name="privacy">Privacy</string>
         <string name="javascript_preference_summary">JavaScript allows websites to run programs (scripts) on the device.</string>
-        <string name="cookies_preference_summary">Cookies are an app level setting. When the active tab has cookies enabled,
-            any network request made in the background by another tab also has cookies enabled.</string>
+        <string name="cookies_preference_summary">Cookies are an app level setting.
+            When the active tab has cookies enabled, any network request made in the background by another tab also has cookies enabled.</string>
         <string name="dom_storage_preference">DOM storage</string>
         <string name="dom_storage_preference_summary">JavaScript must be enabled for Document Object Model storage to function.</string>
         <string name="save_form_data_preference">Form data</string>  <!-- The form data strings can be removed once the minimum API >= 26. -->
index 464b023e93070f52dc76320e9ff611b49e562293..5c47d125ec83cd11172d0b7dabc5e51e507672aa 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -66,6 +66,7 @@
         <item name="domainsBlueIcon">@drawable/domains_day</item>
         <item name="fontSizeBlueIcon">@drawable/font_size_day</item>
         <item name="lockBlueIcon">@drawable/lock_day</item>
+        <item name="sslCertificateBlueIcon">@drawable/ssl_certificate_enabled_day</item>
     </style>
 
     <style name="PrivacyBrowserAppBar" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" >
index 01f38d5cda3563c48b9e3d598766f900bdd335f1..c891ef0ba955c7ef40254ec8015ee4cb5b8734f4 100644 (file)
@@ -25,7 +25,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:4.2.0'
+        classpath 'com.android.tools.build:gradle:4.2.1'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0"
 
         // NOTE: Do not place your application dependencies here; they belong