How to implement Global Privacy Control (GPC) on Android

Hands-on tutorial for GPC with Android WebView

Pluma Browser
4 min readOct 30, 2020

Global Privacy Control (GPC) is a new initiative aiming to give users control over their privacy with a single setting in their browser. The goal is for laws around the world to enforce compliance when a user signals they don’t wish to be tracked. Such laws may already exist in certain jurisdictions, like the European Union’s Global Data Protection Regulation (GDPR) and California Consumer Protection Act (CCPA).

Photo by Tim Mossholder on Unsplash

Technical details

How does a user turn GPC on? Their browser or browser extension must implement the GPC specification, which indicates how to surface the GPC signal to two components in a website: 1) the web server (remote code), and 2) the client-side JavaScript code (local code).

The GPC organization provides a website to verify that GPC is indeed being signaled from your browser: https://global-privacy-control.glitch.me/ We’ll use it throughout this blog post to verify our work.

Note that all sample code in the form of Github gists is not necessarily following all the best practices and is simplified for easier understanding.

1) Web server

Web servers receive HTTP requests, which include a header. If the browser’s GPC setting is on, the header of those requests must include:

Sec-GPC: 1

Including custom HTTP headers may seem trivial with an Android WebView:

From the Android Developer website for WebView#loadUrl(String, Map<String, String>).

Whenever we try to load a URL, we’ll use:

Easy peasy, right? This works fine if the user only visits one website and doesn’t click on any links. We can verify this by calling

We’ll see a thumbs-up in the server-side detection section:

However, when first navigating to https://globalprivacycontrol.org/ and then clicking on “Test against the reference server”, we’ll see a thumbs-down for server-side detection. WebView doesn’t offer an API to provide additional headers when the navigation is not initiated programmatically, and hence the GPC header is not being set! This is a critical thing to get right; we’re talking about privacy after all.

We can fix this by using a workaround:

There is a note in the documentation for WebViewClient#shouldOverrideUrlLoading advising not to do this:

Note: Do not call WebView#loadUrl(String) with the request's URL and then return true. This unnecessarily cancels the current load and starts a new load with the same URL. The correct way to continue loading a given URL is to simply return false, without calling WebView#loadUrl(String).

Two points to keep in mind:

  1. I haven’t found a different alternative to this workaround. So if WebView or WebViewClient offered an API to achieve this without canceling the load, I’d love it!
  2. (tongue-in-cheek) The documentation warns us not to call WebView#loadUrl(String), but we’re calling WebView#loadUrl(String, Map<String, String>) instead, so it’s fine?

Note that some well-known browsers, such as DuckDuckGo, missed this and exhibit this undesired behavior. Hopefully it will be fixed soon.

Client-side JavaScript code

Most websites include JavaScript code that is run on your browser; this code can communicate with servers as well, so it’s important to expose the GPC signal there. The spec defines that the value of Navigator.globalPrivacyControl should be true when GPC is enabled.

JavaScript Property to Detect Preference, from the GPC specification.

Just like before, we search for methods in WebView with “JavaScript” in the name and strike gold:

From the Android Developer website for WebView#evaluateJavascript.

So we’ll evaluate some JavaScript code that will set Navigator.globalPrivacyControl = true. This will do the job:

When loading https://global-privacy-control.glitch.me/ , we can see the long-awaited thumbs-up in the client-side detection section:

Pluma Browser and Global Privacy Control

Pluma is an Android browser that uses the methods described in this post to implement GPC. In order to enable GPC on Pluma, you must turn on Enhanced privacy in the Settings screen.

Pluma is focused on simplicity, so you won’t find a ton of features or clutter; just a clean interface. Consider downloading it from the Play Store and provide feedback by email or Twitter (@PlumaBrowser).

--

--