<component name="ProjectDictionaryState">
<dictionary name="soren">
<words>
+ <w>adsense</w>
<w>androidversion</w>
<w>anonymized</w>
<w>appbarlayout</w>
<w>coordinatorlayout</w>
<w>eadd</w>
<w>exynos</w>
+ <w>imbedded</w>
+ <w>imbedding</w>
<w>intl</w>
<w>khtml</w>
<w>konqueror</w>
<w>linearlayout</w>
+ <w>logins</w>
<w>mozilla</w>
<w>nojs</w>
+ <w>orbot</w>
+ <w>panopticlick</w>
<w>redmine</w>
<w>relativelayout</w>
+ <w>robinlinus</w>
<w>samsung</w>
<w>securitypatch</w>
<w>snackbar</w>
<w>tablayout</w>
<w>techrepublic</w>
<w>textview</w>
+ <w>webkay</w>
<w>webkitversion</w>
+ <w>whatismyip</w>
<w>zenlte</w>
</words>
</dictionary>
<body>
<h3>Privacy Browser Free</h3>
+
<p><strong>Privacy Browser Free does not collect any user information</strong>.</p>
-<hr />
<h3>Advertisements</h3>
+
<p>Privacy Browser Free displays a banner add across the bottom of the screen using the Google's AdMob network,
which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
Note that unless you have <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">opted out of interest-based ads</a>,
the advertiser will receive a copy of your unique device advertising ID, which allows them to track your device across apps.
AdMob reports <em>anonymized summaries</em> of the following information. <strong>Stoutner may use this information for any purpose</strong>.</p>
+
<ul>
<li><item>Total impressions</item></li>
<li><item>Total clicks</item></li>
<li><item>Activity by country</item></li>
</ul>
-<hr />
<h3>Google Play Ratings</h3>
+
<p>Google Play has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
Google provides developers with <em>anonymized summaries</em> of the following information related to user ratings.
<strong>Stoutner may use this information for any purpose</strong>.</p>
+
<ul>
<li><item>Country</item></li>
<li><item>Language</item></li>
<li><item>Tablets</item> (eg. Tablets 10" and above)</li>
</ul>
-<hr />
<h3>Google Play Reviews</h3>
+
<p>Google Play has it <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
In addition to the name of the reviewer, the rating, and the text of the review (which are all available publicly),
Google provides some or all of the following information to the developer.
<strong>Stoutner may use this information for any purpose</strong>.</p>
+
<ul>
<li><item>Version code</item> (eg. 7)</li>
<li><item>Version name</item> (eg. 1.6)</li>
<!-- Required to create homescreen shortcuts. -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
+
<!-- For API >= 23, app data is automatically backed up to Google cloud servers unless android:allowBackup="false" and android:fullBackupContent="false" is set. -->
<application
android:label="@string/privacy_browser"
android:allowBackup="false"
android:fullBackupContent="false" >
+ <!-- If android:name="android.webkit.WebView.MetricsOptOut" is not "true" then WebViews will upload metrics to Google.
+ https://developer.android.com/reference/android/webkit/WebView.html -->
+ <meta-data
+ android:name="android.webkit.WebView.MetricsOptOut"
+ android:value="true" />
+
<!-- android:configChanges="orientation|screenSize" makes the activity not reload when the orientation changes, which preserves scroll location in the WebView.
android:launchMode="singleTask" makes the app launch in a new task instead of inside the task of the program that sends it an intent.
It also makes it reuse an existing Privacy Browser activity if available instead of launching a new one.
</intent-filter>
</activity>
+ <!-- android:configChanges="orientation|screenSize" makes the activity not reload when the orientation changes.
+ android:persistableMode="persistNever" removes Privacy Browser from the recents screen on a device reboot. -->
+ <activity
+ android:name=".GuideActivity"
+ android:label="@string/privacy_browser_guide"
+ android:theme="@style/PrivacyBrowser.TabActivity"
+ android:parentActivityName=".MainWebViewActivity"
+ android:configChanges="orientation|screenSize"
+ android:persistableMode="persistNever" >
+
+ <!-- android.support.PARENT_ACTIVITY is necessary for API <= 15. -->
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".MainWebViewActivity" />
+ </activity>
+
<!-- android:configChanges="orientation|screenSize" makes the activity not reload when the orientation changes.
android:persistableMode="persistNever" removes Privacy Browser from the recents screen on a device reboot. -->
<activity
<activity
android:name=".AboutActivity"
android:label="@string/about_privacy_browser"
- android:theme="@style/PrivacyBrowser.About"
+ android:theme="@style/PrivacyBrowser.TabActivity"
android:parentActivityName=".MainWebViewActivity"
android:configChanges="orientation|screenSize"
android:persistableMode="persistNever" >
<html>
<head>
- <style>
- h3 {
- color: 0D4781;
- }
- </style>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+</style>
</head>
<body>
<html>
<head>
- <style>
- h3 {
+<style>
+ h3 {
color: 0D4781;
- }
- </style>
+ }
+</style>
</head>
<body>
<h3>Principle Developers</h3>
+
<p>Privacy Browser is primarily developed by <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
-<hr />
<h3>Contributors</h3>
+
<p>Contributors are welcome to submit both <a href="https://www.stoutner.com/privacy-browser/contributors/">code and translations</a>.</p>
</body>
</html>
\ No newline at end of file
<html>
<head>
- <style>
- h3 {
- color: 0D4781;
- }
-
- img.center {
- vertical-align: middle;
- }
-
- img.left {
- float: left;
- }
- </style>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ img.center {
+ vertical-align: middle;
+ }
+
+ img.left {
+ float: left;
+ }
+</style>
</head>
+
<body>
<h3>Copyright</h3>
+
<p>Privacy Browser is copyright © 2015-2016 by <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
-<hr />
<h3>License</h3>
+
<p>Privacy Browser is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.
The full text of the license is at the bottom of this document.</p>
-<hr/>
<h3>Attributions</h3>
+
<p>The icons in Privacy Browser come from the Android Material icon set, which is released under the <a href=https://creativecommons.org/licenses/by/4.0/>CC-BY license</a>.</p>
<p><img class="left" src="images/privacy_browser.png" height="32" width="32">
<html>
<head>
- <style>
- h3 {
+<style>
+ h3 {
color: 0D4781;
- }
- </style>
+ }
+</style>
</head>
<body>
<html>
<head>
- <style>
- h3 {
- color: 0D4781;
- }
- </style>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+</style>
</head>
<body>
<h3>Have full network access</h3>
+
<p><a href="https://developer.android.com/reference/android/Manifest.permission.html#INTERNET">android.permission.INTERNET</a></p>
-<p>Required for the WebView to access the internet. Without this permission, Privacy Browser would be “No Browser: Protecting Your Privacy by Staying Completely Off the Internet”.</p>
-<hr />
+<p>Required for the WebView to access the internet. Without this permission, Privacy Browser would be “No Browser: Protecting Your Privacy by Staying Completely
+ Off the Internet”.</p>
+
<h3>Install shortcuts</h3>
+
<p><a href="https://developer.android.com/reference/android/Manifest.permission.html#INSTALL_SHORTCUT">com.android.launcher.permission.INSTALL_SHORTCUT</a></p>
+
<p>Required to add shortcuts for websites to the launcher desktop.</p>
</body>
</html>
\ No newline at end of file
<html>
<head>
- <style>
- h3 {
- color: 0D4781;
- }
-
- strong {
- color: B71C1C;
- }
-
- item {
- color: 1976D2;
- font-weight: bold;
- }
- </style>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ strong {
+ color: B71C1C;
+ }
+
+ item {
+ color: 1976D2;
+ font-weight: bold;
+ }
+</style>
</head>
<body>
<h3>Privacy Browser</h3>
+
<p><strong>Privacy Browser does not collect any user information</strong>.</p>
-<hr />
<h3>Google Play Ratings</h3>
+
<p>Google Play has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
Google provides developers with <em>anonymized summaries</em> of the following information related to user ratings.
<strong>Stoutner may use this information for any purpose</strong>.</p>
+
<ul>
<li><item>Country</item></li>
<li><item>Language</item></li>
<li><item>Tablets</item> (eg. Tablets 10" and above)</li>
</ul>
-<hr />
<h3>Google Play Reviews</h3>
+
<p>Google Play has it <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
In addition to the name of the reviewer, the rating, and the text of the review (which are all available publicly),
Google provides some or all of the following information to the developer.
<strong>Stoutner may use this information for any purpose</strong>.</p>
+
<ul>
<li><item>Version code</item> (eg. 7)</li>
<li><item>Version name</item> (eg. 1.6)</li>
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ strong {
+ color: BF360C;
+ }
+</style>
+</head>
+
+<body>
+<h3>Cleaning Out the Cruft</h3>
+
+<p>Clear and Exit does the following things:</p>
+
+<ul>
+ <li><strong>Removes all cookies</strong>.</li>
+ <li><strong>Removes all DOM storage</strong>.</li>
+ <li><strong>Clears the cache, including disk files</strong>.</li>
+ <li><strong>Clears the back/forward history</strong>.</li>
+ <li><strong>Destroys the internal state of the WebView</strong>.</li>
+ <li><strong>Closes Privacy Browser</strong>. For Android Lollipop and newer (version >= 5.0 or API >= 21), Privacy Browser is also removed from the recent app list.</li>
+</ul>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<!-- We have to make an image into its own block to center it. -->
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ img.center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ }
+</style>
+</head>
+
+<body>
+<h3>JavaScript Is Powerful</h3>
+
+<p>Back in the early days of the internet, web pages were static, meaning they they contained text and images that 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 was one of these technologies.</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>
+
+<h3>JavaScript Is Dangerous</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 on the device. 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.</p>
+
+<p><img class="center" src="images/webkay.png" height="640" width="360"></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 src="images/privacy_browser.png" height="16" width="16"> or yellow <img src="images/warning.png" height="16" width="16"> (both of which indicate
+ that JavaScript is disabled) and red <img src="images/javascript_enabled.png" height="16" width="16"> (JavaScript enabled) and and reload the website.
+ 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 to protecting user 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 only contain less annoying advertisements, instead of those that do things like cover up the text of the
+ entire web page.</p>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+</style>
+</head>
+
+<body>
+<h3>First-Party Cookies</h3>
+
+<p>Cookies can be divided into two types. First-party cookies are cookies set by the website in the URL bar at the top of the page.</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 the zip code, and without the need for
+ the user to create an account on the website (which would be overkill for such a simple task).</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, as cell phones often do.</p>
+
+<p>Some websites with logins require first-party cookies to be enabled for a user to stay logged in. Cookies aren't the only only way
+ a website can maintain a user logged in as they move from page to page on the site, but if a particular website has chosen to
+ implement logins in that way, enabling first-party cookies on that site will be the only way to use the functionality.</p>
+
+<p>If first-party cookies are enabled but JavaScript is disabled, the privacy icon will be yellow <img src="images/warning.png" height="16" width="16">
+ as a warning.</p>
+
+
+<h3>Third-Party Cookies</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.
+ For example, most website that have advertisements load them from a third-party ad broker, like Google's
+ <a href="https://www.google.com/adsense/start/#?modal_active=none">Ad Sense</a>. Every time the website loads, it requests the ad
+ broker to display some ads. The ad broker analyzes any information they may have about the user, looks at the current
+ rate advertisers are willing to pay for their ads, and selects those to display. The section of the website that displays
+ the ads is loaded from the third-party broker's server instead of the main server.</p>
+
+<p>Because most of the advertisements on the internet are displayed from only a few brokers, it didn't take long for them to realize
+ that they could set a tracking cookie on the user's device and know every place that user goes. Every time an ad loads from a broker,
+ the first thing it does it check to see if if the device already has a unique serial number in a tracking cookie. If it does, it looks up
+ the profile for that serial number and makes a note of the new site. This is why a user can do a search on one website for a
+ product that they typically don't look for, like walnuts, and then suddenly start seeing advertisements for walnuts on every
+ website they visit.</p>
+
+<p>In addition to ad brokers, social media sites discovered they could get in on the action. A few years ago, the major social media sites
+ like Facebook and Twitter convinced a large number of websites that it would be in there best interest to place little social media
+ icons on their pages. These are not just images. They contain <a href="https://developers.facebook.com/docs/plugins/like-button/">imbedded code</a> that
+ links back to the social media site, and, among other things, loads a third-party cookie on the device. These cookies are placed even if the user does
+ not have an account with the social media platform. Over time, companies like Facebook (which also run an ad network) have built up quite a large number
+ of detailed profiles about people who have <a href="http://www.theverge.com/2016/5/27/11795248/facebook-ad-network-non-users-cookies-plug-ins">never even
+ created an account on their site</a>.</p>
+
+<p>There is almost no good reason to ever enable third-party cookies. On devices with Android KitKat or older (version <= 4.4.4 or API <= 20), WebView
+ does not <a href="https://developer.android.com/reference/android/webkit/CookieManager.html#acceptThirdPartyCookies(android.webkit.WebView)">differentiate
+ between first-party and third-party cookies</a>. Thus, enabling first-party cookies will also enable third-party cookies.</p>
+
+
+<h3>DOM Storage</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 between <a href="https://en.wikipedia.org/wiki/Web_storage#Storage_size">5-25 megabytes per site</a>.
+ Because DOM storage uses JavaScript to read and write data, enabling it will do nothing unless JavaScript is also enabled.</p>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+</style>
+</head>
+
+<body>
+<h3>True Privacy</h3>
+
+<p>Privacy Browser is designed to let you take as much control of your privacy as possible while still browsing the internet.
+ When you connect 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 so it knows 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>However, most website operators want to track your web browsing across multiple websites, not just on a single server. There are many techniques they use to do so.
+ Some of them involve requesting or placing extra information on your device that facilitates this tracking. Almost all browsers will voluntarily participate in this tracking
+ without informing the user they are doing so. Privacy Browser is designed to grant the user as much information and control over these tracking techniques as possible.</p>
+
+
+<h3>WebView Limitations</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.
+ Once Privacy Browser has matured to take full advantage of all the privacy options WebView does offer, some consideration might be made to imbedding a customized WebView
+ or using a different rendering engine.</p>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ strong {
+ color: BF360C;
+ }
+</style>
+</head>
+
+<body>
+<h3>The Best Is Yet to Come</h3>
+
+<p>Privacy Browser is still in its infancy. Most of the best features are yet to be implemented. They include the following:</p>
+
+<ul>
+ <li><strong>SSL certificate controls</strong>.</li>
+ <li><strong>Fine grained controls for cookies and DOM storage</strong>.</li>
+ <li><strong>Automatically loading of privacy settings by URL</strong>.</li>
+ <li><strong>Encrypted sync between devices</strong>.</li>
+ <li><strong>Tabbed browsing</strong>.</li>
+</ul>
+
+<p>A full list of planned features and bug reports is available on <a href="https://redmine.stoutner.com/projects/privacy-browser/issues">redmine.stoutner.com</a>.</p>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ strong {
+ color: BF360C;
+ }
+</style>
+</head>
+
+<body>
+<h3>Masking IP Addresses</h3>
+
+<p>Although it isn't a perfect science, IP addresses can be turned into physical addresses with increasing accuracy.
+ There are <a href="https://www.whatismyip.com/">public databases</a> that show which ISP owns which IP address with a
+ good sense of which region they use it in. There are private databases with more accurate information. And, of course,
+ the ISP knows the exact service address of each IP address.</p>
+
+<p>VPN services can mask a device's IP address from a web server. When a VPN service is engaged, all traffic is encrypted and routed
+ through the VPN server. The web server only sees the IP address of the VPN server. This is sufficient for maintaining anonymity
+ from web server operators and advertisers, but it isn't sufficient for maintaining anonymity from oppressive regimes which might
+ be able to lean on VPN operators to turn over their logs showing the original IP addresses. Those looking for safety from such
+ regimes or desiring to blow the whistle on government agencies need something more.</p>
+
+<p>The Tor (The Onion Router) network was designed for just such purposes. It bounces encrypted web traffic through at least three independent servers
+ that volunteer bandwidth to the project. None of the servers have enough information to identify both the IP address of the original computer
+ and the final destination. Therefore, any government agency wanting to access the information would have to compromise all the machines in the
+ link, which are dispersed over the globe. This doesn't provide perfect privacy, but it gets pretty close.</p>
+
+<p>The Tor project has an app for Android called Orbot, which is available on <a href="https://f-droid.org/repository/browse/?fdfilter=orbot&fdid=org.torproject.android">F-Droid</a>
+ and everywhere else Privacy Browser is distributed. Orbot can operate in three modes.</p>
+
+<ul>
+ <li><strong>Proxy mode</strong> Apps have to request to proxy their traffic through Orbot, meaning that each app developer has to add code to
+ their project to make it work.</li>
+ <li><strong>Transparent proxy mode</strong> Orbot intercepts traffic from other apps as it heads out onto the network and redirects it to the
+ Tor network. Apps do not need to be modified by their developer to work with transparent proxy mode, but it does require that Orbot have
+ root access on the device.</li>
+ <li><strong>VPN mode</strong> Orbot registers itself as a VPN using Android's builtin VPN interface. Apps do not need to be modified by the
+ developer to work with Orbot in VPN mode and root is not required.</li>
+</ul>
+
+<p>Currently, Privacy Browser works with Orbot in transparent proxy and VPN modes. Support for the standard proxy mode will be added in a
+ <a href="https://redmine.stoutner.com/issues/26">future release</a>.</p>
+
+<p>Because traffic is being routed through several Tor nodes, using Tor is often much slower than going straight to the internet.</p>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ img.center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ }
+</style>
+</head>
+
+<body>
+<h3>Advertisements</h3>
+
+<p>Privacy Browser Free includes a banner advertisement across the bottom of the screen that is populated by Google's
+ AdMob network. By default, Google provides the <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">advertising ID</a>
+ of the device to the ads displayed through this network. This allows advertising companies to build a profile of
+ the device that show which apps are installed (that display ads), how often they are used, and which ads the user is interested in.</p>
+
+<p>Users can choose to disable the advertising ID in <strong>Settings</strong>, <strong>Google</strong>, <strong>Ads</strong>.</p>
+
+<img class="center" src="images/advertising_id.png" height="640" width="360">
+
+<p>The purpose of the free version of Privacy Browser is to allow people to test the features of the app. The standard version can be purchased
+ on the major app stores or downloaded for free from
+ <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
+
+
+<h3>Verizon Tracking Headers</h3>
+
+<p>Verizon, one of the major mobile carriers in the United States, adds a unique tracking header to all HTTP traffic on their network. The Electronic Frontier
+ Foundation has written about the <a href="https://www.eff.org/deeplinks/2014/11/verizon-x-uidh">privacy implications of this practice</a>. Due to public pressure
+ Verizon has created a way to <a href="http://www.clark.com/how-opt-out-verizons-super-cookie-tracking">opt out of this tracking</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ Copyright 2016 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/>. -->
+
+<html>
+<head>
+<!-- We have to make an image into its own block to center it. -->
+<style>
+ h3 {
+ color: 0D4781;
+ }
+
+ img.center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ }
+</style>
+</head>
+
+<body>
+<h3>Browser Identification</h3>
+
+<p>When web browsers connect to websites, they send a user agent, which identifies the browser and the
+ rendering capabilities it possesses. They website 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>By default, Privacy Browser uses the built-in user agent that comes with the WebView installed on the
+ device. You can see what it is by going to the <strong>Settings</strong> screen and setting the <strong>User
+ agent</strong> to <strong>WebView Default</strong>. The screenshot below shows a Nexus 6P running Android 6.0.1
+ with Android System WebView 51.0.2704.81 installed.</p>
+
+<img class="center" src="images/user_agent.png" height="640" width="360">
+
+<p>There is enough information in the user agent that someitmes 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.</p>
+
+<img class="center" src="images/panopticlick.png" height=640" width="360">
+
+<p>Privacy Browser allows you to change the user agent. There are several preset options that match common browsers and operating systems.
+ Privacy Browser also has its own user agent, which is simply PrivacyBrowser/1.0. For tracking purposes, anything that is rare is easier
+ to track. If Privacy Browser becomes common and many people use PrivacyBrowser/1.0 as their user agent, it will be a good choice for privacy.
+ For now, choosing something that has lots of hits on a web server, like <strong>Edge 13 on Windows 10</strong>, allows the device to
+ blend in with the crowd. Firefox or Chrome provide less privacy because 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>A second reason to change the user agent is to convince the web server to send the desktop version of the web page, which often works
+ better on modern smart phones than the mobile version. For this purpose, PrivacyBrowser/1.0 works well, because web servers typically
+ default to the desktop version unless they recognize a phone browser agent.</p>
+
+<p>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>
+</body>
+</html>
\ No newline at end of file
// Display the home arrow on supportAppBar.
final ActionBar appBar = getSupportActionBar();
- assert appBar != null;// This assert removes the incorrect warning on the following line that appBar might be null.
+ assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that appBar might be null.
appBar.setDisplayHomeAsUpEnabled(true);
// Setup the ViewPager.
ViewPager aboutViewPager = (ViewPager) findViewById(R.id.about_viewpager);
- assert aboutViewPager != null; // This assert removes the incorrect warning on the following line that aboutViewPager might be null.
+ assert aboutViewPager != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutViewPager might be null.
aboutViewPager.setAdapter(new aboutPagerAdapter(getSupportFragmentManager()));
// Setup the TabLayout and connect it to the ViewPager.
TabLayout aboutTabLayout = (TabLayout) findViewById(R.id.about_tablayout);
- assert aboutTabLayout != null; // This assert removes the incorrect warning on the following line that aboutTabLayout might be null.
+ assert aboutTabLayout != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutTabLayout might be null.
aboutTabLayout.setupWithViewPager(aboutViewPager);
}
return AboutTabFragment.createTab(tab);
}
}
-
-
}
public static AboutTabFragment createTab(int tab) {
Bundle thisTabArguments = new Bundle();
thisTabArguments.putInt("Tab", tab);
+
AboutTabFragment thisTab = new AboutTabFragment();
thisTab.setArguments(thisTabArguments);
return thisTab;
}
@Override
- public void onCreate (Bundle savedInstanceState) {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Store the tab number in tabNumber.
case 6:
tabWebView.loadUrl("file:///android_asset/about_links.html");
+ break;
default:
break;
--- /dev/null
+/**
+ * Copyright 2016 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;
+
+import android.os.Bundle;
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+
+public class GuideActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.guide_coordinatorlayout);
+
+ // We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21.
+ Toolbar supportAppBar = (Toolbar) findViewById(R.id.guide_toolbar);
+ setSupportActionBar(supportAppBar);
+
+ // Display the home arrow on supportAppBar.
+ final ActionBar appBar = getSupportActionBar();
+ assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that appBar might be null.
+ appBar.setDisplayHomeAsUpEnabled(true);
+
+ // Setup the ViewPager.
+ ViewPager aboutViewPager = (ViewPager) findViewById(R.id.guide_viewpager);
+ assert aboutViewPager != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutViewPager might be null.
+ aboutViewPager.setAdapter(new guidePagerAdapter(getSupportFragmentManager()));
+
+ // Setup the TabLayout and connect it to the ViewPager.
+ TabLayout aboutTabLayout = (TabLayout) findViewById(R.id.guide_tablayout);
+ assert aboutTabLayout != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutTabLayout might be null.
+ aboutTabLayout.setupWithViewPager(aboutViewPager);
+ }
+
+ public class guidePagerAdapter extends FragmentPagerAdapter {
+ public guidePagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ // Get the count of the number of tabs.
+ public int getCount() {
+ return 8;
+ }
+
+ @Override
+ // Get the name of each tab. Tab numbers start at 0.
+ public CharSequence getPageTitle(int tab) {
+ switch (tab) {
+ case 0:
+ return getString(R.string.overview);
+
+ case 1:
+ return getString(R.string.javascript);
+
+ case 2:
+ return getString(R.string.local_storage);
+
+ case 3:
+ return getString(R.string.user_agent);
+
+ case 4:
+ return getString(R.string.tor);
+
+ case 5:
+ return getString(R.string.tracking_uids);
+
+ case 6:
+ return getString(R.string.clear_and_exit);
+
+ case 7:
+ return getString(R.string.planned_features);
+
+ default:
+ return "";
+ }
+ }
+
+ @Override
+ // Setup each tab.
+ public Fragment getItem(int tab) {
+ return GuideTabFragment.createTab(tab);
+ }
+ }
+
+}
--- /dev/null
+/**
+ * Copyright 2016 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;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+
+public class GuideTabFragment extends Fragment {
+ private int tabNumber;
+
+ // GuideTabFragment.createTab stores the tab number in the bundle arguments so it can be referenced from onCreate().
+ public static GuideTabFragment createTab (int tab) {
+ Bundle thisTabArguments = new Bundle();
+ thisTabArguments.putInt("Tab", tab);
+
+ GuideTabFragment thisTab = new GuideTabFragment();
+ thisTab.setArguments(thisTabArguments);
+ return thisTab;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Store the tab number in tabNumber.
+ tabNumber = getArguments().getInt("Tab");
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ // Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container.
+ // The fragment will take care of attaching the root automatically.
+ View tabLayout = inflater.inflate(R.layout.guide_tab_webview, container, false);
+ WebView tabWebView = (WebView) tabLayout;
+
+ // Tab numbers start at 0.
+ switch (tabNumber) {
+ case 0:
+ tabWebView.loadUrl("file:///android_asset/guide_overview.html");
+ break;
+
+ case 1:
+ tabWebView.loadUrl("file:///android_asset/guide_javascript.html");
+ break;
+
+ case 2:
+ tabWebView.loadUrl("file:///android_asset/guide_local_storage.html");
+ break;
+
+ case 3:
+ tabWebView.loadUrl("file:///android_asset/guide_user_agent.html");
+ break;
+
+ case 4:
+ tabWebView.loadUrl("file:///android_asset/guide_tor.html");
+ break;
+
+ case 5:
+ tabWebView.loadUrl("file:///android_asset/guide_tracking_uids.html");
+ break;
+
+ case 6:
+ tabWebView.loadUrl("file:///android_asset/guide_clear_and_exit.html");
+ break;
+
+ case 7:
+ tabWebView.loadUrl("file:///android_asset/guide_planned_features.html");
+ break;
+
+ default:
+ break;
+ }
+
+ return tabLayout;
+ }
+}
// Update the progress bar when a page is loading.
@Override
public void onProgressChanged(WebView view, int progress) {
- // Make sure that appBar is not null.
- if (appBar != null) {
- ProgressBar progressBar = (ProgressBar) appBar.getCustomView().findViewById(R.id.progressBar);
- progressBar.setProgress(progress);
- if (progress < 100) {
- progressBar.setVisibility(View.VISIBLE);
- } else {
- progressBar.setVisibility(View.GONE);
+ ProgressBar progressBar = (ProgressBar) appBar.getCustomView().findViewById(R.id.progressBar);
+ progressBar.setProgress(progress);
+ if (progress < 100) {
+ progressBar.setVisibility(View.VISIBLE);
+ } else {
+ progressBar.setVisibility(View.GONE);
- //Stop the SwipeToRefresh indicator if it is running
- swipeToRefresh.setRefreshing(false);
- }
+ //Stop the SwipeToRefresh indicator if it is running
+ swipeToRefresh.setRefreshing(false);
}
}
// Save a copy of the favorite icon for use if a shortcut is added to the home screen.
favoriteIcon = icon;
- // Place the favorite icon in the appBar if it is not null.
- if (appBar != null) {
- ImageView imageViewFavoriteIcon = (ImageView) appBar.getCustomView().findViewById(R.id.favoriteIcon);
- imageViewFavoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
- }
+ // Place the favorite icon in the appBar.
+ ImageView imageViewFavoriteIcon = (ImageView) appBar.getCustomView().findViewById(R.id.favoriteIcon);
+ imageViewFavoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
}
// Enter full screen video
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
- if (appBar != null) {
- appBar.hide();
- }
+ appBar.hide();
// Show the fullScreenVideoFrameLayout.
assert fullScreenVideoFrameLayout != null; //This assert removes the incorrect warning on the following line that fullScreenVideoFrameLayout might be null.
// Exit full screen video
public void onHideCustomView() {
- if (appBar != null) {
- appBar.show();
- }
+ appBar.show();
// Show the mainWebView.
mainWebView.setVisibility(View.VISIBLE);
MenuItem clearCookies = menu.findItem(R.id.clearCookies);
clearCookies.setEnabled(cookieManager.hasCookies());
+ // Enable DOM Storage if JavaScript is enabled.
+ MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
+ toggleDomStorage.setEnabled(javaScriptEnabled);
+
// Run all the other default commands.
super.onPrepareOptionsMenu(menu);
if (javaScriptEnabled) {
Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
} else {
- if (domStorageEnabled || firstPartyCookiesEnabled) {
+ if (firstPartyCookiesEnabled) {
Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
// Apply the new DOM Storage status.
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
- // Update the privacy icon.
- updatePrivacyIcon();
-
// Reload the WebView.
mainWebView.reload();
return true;
startActivity(downloadManagerIntent);
break;
+ case R.id.guide:
+ // Launch GuideActivity.
+ Intent guideIntent = new Intent(this, GuideActivity.class);
+ startActivity(guideIntent);
+ break;
+
case R.id.settings:
// Launch SettingsActivity.
Intent settingsIntent = new Intent(this, SettingsActivity.class);
break;
case R.id.clearAndExit:
- // Clear DOM storage.
- WebStorage domStorage = WebStorage.getInstance();
- domStorage.deleteAllData();
-
// Clear cookies. The commands changed slightly in API 21.
if (Build.VERSION.SDK_INT >= 21) {
cookieManager.removeAllCookies(null);
cookieManager.removeAllCookie();
}
+ // Clear DOM storage.
+ WebStorage domStorage = WebStorage.getInstance();
+ domStorage.deleteAllData();
+
// Clear cache. The argument of "true" includes disk files.
mainWebView.clearCache(true);
drawerLayout.closeDrawer(GravityCompat.START);
} else {
// Load the previous URL if available.
- assert mainWebView != null; //This assert removes the incorrect warning on the following line that mainWebView might be null.
+ assert mainWebView != null; //This assert removes the incorrect warning in Android Studio on the following line that mainWebView might be null.
if (mainWebView.canGoBack()) {
mainWebView.goBack();
} else {
if (javaScriptEnabled) {
privacyIcon.setIcon(R.drawable.javascript_enabled);
} else {
- if (domStorageEnabled || firstPartyCookiesEnabled) {
+ if (firstPartyCookiesEnabled) {
privacyIcon.setIcon(R.drawable.warning);
} else {
privacyIcon.setIcon(R.drawable.privacy_mode);
// Initialize savedPreferences.
savedPreferences = getPreferenceScreen().getSharedPreferences();
+ // Allow the user to access "dom_storage_enabled" if "javascript_enabled" is enabled. The default is false.
+ final Preference domStorageEnabled = findPreference("dom_storage_enabled");
+ domStorageEnabled.setEnabled(savedPreferences.getBoolean("javascript_enabled", false));
+
+ // Allow the user to access "third_party_cookies_enabled" if "first_party_cookies_enabled" is enabled. The default is false.
+ final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
+ thirdPartyCookiesEnabled.setEnabled(savedPreferences.getBoolean("first_party_cookies_enabled", false));
// Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded.
final Preference userAgentPreference = findPreference("user_agent");
// Listen for preference changes.
preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
- // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.
+ // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled. We know.
@SuppressLint("SetJavaScriptEnabled")
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- // Several keys need to update the toggleJavaScript icon.
- MenuItem toggleJavaScript = MainWebViewActivity.mainMenu.findItem(R.id.toggleJavaScript);
-
switch (key) {
case "javascript_enabled":
// Set javaScriptEnabled to the new state. The default is false.
MainWebViewActivity.javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false);
+ // Toggle the state of the "dom_storage_enabled" preference. The default is false.
+ final Preference domStorageEnabled = findPreference("dom_storage_enabled");
+ domStorageEnabled.setEnabled(sharedPreferences.getBoolean("javascript_enabled", false));
+
// Update mainWebView and reload the website.
MainWebViewActivity.mainWebView.getSettings().setJavaScriptEnabled(MainWebViewActivity.javaScriptEnabled);
MainWebViewActivity.mainWebView.reload();
- // Update the toggleJavaScript icon.
- if (MainWebViewActivity.javaScriptEnabled) {
- toggleJavaScript.setIcon(R.drawable.javascript_enabled);
- } else {
- if (MainWebViewActivity.firstPartyCookiesEnabled || MainWebViewActivity.domStorageEnabled) {
- toggleJavaScript.setIcon(R.drawable.warning);
- } else {
- toggleJavaScript.setIcon(R.drawable.privacy_mode);
- }
- }
+ // Update the privacy icon.
+ updatePrivacyIcon();
break;
case "first_party_cookies_enabled":
// Set firstPartyCookiesEnabled to the new state. The default is false.
MainWebViewActivity.firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false);
- // Update the checkbox in the options menu.
- MenuItem firstPartyCookiesMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleFirstPartyCookies);
- firstPartyCookiesMenuItem.setChecked(MainWebViewActivity.firstPartyCookiesEnabled);
+ // Toggle the state of the "third_party_cookies_enabled" preference. The default is false.
+ final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
+ thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false));
// Update mainWebView and reload the website.
MainWebViewActivity.cookieManager.setAcceptCookie(MainWebViewActivity.firstPartyCookiesEnabled);
MainWebViewActivity.mainWebView.reload();
- // Update the toggleJavaScript icon.
- if (MainWebViewActivity.javaScriptEnabled) {
- toggleJavaScript.setIcon(R.drawable.javascript_enabled);
- } else {
- if (MainWebViewActivity.firstPartyCookiesEnabled || MainWebViewActivity.domStorageEnabled) {
- toggleJavaScript.setIcon(R.drawable.warning);
- } else {
- toggleJavaScript.setIcon(R.drawable.privacy_mode);
- }
- }
+ // Update the checkbox in the options menu.
+ MenuItem firstPartyCookiesMenuItem = MainWebViewActivity.mainMenu.findItem(R.id.toggleFirstPartyCookies);
+ firstPartyCookiesMenuItem.setChecked(MainWebViewActivity.firstPartyCookiesEnabled);
+
+ // Update the privacy icon.
+ updatePrivacyIcon();
break;
case "third_party_cookies_enabled":
MainWebViewActivity.mainWebView.getSettings().setDomStorageEnabled(MainWebViewActivity.domStorageEnabled);
MainWebViewActivity.mainWebView.reload();
- // Update the toggleJavaScript icon.
- if (MainWebViewActivity.javaScriptEnabled) {
- toggleJavaScript.setIcon(R.drawable.javascript_enabled);
- } else {
- if (MainWebViewActivity.firstPartyCookiesEnabled || MainWebViewActivity.domStorageEnabled) {
- toggleJavaScript.setIcon(R.drawable.warning);
- } else {
- toggleJavaScript.setIcon(R.drawable.privacy_mode);
- }
- }
+ // Update the privacy icon.
+ updatePrivacyIcon();
break;
case "user_agent":
super.onResume();
savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
}
+
+ private void updatePrivacyIcon() {
+ // Define a reference to the toggleJavaScript icon.
+ MenuItem toggleJavaScript = MainWebViewActivity.mainMenu.findItem(R.id.toggleJavaScript);
+
+ if (MainWebViewActivity.javaScriptEnabled) {
+ toggleJavaScript.setIcon(R.drawable.javascript_enabled);
+ } else {
+ if (MainWebViewActivity.firstPartyCookiesEnabled) {
+ toggleJavaScript.setIcon(R.drawable.warning);
+ } else {
+ toggleJavaScript.setIcon(R.drawable.privacy_mode);
+ }
+ }
+ }
}
<!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
- to make the status bar transparent, darkened overlay. -->
+ to make the status bar a transparent, darkened overlay. -->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/about_coordinatorlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"
- android:padding="16dp">
+ android:padding="16dp" >
<!-- The RelativeLayout contains the header. -->
<RelativeLayout
android:id="@+id/about_version_relativelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- xmlns:tools="http://schemas.android.com/tools">
+ xmlns:tools="http://schemas.android.com/tools" >
<!--tools:ignore="ContentDescription" suppresses the lint warning about supplying a content description for the ImageView,
which isn't needed in this case because the ImageView is only decorative. -->
android:paddingStart="4dp"
android:paddingEnd="0dp"
android:paddingLeft="4dp"
- android:paddingRight="4dp">
+ android:paddingRight="4dp" >
<!-- Hardware. -->
<TextView
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright 2016 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/>. -->
+
+<!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
+ When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
+ to make the status bar a transparent, darkened overlay. -->
+<android.support.design.widget.CoordinatorLayout
+ android:id="@+id/guide_coordinatorlayout"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:fitsSystemWindows="true" >
+
+ <!-- the LinearLayout with orientation="vertical" moves the ViewPager below the AppBarLayout. -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <!-- We need to set android:background="@color/blue" here or any space to the right of the TabLayout on large devices will be white. -->
+ <android.support.design.widget.AppBarLayout
+ android:id="@+id/guide_appbarlayout"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="@color/blue"
+ android:theme="@style/PrivacyBrowser.AppBarOverlay" >
+
+ <!-- android:theme="@style/PrivacyBrowser.DarkAppBar" makes the text and icons in the AppBar white. -->
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/guide_toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/blue"
+ android:theme="@style/PrivacyBrowser.DarkAppBar"
+ app:popupTheme="@style/PrivacyBrowser.PopupOverlay" />
+
+ <android.support.design.widget.TabLayout
+ android:id="@+id/guide_tablayout"
+ xmlns:android.support.design="http://schemas.android.com/apk/res-auto"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android.support.design:tabBackground="@color/blue"
+ android.support.design:tabTextColor="@color/light_blue"
+ android.support.design:tabSelectedTextColor="@color/white"
+ android.support.design:tabIndicatorColor="@color/white"
+ android.support.design:tabMode="scrollable" />
+ </android.support.design.widget.AppBarLayout>
+
+ <!-- android:layout_weight="1" makes about_viewpager fill the rest of the screen. -->
+ <android.support.v4.view.ViewPager
+ android:id="@+id/guide_viewpager"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ </LinearLayout>
+</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright 2016 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/>. -->
+
+<!-- This WebView displays inside of the tabs in GuideActivity. -->
+<WebView
+ android:id="@+id/guide_tab_webview"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
\ No newline at end of file
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
<resources>
- <!-- The default actionBarSize is 56dp. 53dp is the smallest that doesn't cause the urlTextBox to scroll vertically with a font size of Huge.
- android:windowTranslucentStatus requires API >= 19. It makes the system status bar transparent.
+ <!-- android:windowTranslucentStatus requires API >= 19. It makes the system status bar transparent.
When it is specified the root layout should include android:fitsSystemWindows="true". -->
<style name="PrivacyBrowser.MainWebView">
- <item name="android:actionBarSize">53dp</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
<!-- android:windowTranslucentStatus requires API >= 19. It makes the system status bar transparent.
When it is specified the root layout should include android:fitsSystemWindows="true".
colorPrimaryDark goes behind the status bar, which is then darkened by the overlay. -->
- <style name="PrivacyBrowser.About">
+ <style name="PrivacyBrowser.TabActivity">
<item name="android:windowTranslucentStatus">true</item>
<item name="colorPrimaryDark">@color/blue</item>
</style>
<string name="cancel">Cancel</string>
<string name="create">Create</string>
+ <!-- Guide. -->
+ <string name="privacy_browser_guide">Privacy Browser Guide</string>
+ <string name="overview">Overview</string>
+ <string name="local_storage">Local Storage</string>
+ <string name="tor">Tor</string>
+ <string name="tracking_uids">Tracking UIDs</string>
+ <string name="planned_features">Planned Features</string>
+
<!-- Preferences. -->
<string name="privacy">Privacy</string>
<string name="javascript_preference">Enable JavaScript by default</string>
<string name="javascript_preference_summary">JavaScript allows websites to run programs (scripts) on your device.</string>
<string name="first_party_cookies_preference">Enable first-party cookies by default</string>
- <string name="first_party_cookies_preference_summary">Cookies allow websites to store information on your device.
- First-party cookies come from the server listed in the address bar.
- Devices with versions of Android older than Lollipop (version 5.0) will also enable third-party cookies with this setting.</string>
+ <string name="first_party_cookies_preference_summary">Devices with versions of Android older than Lollipop (version 5.0) will also enable third-party cookies with this setting.</string>
<string name="third_party_cookies_preference">Enable third-party cookies by default</string>
- <string name="third_party_cookies_summary">Third-party cookies allow parts of websites that aren\'t the main website, like advertisements, to store information on your device.
- This setting requires Android Lollipop (version 5.0) or higher. This setting has no effect if first-party cookies are disabled.</string>
+ <string name="third_party_cookies_summary">This setting requires Android Lollipop (version 5.0) or higher. It has no effect if first-party cookies are disabled.</string>
<string name="dom_storage_preference">Enable DOM storage by default</string>
- <string name="dom_storage_preference_summary">Document Object Management storage, also called web storage, is an enhanced form of cookies
- that allows websites to store larger and more complex types of information, like pictures, on your device.</string>
+ <string name="dom_storage_preference_summary">JavaScript must be enabled for DOM storage to function.</string>
<string name="user_agent">User agent</string>
<string-array name="user_agent_entries">
<item>WebView Default</item>
<item name="colorAccent">@color/blue</item>
</style>
- <!-- The default actionBarSize is 56dp. 53dp is the smallest that doesn't cause the urlTextBox to scroll vertically with a font size of Huge. -->
- <style name="PrivacyBrowser.MainWebView">
- <item name="android:actionBarSize">53dp</item>
- </style>
+ <style name="PrivacyBrowser.MainWebView" />
- <style name="PrivacyBrowser.About">
- <item name="colorPrimaryDark">@color/blue</item>
- </style>
+ <style name="PrivacyBrowser.TabActivity" />
<!-- colorPrimaryDark is the color of the status bar. -->
<style name="PrivacyBrowser.Settings" parent="Theme.AppCompat.Light.DarkActionBar">