From: Soren Stoutner Date: Thu, 15 Sep 2016 05:15:07 +0000 (-0700) Subject: Implement Orbot proxy support. Fixes https://redmine.stoutner.com/issues/26. X-Git-Tag: v1.10~2 X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=commitdiff_plain;h=b36f8bd357e28072bd7c810bb3ae47e4e0b20acc Implement Orbot proxy support. Fixes https://redmine.stoutner.com/issues/26. --- diff --git a/.idea/dictionaries/soren.xml b/.idea/dictionaries/soren.xml index c623c835..5818a708 100644 --- a/.idea/dictionaries/soren.xml +++ b/.idea/dictionaries/soren.xml @@ -39,6 +39,7 @@ oname orbot panopticlick + parameterized parentfolder programatically qwant @@ -58,6 +59,7 @@ tablayout techrepublic textview + torproject uids uname webkay diff --git a/app/src/main/assets/de/images/tor.png b/app/src/main/assets/de/images/tor.png new file mode 120000 index 00000000..4d657c3f --- /dev/null +++ b/app/src/main/assets/de/images/tor.png @@ -0,0 +1 @@ +../../en/images/tor.png \ No newline at end of file diff --git a/app/src/main/assets/en/guide_tor.html b/app/src/main/assets/en/guide_tor.html index caab3b4c..1ce0d59d 100644 --- a/app/src/main/assets/en/guide_tor.html +++ b/app/src/main/assets/en/guide_tor.html @@ -23,48 +23,71 @@ color: 0D4781; } - strong { - color: BF360C; + img.center { + display: block; + margin-left: auto; + margin-right: auto; } -

Masking IP Addresses

- -

Although it isn't a perfect science, IP addresses can be turned into physical addresses with increasing accuracy. - There are public databases 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.

- -

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, as well as accessing websites that intentionally block access from particular countries - (like some music and video streaming services), 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.

- -

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.

- -

The Tor project has an app for Android called Orbot, which is available on F-Droid - and everywhere else Privacy Browser is distributed. Orbot can operate in three modes.

- - - -

Currently, Privacy Browser works with Orbot in transparent proxy and VPN modes. Support for the standard proxy mode will be added in a - future release.

- -

Because traffic is being routed through several Tor nodes, using Tor is often much slower than connecting straight to the internet.

+

Tor and Its Limits

+ +

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. + TOR (The Onion Router) is useful in protecting privacy from malicious governments but not from mega corporations.

+ + +

Malicious Governments

+ +

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. Tor is designed to defeat this infringement of privacy by encrypting the traffic + from a user's device and routing it through three separate 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 IP address the user's device + 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 Tor. In some parts of + the world, using Tor could be construed as an evidence of illegal behavior ("if you didn't have anything + to hide you wouldn't be hiding your traffic from us") and users could be punished because governments + assume they are doing something that is prohibited. Thus, Tor can be helpful, but isn't a panacea.

+ + +

Mega Corporations

+ +

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 fair amount of accuracy. + Small web servers typically rely on IP addresses to identify the location of the users visiting their site. + Tor is 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 browser fingerprinting. 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 build profiles for almost every user online and can track their internet + activity across unrelated sites.

+ +

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 circumstance, number of pets, and everything else they can get their hands on. + They even buy up databases of credit card usage at 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, + Tor provides no real privacy protection against mega corporations.

+ +

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.

+ + +

Using Tor

+ +

Despite the limitations, Tor can be useful in some circumstances. The Tor project has an app for Android called Orbot, + which is available on F-Droid + and everywhere else that Privacy Browser is distributed. Privacy Browser has a setting to use Orbot as + a proxy. When this is turned on, Privacy Browser's app bar will have a light blue background instead of + the default light grey. When Privacy Browser's Orbot proxy setting is enabled, internet access + will not work unless Orbot is running and connected to Tor. Because traffic is being routed through several Tor nodes, + using Tor is often much slower than connecting straight to the internet.

+ + \ No newline at end of file diff --git a/app/src/main/assets/en/images/tor.png b/app/src/main/assets/en/images/tor.png new file mode 100644 index 00000000..58dc7e1f Binary files /dev/null and b/app/src/main/assets/en/images/tor.png differ diff --git a/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java b/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java index 5c670bcd..7d63bb22 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java @@ -119,7 +119,7 @@ public class AboutTabFragment extends Fragment { SpannableStringBuilder chromeStringBuilder = new SpannableStringBuilder(chromeLabel + chrome); // Create a blue `ForegroundColorSpan`. We have to use the deprecated `getColor` until API >= 23. - ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue)); + ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700)); // Setup the spans to display the device information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction. brandStringBuilder.setSpan(blueColorSpan, brandLabel.length(), brandStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); diff --git a/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseViewActivity.java index db5b198e..d4d0f4c6 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseViewActivity.java @@ -122,7 +122,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity { if (bookmarkParentFolder.isEmpty()) { parentFolderImageView.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.folder_grey)); bookmarkParentFolderTextView.setText(R.string.home_folder); - bookmarkParentFolderTextView.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.grey)); + bookmarkParentFolderTextView.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.grey_500)); } else { parentFolderImageView.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.folder_dark_blue)); bookmarkParentFolderTextView.setText(bookmarkParentFolder); diff --git a/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java index 4433cf38..54f6d8ff 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java @@ -23,6 +23,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.DialogFragment; import android.app.DownloadManager; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -74,6 +75,14 @@ import java.util.Map; // We need to use AppCompatActivity from android.support.v7.app.AppCompatActivity to have access to the SupportActionBar until the minimum API is >= 21. public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcut.CreateHomeScreenSchortcutListener, SslCertificateError.SslCertificateErrorListener, DownloadFile.DownloadFileListener { + // `privacyBrowserContext` is public static so it can be accessed from `SettingsFragment`. + // It is also used in `onCreate()` and `onConfigurationChanged()`. + public static Context privacyBrowserContext; + + // `appBar` is public static so it can be accessed from `OrbotProxyHelper`. + // It is also used in `onCreate()`. + public static ActionBar appBar; + // `favoriteIcon` is public static so it can be accessed from `CreateHomeScreenShortcut`, `BookmarksActivity`, `CreateBookmark`, `CreateBookmarkFolder`, and `EditBookmark`. // It is also used in `onCreate()` and `onCreateHomeScreenShortcutCreate()`. public static Bitmap favoriteIcon; @@ -162,10 +171,13 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // We need a handle for the activity, which is accessed from `SettingsFragment` and fed into `updatePrivacyIcons()`. privacyBrowserActivity = this; + // Get a handle for the application context. + privacyBrowserContext = getApplicationContext(); + // We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21. Toolbar supportAppBar = (Toolbar) findViewById(R.id.appBar); setSupportActionBar(supportAppBar); - final ActionBar appBar = getSupportActionBar(); + appBar = getSupportActionBar(); // This is needed to get rid of the Android Studio warning that appBar might be null. assert appBar != null; @@ -200,7 +212,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Implement swipe to refresh swipeToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout); assert swipeToRefresh != null; //This assert removes the incorrect warning on the following line that swipeToRefresh might be null. - swipeToRefresh.setColorSchemeResources(R.color.blue); + swipeToRefresh.setColorSchemeResources(R.color.blue_700); swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { @@ -448,6 +460,10 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation customHeaders.put("DNT", "1"); } + // Set Orbot proxy status. The default is `false`. + if (sharedPreferences.getBoolean("proxy_through_orbot", false)) { + OrbotProxyHelper.setProxy(privacyBrowserContext, privacyBrowserActivity, "localhost", "8118"); + } // Get the intent information that started the app. final Intent intent = getIntent(); @@ -469,7 +485,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // If the favorite icon is null, load the default. if (favoriteIcon == null) { // We have to use `ContextCompat` until API >= 21. - Drawable favoriteIconDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.world); + Drawable favoriteIconDrawable = ContextCompat.getDrawable(privacyBrowserContext, R.drawable.world); BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable; favoriteIcon = favoriteIconBitmapDrawable.getBitmap(); } @@ -951,7 +967,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation super.onConfigurationChanged(newConfig); // Reload the ad if this is the free flavor. - BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id)); + BannerAd.reloadAfterRotate(adView, privacyBrowserContext, getString(R.string.ad_id)); // Reinitialize the adView variable, as the View will have been removed and re-added in the free flavor by BannerAd.reloadAfterRotate(). adView = findViewById(R.id.adView); diff --git a/app/src/main/java/com/stoutner/privacybrowser/OrbotProxyHelper.java b/app/src/main/java/com/stoutner/privacybrowser/OrbotProxyHelper.java new file mode 100644 index 00000000..ec9ad58f --- /dev/null +++ b/app/src/main/java/com/stoutner/privacybrowser/OrbotProxyHelper.java @@ -0,0 +1,101 @@ +/** + * Copyright 2016 Soren Stoutner . + * + * This file is part of 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 . + */ + +package com.stoutner.privacybrowser; + +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Proxy; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; +import android.util.ArrayMap; +import android.util.Log; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class OrbotProxyHelper { + public static void setProxy(Context privacyBrowserContext, Activity parentActivity, String proxyHost, String proxyPort) { + // Set the proxy values + System.setProperty("http.proxyHost", proxyHost); + System.setProperty("http.proxyPort", proxyPort); + System.setProperty("https.proxyHost", proxyHost); + System.setProperty("https.proxyPort", proxyPort); + + // Use reflection to apply the new proxy values. + try { + Class applicationClass = Class.forName("android.app.Application"); + Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk"); + // `setAccessible(true)` allows us to change the value of `mLoadedApkField`. + mLoadedApkField.setAccessible(true); + Object mLoadedApkObject = mLoadedApkField.get(privacyBrowserContext); + + Class loadedApkClass = Class.forName("android.app.LoadedApk"); + Field mReceiversField = loadedApkClass.getDeclaredField("mReceivers"); + // `setAccessible(true)` allows us to change the value of `mReceiversField`. + mReceiversField.setAccessible(true); + + ArrayMap receivers = (ArrayMap) mReceiversField.get(mLoadedApkObject); + + for (Object receiverMap : receivers.values()) { + for (Object receiver : ((ArrayMap) receiverMap).keySet()) { + // We have to use `Class`, which is an `unbounded wildcard parameterized type`, instead of `Class`, which is a `raw type`, or `receiveClass.getDeclaredMethod` below will produce an error. + Class receiverClass = receiver.getClass(); + if (receiverClass.getName().contains("ProxyChangeListener")) { + Method onReceiveMethod = receiverClass.getDeclaredMethod("onReceive", Context.class, Intent.class); + Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); + onReceiveMethod.invoke(receiver, privacyBrowserContext, intent); + } + } + } + } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException exception) { + Log.d("enableProxyThroughOrbot", "Exception: " + exception); + } + + if (proxyPort.equals("8118")) { // Orbot proxy was turned on. + // Set the `appBar` background to be light blue if Orbot proxy support is enabled. + MainWebViewActivity.appBar.setBackgroundDrawable(ContextCompat.getDrawable(privacyBrowserContext, R.color.blue_50)); + + try { // Check to see if Orbot is installed. + PackageManager packageManager = privacyBrowserContext.getPackageManager(); + packageManager.getPackageInfo("org.torproject.android", PackageManager.GET_ACTIVITIES); + } catch (PackageManager.NameNotFoundException exception){ // If an exception is thrown, Orbot is not installed. + // Build an `AlertDialog`. `R.style.LightAlertDialog` formats the color of the button text. + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(parentActivity, R.style.LightAlertDialog); + dialogBuilder.setMessage(R.string.orbot_proxy_not_installed); + dialogBuilder.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Do nothing. The `AlertDialog` will close automatically. + } + }); + + // Convert `dialogBuilder` to `alertDialog` and display it on the screen. + AlertDialog alertDialog = dialogBuilder.create(); + alertDialog.show(); + } + } else { // Otherwise set the default grey `appBar` background. + MainWebViewActivity.appBar.setBackgroundDrawable(ContextCompat.getDrawable(privacyBrowserContext, R.color.grey_100)); + } + } +} diff --git a/app/src/main/java/com/stoutner/privacybrowser/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/SettingsFragment.java index 7446ce61..60e250b2 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/SettingsFragment.java @@ -20,6 +20,7 @@ package com.stoutner.privacybrowser; import android.annotation.SuppressLint; +import android.app.Activity; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; @@ -241,6 +242,17 @@ public class SettingsFragment extends PreferenceFragment { MainWebViewActivity.mainWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0")); break; + case "proxy_through_orbot": + // Get a handle for `settingsActivity`. + Activity settingsActivity = getActivity(); + + // Update the proxy. The default is `false` + if (sharedPreferences.getBoolean("proxy_through_orbot", false)) { // Orbot proxies on localhost port 8118. + OrbotProxyHelper.setProxy(MainWebViewActivity.privacyBrowserContext, settingsActivity, "localhost", "8118"); + } else { // Disable the proxy by setting the host to `null` and the port to `0`. + OrbotProxyHelper.setProxy(MainWebViewActivity.privacyBrowserContext, settingsActivity, "", "0"); + } + case "javascript_disabled_search": String newJavaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q="); if (newJavaScriptDisabledSearchString.equals("Custom URL")) { diff --git a/app/src/main/java/com/stoutner/privacybrowser/SslCertificateError.java b/app/src/main/java/com/stoutner/privacybrowser/SslCertificateError.java index e42b3926..3ee666f8 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/SslCertificateError.java +++ b/app/src/main/java/com/stoutner/privacybrowser/SslCertificateError.java @@ -212,7 +212,7 @@ public class SslCertificateError extends DialogFragment{ SpannableStringBuilder endDateStringBuilder = new SpannableStringBuilder((endDateLabel + endDate)); // Create a blue `ForegroundColorSpan`. We have to use the deprecated `getColor` until API >= 23. - ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue)); + ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700)); // Setup the spans to display the certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction. urlStringBuilder.setSpan(blueColorSpan, urlLabel.length(), urlStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); diff --git a/app/src/main/java/com/stoutner/privacybrowser/ViewSslCertificate.java b/app/src/main/java/com/stoutner/privacybrowser/ViewSslCertificate.java index 2a81362a..f68f503c 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/ViewSslCertificate.java +++ b/app/src/main/java/com/stoutner/privacybrowser/ViewSslCertificate.java @@ -26,15 +26,12 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.http.SslCertificate; import android.os.Bundle; -import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.widget.TextView; -import org.w3c.dom.Text; - import java.util.Date; public class ViewSslCertificate extends DialogFragment { @@ -123,7 +120,7 @@ public class ViewSslCertificate extends DialogFragment { SpannableStringBuilder endDateStringBuilder = new SpannableStringBuilder(endDateLabel + endDate.toString()); // Create a blue `ForegroundColorSpan`. We have to use the deprecated `getColor` until API >= 23. - ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue)); + ForegroundColorSpan blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700)); // Setup the spans to display the certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction. issuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), issuedToCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); diff --git a/app/src/main/res/drawable/bookmarks_list_selector.xml b/app/src/main/res/drawable/bookmarks_list_selector.xml index 834b9ec6..30e99383 100644 --- a/app/src/main/res/drawable/bookmarks_list_selector.xml +++ b/app/src/main/res/drawable/bookmarks_list_selector.xml @@ -22,5 +22,5 @@ + android:drawable="@color/blue_100" /> \ No newline at end of file diff --git a/app/src/main/res/layout/about_coordinatorlayout.xml b/app/src/main/res/layout/about_coordinatorlayout.xml index a0d221e6..6821c446 100644 --- a/app/src/main/res/layout/about_coordinatorlayout.xml +++ b/app/src/main/res/layout/about_coordinatorlayout.xml @@ -35,12 +35,12 @@ android:layout_width="match_parent" android:orientation="vertical" > - + @@ -48,7 +48,7 @@ android:id="@+id/about_toolbar" android:layout_height="wrap_content" android:layout_width="match_parent" - android:background="@color/blue" + android:background="@color/blue_700" android:theme="@style/DarkAppBar" app:popupTheme="@style/LightPopupOverlay" /> @@ -57,8 +57,8 @@ 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:tabBackground="@color/blue_700" + android.support.design:tabTextColor="@color/blue_100" android.support.design:tabSelectedTextColor="@color/white" android.support.design:tabIndicatorColor="@color/white" android.support.design:tabMode="scrollable" /> diff --git a/app/src/main/res/layout/about_tab_version.xml b/app/src/main/res/layout/about_tab_version.xml index 0fd52013..7196450c 100644 --- a/app/src/main/res/layout/about_tab_version.xml +++ b/app/src/main/res/layout/about_tab_version.xml @@ -60,7 +60,7 @@ android:id="@+id/about_version_number" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textColor="@color/blue" + android:textColor="@color/blue_700" android:layout_below="@id/about_version_privacy_browser_textview" android:layout_toEndOf="@id/about_version_icon" /> @@ -82,7 +82,7 @@ android:text="@string/hardware" android:textStyle="bold" android:textSize="18sp" - android:textColor="@color/dark_blue" /> + android:textColor="@color/blue_900" /> diff --git a/app/src/main/res/layout/bookmarks_database_view_coordinatorlayout.xml b/app/src/main/res/layout/bookmarks_database_view_coordinatorlayout.xml index 2db02819..b1aa243d 100644 --- a/app/src/main/res/layout/bookmarks_database_view_coordinatorlayout.xml +++ b/app/src/main/res/layout/bookmarks_database_view_coordinatorlayout.xml @@ -45,7 +45,7 @@ android:id="@+id/bookmarks_database_view_toolbar" android:layout_height="wrap_content" android:layout_width="match_parent" - android:background="@color/blue" + android:background="@color/blue_700" android:theme="@style/DarkAppBar" app:popupTheme="@style/LightPopupOverlay" /> diff --git a/app/src/main/res/layout/bookmarks_database_view_item_linearlayout.xml b/app/src/main/res/layout/bookmarks_database_view_item_linearlayout.xml index 393ac28f..8bbaf1bf 100644 --- a/app/src/main/res/layout/bookmarks_database_view_item_linearlayout.xml +++ b/app/src/main/res/layout/bookmarks_database_view_item_linearlayout.xml @@ -41,7 +41,7 @@ android:layout_width="50dp" android:layout_marginEnd="10dp" android:gravity="end" - android:textColor="@color/grey" + android:textColor="@color/grey_500" android:textSize="22sp" /> - + @@ -48,7 +48,7 @@ android:id="@+id/guide_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/blue" + android:background="@color/blue_700" android:theme="@style/DarkAppBar" app:popupTheme="@style/LightPopupOverlay" /> @@ -57,8 +57,8 @@ 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:tabBackground="@color/blue_700" + android.support.design:tabTextColor="@color/blue_100" android.support.design:tabSelectedTextColor="@color/white" android.support.design:tabIndicatorColor="@color/white" android.support.design:tabMode="scrollable" /> diff --git a/app/src/main/res/layout/main_coordinatorlayout.xml b/app/src/main/res/layout/main_coordinatorlayout.xml index 0dba1f95..b0d9c1f2 100644 --- a/app/src/main/res/layout/main_coordinatorlayout.xml +++ b/app/src/main/res/layout/main_coordinatorlayout.xml @@ -56,7 +56,7 @@ android:id="@+id/appBar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/colorPrimary" + android:background="@color/grey_100" app:popupTheme="@style/LightPopupOverlay" /> @@ -81,5 +81,5 @@ android:layout_gravity="start" app:headerLayout="@layout/navigation_header" app:menu="@menu/webview_navigation_menu" - app:itemIconTint="@color/blue_grey" /> + app:itemIconTint="@color/blue_800" /> \ No newline at end of file diff --git a/app/src/main/res/layout/navigation_header.xml b/app/src/main/res/layout/navigation_header.xml index 7ed9685e..0f6c443a 100644 --- a/app/src/main/res/layout/navigation_header.xml +++ b/app/src/main/res/layout/navigation_header.xml @@ -32,6 +32,6 @@ android:paddingStart="15dp" android:textStyle="bold" android:textSize="20sp" - android:background="@color/blue" + android:background="@color/blue_700" android:textColor="@color/white" /> diff --git a/app/src/main/res/layout/ssl_certificate_error.xml b/app/src/main/res/layout/ssl_certificate_error.xml index c9626512..08e8ca79 100644 --- a/app/src/main/res/layout/ssl_certificate_error.xml +++ b/app/src/main/res/layout/ssl_certificate_error.xml @@ -33,7 +33,7 @@ android:id="@+id/primary_error" android:layout_height="wrap_content" android:layout_width="wrap_content" - android:textColor="@color/red" + android:textColor="@color/red_a700" android:textStyle="bold"/> @@ -44,7 +44,7 @@ android:text="@string/url" android:textAllCaps="true" android:textStyle="bold" - android:textColor="@color/dark_blue" /> + android:textColor="@color/blue_900" /> + android:textColor="@color/blue_900" /> + android:textColor="@color/blue_900"/> + android:textColor="@color/blue_900"/> \ No newline at end of file diff --git a/app/src/main/res/layout/view_ssl_certificate.xml b/app/src/main/res/layout/view_ssl_certificate.xml index cdb5cebe..ccef2701 100644 --- a/app/src/main/res/layout/view_ssl_certificate.xml +++ b/app/src/main/res/layout/view_ssl_certificate.xml @@ -36,7 +36,7 @@ android:text="@string/issued_to" android:textAllCaps="true" android:textStyle="bold" - android:textColor="@color/dark_blue" /> + android:textColor="@color/blue_900" /> + android:textColor="@color/blue_900"/> + android:textColor="@color/blue_900"/> = 22 we can remove the hardcoded colors and reference these entries. --> #FF000000 - #FF1976D2 - #FF0D47A1 - #FF607D8B - #FF9E9E9E - #FF64DD17 - #FFBBDEFB - #FF42A5F5 - #FFF57F17 - #FFD50000 + + #FFE3F2FD + #FFBBDEFB + #FF90CAF9 + #FF64B5F6 + #FF42A5F5 + #FF2196F3 + #FF1E88E5 + #FF1976D2 + #FF1565C0 + #FF0D47A1 + #FF2962FF + + #FF607D8B + + #FFF5F5F5 + #FF9E9E9E + + #FF64DD17 + + #FFD50000 + #FFFFFFFF - #FFFFD600 + + #FFF57F17 + #FFFFD600 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 628548f3..9b6a969d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -166,119 +166,124 @@ Privacy - Enable JavaScript by default - JavaScript allows websites to run programs (scripts) on your device. - Enable first-party cookies by default - Devices with versions of Android older than Lollipop (version 5.0) will also enable third-party cookies with this setting. - Enable third-party cookies by default - This setting requires Android Lollipop (version 5.0) or higher. It has no effect if first-party cookies are disabled. - Enable DOM storage by default - JavaScript must be enabled for DOM storage to function. - Enable saving of form data by default - Saved form data can auto-populate fields on websites. - User agent - - WebView Default - Privacy Browser 1.0 - Firefox 48 on Android 6.0.1 - Chrome 52 on Android 6.0.1 - Safari on iOS 10 - Firefox 45 on Linux - Chromium 52 on Linux - Konqueror 4.14.23 on Linux - Firefox 48 on Windows 10 - Chrome 52 on Windows 10 - Internet Explorer 11 on Windows 10 - Edge 14 on Windows 10 - Safari 9.1.2 on OS X 10.11.6 - Custom - - - Default user agent - PrivacyBrowser/1.0 - Mozilla/5.0 (Android 6.0.1; Mobile; rv:48.0) Gecko/48.0 Firefox/48.0 - Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC20F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.98 Mobile Safari/537.36 - Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/14A5345a Safari/602.1 - Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) konqueror/4.14.23 Safari/537.21 - Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 - Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 - Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393 - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7 - Custom user agent - - Custom user agent - Do not track - Send the Do Not Track header which politely suggests that web servers not track this browser. + Enable JavaScript by default + JavaScript allows websites to run programs (scripts) on your device. + Enable first-party cookies by default + Devices with versions of Android older than Lollipop (version 5.0) will also enable third-party cookies with this setting. + Enable third-party cookies by default + This setting requires Android Lollipop (version 5.0) or higher. It has no effect if first-party cookies are disabled. + Enable DOM storage by default + JavaScript must be enabled for DOM storage to function. + Enable saving of form data by default + Saved form data can auto-populate fields on websites. + User agent + + WebView Default + Privacy Browser 1.0 + Firefox 48 on Android 6.0.1 + Chrome 52 on Android 6.0.1 + Safari on iOS 10 + Firefox 45 on Linux + Chromium 52 on Linux + Konqueror 4.14.23 on Linux + Firefox 48 on Windows 10 + Chrome 52 on Windows 10 + Internet Explorer 11 on Windows 10 + Edge 14 on Windows 10 + Safari 9.1.2 on OS X 10.11.6 + Custom + + + Default user agent + PrivacyBrowser/1.0 + Mozilla/5.0 (Android 6.0.1; Mobile; rv:48.0) Gecko/48.0 Firefox/48.0 + Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC20F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.98 Mobile Safari/537.36 + Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/14A5345a Safari/602.1 + Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 + Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 + Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) konqueror/4.14.23 Safari/537.21 + Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 + Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 + Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko + Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393 + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7 + Custom user agent + + Custom user agent + Do not track + Send the Do Not Track header which politely suggests that web servers not track this browser. + Proxy through Orbot + Proxy all web traffic through Orbot on localhost:8118. Search - JavaScript-disabled search - - DuckDuckGo - Google - Bing - Yahoo - StartPage - Qwant - Custom - - - https://duckduckgo.com/html/?q= - https://www.google.com/search?q= - https://www.bing.com/search?q= - https://search.yahoo.com/mobile/s?nojs=1&p= - https://www.startpage.com/do/search?q= - https://lite.qwant.com/?q= - Custom URL - - JavaScript-disabled search custom URL - JavaScript-enabled search - - DuckDuckGo - Google - Bing - Yahoo - StartPage - Qwant - Custom - - - https://duckduckgo.com/?q= - https://www.google.com/search?q= - https://www.bing.com/search?q= - https://search.yahoo.com/mobile/s?p= - https://www.startpage.com/do/search?q= - https://www.qwant.com/?q= - Custom URL - - JavaScript-enabled search custom URL - Custom URL + JavaScript-disabled search + + DuckDuckGo + Google + Bing + Yahoo + StartPage + Qwant + Custom + + + https://duckduckgo.com/html/?q= + https://www.google.com/search?q= + https://www.bing.com/search?q= + https://search.yahoo.com/mobile/s?nojs=1&p= + https://www.startpage.com/do/search?q= + https://lite.qwant.com/?q= + Custom URL + + JavaScript-disabled search custom URL + JavaScript-enabled search + + DuckDuckGo + Google + Bing + Yahoo + StartPage + Qwant + Custom + + + https://duckduckgo.com/?q= + https://www.google.com/search?q= + https://www.bing.com/search?q= + https://search.yahoo.com/mobile/s?p= + https://www.startpage.com/do/search?q= + https://www.qwant.com/?q= + Custom URL + + JavaScript-enabled search custom URL + Custom URL General - Homepage - Default font size - - 50% - 75% - 100% - 125% - 150% - 175% - 200% - - - 50 - 75 - 100 - 125 - 150 - 175 - 200 - - Swipe to refresh - Some websites don\'t work well if swipe to refresh is enabled. - Display additional app bar icons - Display icons for toggling cookies, DOM storage, and form data in the app bar if there is room. + Homepage + Default font size + + 50% + 75% + 100% + 125% + 150% + 175% + 200% + + + 50 + 75 + 100 + 125 + 150 + 175 + 200 + + Swipe to refresh + Some websites don\'t work well if swipe to refresh is enabled. + Display additional app bar icons + Display icons for toggling cookies, DOM storage, and form data in the app bar if there is room. + + + Orbot proxy will not work unless Orbot is installed. About Privacy Browser diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 25ca3a0d..74364f58 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -23,23 +23,23 @@ When it is specified the root layout should include android:fitsSystemWindows="true". --> @@ -51,6 +51,6 @@ \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 4441ca6a..35d9ed1b 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -74,6 +74,12 @@ android:summary="@string/do_not_track_summary" android:defaultValue="true" /> + +