hakurei.app/static/usage.html
2021-11-18 19:08:54 -05:00

949 lines
67 KiB
HTML

<!DOCTYPE html>
<html lang="en" prefix="og: https://ogp.me/ns#">
<head>
<meta charset="utf-8"/>
<title>Usage guide | GrapheneOS</title>
<meta name="description" content="Usage instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
<meta name="theme-color" content="#212121"/>
<meta name="color-scheme" content="dark light"/>
<meta name="msapplication-TileColor" content="#ffffff"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="twitter:site" content="@GrapheneOS"/>
<meta name="twitter:creator" content="@GrapheneOS"/>
<meta property="og:title" content="GrapheneOS usage guide"/>
<meta property="og:description" content="Usage instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
<meta property="og:image:width" content="512"/>
<meta property="og:image:height" content="512"/>
<meta property="og:image:alt" content="GrapheneOS logo"/>
<meta property="og:site_name" content="GrapheneOS"/>
<meta property="og:url" content="https://grapheneos.org/usage"/>
<link rel="canonical" href="https://grapheneos.org/usage"/>
<link rel="icon" href="/favicon.ico"/>
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
<link rel="mask-icon" href="{{path|/mask-icon.svg}}" color="#1a1a1a"/>
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
{{css|/main.css}}
<link rel="manifest" href="/manifest.webmanifest"/>
<link rel="license" href="/LICENSE.txt"/>
{{js|/js/redirect.js}}
</head>
<body>
<header>
<nav id="site-menu">
<ul>
<li><a href="/"><img src="{{path|/mask-icon.svg}}" alt=""/>GrapheneOS</a></li>
<li><a href="/features">Features</a></li>
<li><a href="/install/">Install</a></li>
<li><a href="/build">Build</a></li>
<li aria-current="page"><a href="/usage">Usage</a></li>
<li><a href="/faq">FAQ</a></li>
<li><a href="/releases">Releases</a></li>
<li><a href="/source">Source</a></li>
<li><a href="/history/">History</a></li>
<li><a href="/articles/">Articles</a></li>
<li><a href="/donate">Donate</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<main id="usage">
<h1><a href="#usage">Usage guide</a></h1>
<p>This is a guide covering some aspects of using GrapheneOS. See the
<a href="/features">features page</a> for a list of GrapheneOS features.</p>
<nav id="table-of-contents">
<h2><a href="#table-of-contents">Table of contents</a></h2>
<ul>
<li>
<a href="#system-navigation">System navigation</a>
<ul>
<li><a href="#gesture-navigation">Gesture navigation</a></li>
<li><a href="#2-button-navigation">2-button navigation</a></li>
<li><a href="#3-button-navigation">3-button navigation</a></li>
</ul>
</li>
<li><a href="#accessibility">Accessibility</a></li>
<li><a href="#auditor">Auditor</a></li>
<li>
<a href="#updates">Updates</a>
<ul>
<li><a href="#updates-settings">Settings</a></li>
<li><a href="#updates-security">Security</a></li>
<li><a href="#updates-disabling">Disabling</a></li>
<li><a href="#updates-sideloading">Sideloading</a></li>
</ul>
</li>
<li><a href="#web-browsing">Web browsing</a></li>
<li>
<a href="#camera">Camera</a>
<ul>
<li><a href="#grapheneos-camera-app">GrapheneOS Camera app</a></li>
<li><a href="#google-camera">Google Camera</a></li>
</ul>
</li>
<li><a href="#exec-spawning">Exec spawning</a></li>
<li><a href="#bugs-uncovered-by-security-features">Bugs uncovered by security features</a></li>
<li>
<a href="#wifi-privacy">Wi-Fi privacy</a>
<ul>
<li><a href="#wifi-privacy-scanning">Scanning</a></li>
<li><a href="#wifi-privacy-associated">Associated with an Access Point (AP)</a></li>
</ul>
</li>
<li><a href="#lte-only-mode">LTE-only mode</a></li>
<li>
<a href="#sandboxed-play-services">Sandboxed Play services</a>
<ul>
<li><a href="#sandboxed-play-services-installation">Installation</a></li>
<li><a href="#sandboxed-play-services-limitations">Limitations</a></li>
</ul>
</li>
<li><a href="#banking-apps">Banking apps</a></li>
</ul>
</nav>
<section id="system-navigation">
<h2><a href="#system-navigation">System navigation</a></h2>
<p>By default, GrapheneOS uses gesture-based navigation. We recommend reading our
guide on gesture navigation and giving it a chance even if you think you won't
like it. Our experience is that when armed with the appropriate knowledge, the
vast majority of users prefer the newer gesture navigation approach.</p>
<p>The system navigation mode can be configured in Settings → System → Gestures →
System navigation. The same menu is also available in Settings → Accessibility →
System navigation.</p>
<section id="gesture-navigation">
<h3><a href="#gesture-navigation">Gesture navigation</a></h3>
<p>The bottom of the screen is a reserved touch zone for system navigation. A
line is displayed in the center to show that the navigation bar is present
across the entire bottom of the screen. In most apps, this area will display
padding. Modern apps are able to tell the OS that they can handle not having
the padding to display app content there while still not being able to receive
touches from it. Open up the Settings app for an example.</p>
<p>Swiping up from the navigation bar while removing your finger from the
screen is the <strong>Home</strong> gesture.</p>
<p>Swiping up from the navigation bar while holding your finger on the screen
before releasing is the <strong>Recent Apps</strong> gesture. The most
recently opened activity is always on the furthest right. Each step left goes
one step back through the history of recently opened apps. Opening an app with
the recent apps activity will place it on the furthest right in the recent
apps order just like a new app being opened.</p>
<p>The recent apps activity has a screenshot button as an alternative to
holding power and volume down while using an app.</p>
<p>Rather than opening the recent apps activity, you can swipe left on the
navigation bar for the <strong>Previous</strong> app and swipe right for the
<strong>Next</strong> app. This will not change the recent apps order. This is
usually the best way to navigate through recent apps.</p>
<p>Swiping from either the left or the right of the screen within the app (not
the navigation bar) is the <strong>Back</strong> gesture. Apps are supposed to
avoid implementing conflicting gestures, but have the option to override this
gesture if they truly need to get rid of it. However, many apps without active
development of their UI design still haven't addressed this despite gestures
being the default for 2 years on Google Android. You can avoid triggering the
back gesture in one of 2 easy ways: avoid swiping from right near the edge or
hold your finger on the side of the screen for a moment before swiping. The
more advanced option is using a diagonal swipe pointing sharply to the bottom
of the screen since this will bypass the back gesture but will still trigger
most app gestures. The advanced option is the most convenient approach once
you get used to doing it.</p>
<p>The launcher uses a swipe up gesture starting anywhere on the screen to
open the app drawer from the home screen. You need to start that gesture above
the system navigation bar since any gesture starting on the navigation bar is
handled by the OS as a system navigation gesture.</p>
</section>
<section id="2-button-navigation">
<h3><a href="#2-button-navigation">2-button navigation</a></h3>
<p>2-button navigation is a legacy mode not supported anymore by Google
Android on the Pixel 4 and later. It will likely be removed in a future
release of GrapheneOS. You should use <a href="#3-button-navigation">3-button
navigation</a> if you want the traditional button-based navigation.</p>
<p>A large row across the bottom of the screen is reserved for navigation
buttons. The <strong>Back</strong> button is on the left and the
<strong>Home</strong> button is in the center.</p>
<p>Swiping up from the navigation bar while removing your finger from the
screen is the <strong>Recent apps</strong> gesture. The most recently opened
activity is always on the furthest right. Each step left goes one step back
through the history of recently opened apps. Opening an app with the recent
apps activity will place it on the furthest right in the recent apps
order just like a new app being opened.</p>
<p>2-button navigation provides the recent apps activity with the launcher. It
shows the recent apps above the bottom row of the home screen and the search
integration not used in GrapheneOS. The usual launcher features work including
swiping up anywhere on the screen to open the app drawer. Due to the launcher
integration, the screenshot button available in the other modes isn't present.
Instead, a screenshot button is added to the global action menu accessed by
holding the power button.</p>
</section>
<section id="3-button-navigation">
<h3><a href="#3-button-navigation">3-button navigation</a></h3>
<p>3-button navigation is Android's oldest touchscreen-based navigation
system. It will remain supported for the foreseeable future to provide
accessibility for users unable to easily use the gestures. It's older than
2-button navigation but isn't considered a legacy feature.</p>
<p>A large row across the bottom of the screen is reserved for navigation
buttons. The <strong>Back</strong> button is on the left, the
<strong>Home</strong> button is in the center and the <strong>Recent
Apps</strong> button is on the right.</p>
<p>In the recent apps activity, the most recently opened activity is always on
the furthest right. Each step left goes one step back through the history of
recently opened apps. Opening an app with the recent apps activity will place
it on the furthest right in the recent apps order just like a new app being
opened.</p>
<p>The recent apps activity has a screenshot button as an alternative to
holding power and volume down while using an app.</p>
</section>
</section>
<section id="accessibility">
<h2><a href="#accessibility">Accessibility</a></h2>
<p>GrapheneOS includes all of the accessibility features from the Android Open
Source Project and strives to fill in the gaps from not including Google apps and
services. We include our own fork of the open source TalkBack accessibility
service along with a Monochromacy option for the standard color correction
menu.</p>
<p>GrapheneOS does not yet include a text-to-speech (TTS) service in the base OS
due to limitations of the available options. Including one is planned in the
future when a suitable option is available. RHVoice and eSpeak NG are both open
source and are the most common choices by GrapheneOS users. Both of these mostly
work fine but have licensing issues and don't support Direct Boot so they cannot
be used before the initial unlock of the device. Installing and setting up either
one of these or another TTS app will get TalkBack working. TalkBack itself
supports Direct Boot and works before the first unlock but it needs to have a TTS
app supporting it in order to do more than playing the activation sound before the
first unlock. After installing a TTS service, you need to select it in the OS
configuration to accept activating it. The OS will display one of them as already
selected, but it won't simply work from being installed as that wouldn't be safe.
This is the same as the stock OS but it comes with one set up already.</p>
<p>GrapheneOS disables showing the characters as passwords are typed by default.
You can enable this in Settings ➔ Privacy.</p>
<p>Third party accessibility services can be installed and activated. This
includes the ones made by Google. Most of these will work but some may have a hard
dependency on functionality from Google Play services for some of their
functionality or to run at all. Accessibility services are very powerful and we
strongly recommend against using third party implementations if you can get by
well without them. We plan to add safeguards in this area while still keeping them
working without problematic barriers.</p>
</section>
<section id="auditor">
<h2><a href="#auditor">Auditor</a></h2>
<p>See the <a href="https://attestation.app/tutorial">tutorial page on the site for the attestation sub-project</a>.</p>
</section>
<section id="updates">
<h2><a href="#updates">Updates</a></h2>
<p>The update system implements automatic background updates. It checks for updates
approximately once every four hours when there's network connectivity and then
downloads and installs updates in the background. It will pick up where it left off if
downloads are interrupted, so you don't need to worry about interrupting it.
Similarly, interrupting the installation isn't a risk because updates are installed to
a secondary installation of GrapheneOS which only becomes the active installation
after the update is complete. Once the update is complete, you'll be informed with a
notification and simply need to reboot with the button in the notification or via a
normal reboot. If the new version fails to boot, the OS will be rolled back to the
past version and the updater will attempt to download and install the update
again.</p>
<p>The updater will use incremental (delta) updates to download only changes rather
than the whole OS when one is available to go directly from the installed version to
the latest version. As long as you have working network connectivity on a regular
basis and reboot when asked, you'll almost always be on one of the past couple
versions of the OS which will minimize bandwidth usage since incrementals will always
be available.</p>
<p>The updater works while the device is locked / idle, including before the first
unlock since it's explicitly designed to be able to run before decryption of user
data.</p>
<p>Release changelogs are available <a href="/releases#changelog">in a section on the releases page</a>.</p>
<section id="updates-settings">
<h3><a href="#updates-settings">Settings</a></h3>
<p>The settings are available in the Settings app in System ➔ Advanced ➔ Update
settings.</p>
<p>The "Check for updates" option will manually trigger an update check as soon as
possible. It will still wait for the configuration conditions listed below to be
satisfied, such as being connected to the internet via one of the permitted network
types.</p>
<p>The "Release channel" setting can be changed from the default Stable channel to the
Beta channel if you want to help with testing. The Beta channel will usually simply
follow the Stable channel, but the Beta channel may be used to experiment with new
features.</p>
<p>The "Permitted networks" setting controls which networks will be used to perform
updates. It defaults to using any network connection. It can be set to "Non-roaming"
to disable it when the cellular service is marked as roaming or "Unmetered" to disable
it on cellular networks and also Wi-Fi networks marked as metered.</p>
<p>The "Require battery above warning level" setting controls whether updates will
only be performed when the battery is above the level where the warning message is
shown. The standard value is at 15% capacity.</p>
<p>Enabling the opt-in "Automatic reboot" setting allows the updater to reboot the
device after an update once it has been idle for a long time. When this setting is
enabled, a device can take care of any number of updates completely automatically even
if it's left completely idle.</p>
</section>
<section id="updates-security">
<h3><a href="#updates-security">Security</a></h3>
<p>The update server isn't a trusted party since updates are signed and verified along
with downgrade attacks being prevented. The update protocol doesn't send identifiable
information to the update server and works well over a VPN / Tor. GrapheneOS isn't
able to comply with a government order to build, sign and ship a malicious update to a
specific user's device based on information like the IMEI, serial number, etc. The
update server only ends up knowing the IP address used to connect to it and the
version being upgraded from based on the requested incremental.</p>
<p>Android updates can support serialno constraints to make them validate only on a
certain device but GrapheneOS rejects any update with a serialno constraint for both
over-the-air updates (Updater app) and sideloaded updates (recovery).</p>
</section>
<section id="updates-disabling">
<h3><a href="#updates-disabling">Disabling</a></h3>
<p>It's highly recommended to leave automatic updates enabled and to configure the
permitted networks if the bandwidth usage is a problem on your mobile data connection.
However, it's possible to turn off the update client by going to Settings ➔ Apps,
enabling Show system via the menu, selecting System Updater and disabling the
app. If you do this, you'll need to remember to enable it again to start receiving
updates.</p>
</section>
<section id="updates-sideloading">
<h3><a href="#updates-sideloading">Sideloading</a></h3>
<p>Updates can be downloaded via
<a href="https://grapheneos.org/releases">the releases page</a> and installed via recovery
with adb sideloading. The zip files are signed and verified by recovery, just as they
are by the update client within the OS. This includes providing downgrade protection,
which prevents attempting to downgrade the version. If recovery didn't enforce these
things, they would still be enforced via verified boot including downgrade protection
and the attempted update would just fail to boot and be rolled back.</p>
<p>To install one by sideloading, first, boot into recovery. You may do this either by
using <code>adb reboot recovery</code> from the operating system, or by selecting the
"Recovery" option in the bootloader interface.</p>
<p>You should see the green Android lying on its back being repaired, with the text "No
command" meaning that no command has been passed to recovery.</p>
<p>Next, access the recovery menu by holding down the power button and pressing the volume
up button a single time. This key combination toggles between the GUI and text-based mode
with the menu and log output.</p>
<p>Finally, select the "Apply update from ADB" option in the recovery menu and
sideload the update with adb. For example:</p>
<pre>adb sideload blueline-ota_update-2019.07.01.21.zip</pre>
<p><strong>You do not need to have adb enabled within the OS or the host's ADB key
whitelisted within the OS to sideload an update to recovery. Recovery mode does not
trust the attached computer and this can be considered a production feature. Trusting
a computer with ADB access within the OS is much different and exposes the device to a
huge amount of attack surface and control by the trusted computer.</strong></p>
</section>
</section>
<section id="usb-peripherals">
<h2><a href="#usb-peripherals">USB peripherals</a></h2>
<p>GrapheneOS defaults to ignoring connected USB peripherals when the device is
already booted and the screen is locked. A USB device already connected at boot
will still work. The purpose is reducing attack surface for a locked device with
active login sessions to user profiles to protect data that's not at rest. This
can be controlled in Settings ➔ Security ➔ USB accessories. The options are:</p>
<ul>
<li>Disallow new USB peripherals</li>
<li>Allow new USB peripherals when unlocked (default)</li>
<li>Allow new USB peripherals (like stock Android)</li>
</ul>
<p>This option has no impact on the device acting as a USB peripheral itself when
connected to a computer. Android defaults to charge only mode and requires opt-in
to the device being used for file transfer, USB tethering, MIDI or PTP.</p>
</section>
<section id="web-browsing">
<h2><a href="#web-browsing">Web browsing</a></h2>
<p>GrapheneOS includes a Vanadium subproject providing privacy and security enhanced
releases of Chromium. Vanadium is both the user-facing browser included in the OS and
the provider of the WebView used by other apps to render web content. The WebView is
the browser engine used by the vast majority of web browsers and nearly all other apps
embedding web content or using web technologies for other uses.</p>
<p>Using Vanadium is highly recommended. Bromite is a solid alternative and is the
only other browser we recommend. Bromite provides integrated ad-blocking and more
advanced anti-fingerprinting. For now, Vanadium is more focused on security hardening
and Bromite is more focused on anti-fingerprinting. The projects are collaborating
together and will likely converge to providing more of the same features. Vanadium
will be providing content filtering and anti-fingerprinting, but it needs to be done
in a way that meets the standards of the project, which takes time.</p>
<p>Vanadium is designed for use on GrapheneOS and does not duplicate the OS privacy
and security features such as the hardened malloc implementation. This leads to some
of the differences from Bromite, such as relying on OS support for encrypted DNS
rather than enabling Chromium's DNS-over-HTTPS support.</p>
<p>Chromium-based browsers like Vanadium and Bromite provide the strongest sandbox
implementation, leagues ahead of the alternatives. It is much harder to escape from
the sandbox and it provides much more than acting as a barrier to compromising the
rest of the OS. Site isolation enforces security boundaries around each site using the
sandbox by placing each site into an isolated sandbox. It required a huge overhaul of
the browser since it has to enforce these rules on all the IPC APIs. Site isolation is
important even without a compromise, due to side channels. Browsers without site
isolation are very vulnerable to attacks like Spectre. On mobile, due to the lack of
memory available to apps, there are different modes for site isolation. Vanadium turns
on strict site isolation, matching Chromium on the desktop. Bromite enables strict
site isolation on high memory devices, including all the devices that are officially
supported by GrapheneOS.</p>
<p>Chromium has decent exploit mitigations, unlike the available alternatives. This is
improved upon in Vanadium by enabling further mitigations, including those developed
upstream but not yet fully enabled due to code size, memory usage or performance. For
example, it enables type-based CFI like Chromium on the desktop, uses a stronger SSP
configuration, zero initializes variables by default, etc. Some of the mitigations are
inherited from the OS itself, which also applies to other browsers, at least if they
don't do things to break them.</p>
<p>We recommend against trying to achieve browser privacy and security through piling
on browser extensions and modifications. Most privacy features for browsers are
privacy theater without a clear threat model and these features often reduce privacy
by aiding fingerprinting and adding more state shared between sites. Every change you
make results in you standing out from the crowd and generally provides more ways to
track you. Enumerating badness via content filtering is not a viable approach to
achieving decent privacy, just as AntiVirus isn't a viable way to achieving decent
security. These are losing battles, and are at best a stopgap reducing exposure while
waiting for real privacy and security features.</p>
<p>Vanadium will be following the school of thought where hiding the IP address
through Tor or a trusted VPN shared between many users is the essential baseline, with
the browser partitioning state based on site and mitigating fingerprinting to avoid
that being trivially bypassed. The Tor Browser's approach is the only one with any
real potential, however flawed the current implementation may be. This work is
currently in a very early stage and it is largely being implemented upstream with the
strongest available implementation of state partitioning. Chromium is using Network
Isolation Keys to divide up connection pools, caches and other state based on site and
this will be the foundation for privacy. Chromium itself aims to prevent tracking
through mechanisms other than cookies, greatly narrowing the scope downstream work
needs to cover. Bromite is doing a lot of work in these areas and Vanadium will be
benefiting from that along with this upstream work. The focus is currently on research
since we don't see much benefit in deploying bits and pieces of this before everything
is ready to come together. At the moment, the only browser with any semblance of
privacy is the Tor Browser but there are many ways to bypass the anti-fingerprinting
and state partitioning. The Tor Browser's security is weak which makes the privacy
protection weak. The need to avoid diversity (fingerprinting) creates a monoculture
for the most interesting targets. This needs to change, especially since Tor itself
makes people into much more of a target (both locally and by the exit nodes).</p>
<p>WebView-based browsers use the hardened Vanadium rendering engine, but they can't
offer as much privacy and control due to being limited to the capabilities supported
by the WebView widget. For example, they can't provide a setting for toggling sensors
access because the feature is fairly new and the WebView WebSettings API doesn't yet
include support for it as it does for JavaScript, location, cookies, DOM storage and
other older features. For sensors, the Sensors app permission added by GrapheneOS can
be toggled off for the browser app as a whole instead. The WebView sandbox also
currently runs every instance within the same sandbox and doesn't support site
isolation.</p>
<p>Avoid Gecko-based browsers like Firefox as they're currently much more vulnerable
to exploitation and inherently add a huge amount of attack surface. Gecko doesn't have
a WebView implementation (GeckoView is not a WebView implementation), so it has to be
used alongside the Chromium-based WebView rather than instead of Chromium, which means
having the remote attack surface of two separate browser engines instead of only one.
Firefox / Gecko also bypass or cripple a fair bit of the upstream and GrapheneOS
hardening work for apps. Worst of all, Firefox runs as a single process on mobile and
has no sandbox beyond the OS sandbox. This is despite the fact that Chromium semantic
sandbox layer on Android is implemented via the OS <code>isolatedProcess</code>
feature, which is a very easy to use boolean property for app service processes to
provide strong isolation with only the ability to communicate with the app running
them via the standard service API. Even in the desktop version, Firefox's sandbox is
still substantially weaker (especially on Linux, where it can hardly be considered a
sandbox at all) and lacks support for isolating sites from each other rather than only
containing content as a whole.</p>
</section>
<section id="camera">
<h2><a href="#camera">Camera</a></h2>
<p>GrapheneOS has the same camera capabilities and quality as the stock OS. It
will match the stock OS when comparing the same app on each OS. GrapheneOS uses
our own modern Camera app rather than the standard AOSP Camera app. GrapheneOS
Camera is far better than any of the portable open source camera alternatives and
even most proprietary camera apps including paid apps. On Pixels, Google Camera
can be used as an alternative with more features. The section below has a detailed
guide on using GrapheneOS Camera and the following section explains the remaining
advantages of Google Camera on Pixels.</p>
<section id="grapheneos-camera-app">
<h3><a href="#grapheneos-camera-app">GrapheneOS Camera app</a></h3>
<p>GrapheneOS includes our own modern Camera app based on the bleeding edge
release channel of Android's CameraX library. It provides modes for QR
scanning, image capture and video recording as tabs at the bottom of the
screen. You can either use the tab interface or swipe left and right anywhere
on the screen above it to switch between them. The arrow button at the top of
the screen opens the settings panel and you can close it by pressing anywhere
outside the settings panel. You can also swipe down to open the settings and
swipe up to close it. Outside of the QR scanning mode, there's a row of large
buttons above the tab bar for switching between the cameras (left), capturing
images and starting/stopping video recording (middle) and opening the gallery
(right). The volume keys can also be used as an equivalent to pressing the
capture button. While recording a video, the gallery button becomes an image
capture button for capturing images.</p>
<p>Our Camera app provides the system media intents used by other apps to
capture images / record videos via the OS provided camera implementation.
These intents can only be provided by a system app since Android 11, so the
quality of the system camera is quite important.</p>
<p>The in-app gallery / video player doesn't yet support zooming and depends
on opening an external image/video editor. This will be improved in the
future. We'll eventually be making our own gallery/editor app sharing a lot of
the code with the in-app gallery in the camera.</p>
<p>Using the default 4:3 aspect ratio for image capture is recommended since
16:9 is simply cropped output on all supported devices. A device oriented
towards video recording might actually have a wider image sensor but that's
not the case for Pixels or nearly any other smartphone.</p>
<p>Image capture uses lightweight HDR+ on all supported Pixels and HDRnet for the
preview on 5th generation Pixels. Using the torch or camera flash will result
in HDR+ being disabled which is why automatic flash isn't enabled by default.
The lightweight HDR+ doesn't use as many frames as the more aggressive Google
Camera HDR+. CameraX extensions will eventually provide support for an HDR
mode with more aggressive HDR+ taking/combining more than only around 3 frames
along with a Night mode providing the Night Sight variant of HDR+ inflating
the light of the scene through combining the frames. Other fancy features like
Portrait mode will also depend on CameraX extensions being provided in the
future. There isn't a timeline for this but an initial implementation will
likely be shipped within the next year for Pixels.</p>
<p>Zooming via pinch to zoom or the zoom slider will automatically make use of
the wide angle and telephoto cameras on Pixels. 5th and 6th generation Pixels
(4a (5G), 5, 5a, 6, 6 Pro) have a wide angle camera for zooming out to under
1x to capture a much wider field of view. Images taken with the wide angle
lens won't match the quality of the normal camera, especially with 6th
generation Pixels. Flagship 4th generation Pixels (4, 4 XL) have a telephoto
camera providing 2x optical zoom and the Pixel 6 Pro has one providing 4x
optical zoom.</p>
<p>By default, continuous auto focus, auto exposure and auto white balance are
used across the whole scene. Tapping to focus will switch to auto focus, auto
exposure and auto white balance based on that location. The focus timeout
setting determines the timeout before it switches back the default mode. The
exposure compensation slider on the left allows manually tuning exposure and
will automatically adjust shutter speed, aperture and ISO without disrupting
lightweight HDR+ support. Further configuration / tuning over the algorithms
will be provided in the future. Direct manual control doesn't make much sense
with the modern camera stack and isn't planned.</p>
<p>CameraX only recently gained official support for video recording in
October 2021 and there are still some quirks. The preview can sometimes end up
misaligned but the recorded videos won't be impacted. 16:9 is currently the
only supported video aspect ratio. 1080p (FHD) is the default but 2160p (UHD)
is supported. CameraX UHD support may be buggy on some devices.</p>
<p>The QR scanning mode only scans within the scanning square marked on the
screen. The QR code should be aligned with the edges of the square but can
have any 90 degree orientation. Non-standard inverted QR codes are fully
supported. It's a very quick and high quality QR scanner able to easily scan
very high density QR codes from Pixels. Every 2 seconds, it will refresh auto
focus, auto exposure and auto white balance on the scanning square. It has
full support for zooming in and out. Support for other kinds of barcodes will
be added in the future, but adding them transparently would result in getting
false positives and would substantially harm the QR scanning capability. It
will need to be done in a way offering more control without having an overly
complex user interface.</p>
<p>Camera permission is the only one that's required. Images and videos are
stored via the Media Store API so media/storage permissions aren't required.
The Microphone permission is needed for video recording by default but not
when including audio is disabled. Location permission is only needed if you
explicitly enabling location tagging, which is an experimental feature.</p>
<p>Captured images currently include an EXIF timestamp, the phone model and an
abstraction of the exposure configuration. This will become fully optional in
the future and will likely be opt-in rather than opt-out. EXIF orientation
data is crucial for setting the proper orientation of the image. Videos have
their own similar metadata.</p>
</section>
<section id="google-camera">
<h3><a href="#google-camera">Google Camera</a></h3>
<p>Google Camera can be used with the <a href="#sandboxed-play-services">sandboxed
Play services compatibility layer</a> and can take full advantage of the
available cameras and image processing hardware as it can on the stock OS.</p>
<p>We aim to reduce the benefits of Google Camera compared to GrapheneOS
Camera over time, especially on Pixels. Many features of Google Camera will
end up being available for GrapheneOS Camera in the next year or so via
CameraX extensions including more aggressive HDR+, Night Sight and Portrait.
Video features such as Electronic Image Stabilization (EIS), slow motion and
time lapse are likely further away than within the next year. These video
features could potentially be provided via CameraX vendor extensions or could
be implemented via our own post-processing of the video output. Panorama,
Photo Sphere, Astrophotography, Motion Photos, Frequent Faces, Dual Exposure
Controls, Google Lens, etc. aren't on the roadmap for GrapheneOS Camera. Video
refresh rate configuration and H.265 support should be available for
GrapheneOS Camera in the near future via CameraX improvements along with DNG
(RAW) support in the further future.</p>
</section>
</section>
<section id="exec-spawning">
<h2><a href="#exec-spawning">Exec spawning</a></h2>
<p>GrapheneOS creates fresh processes (via exec) when spawning applications instead of
using the traditional Zygote spawning model. This improves privacy and security at the
expense of higher cold start app spawning time and higher initial memory usage. It
doesn't impact runtime performance beyond the initial spawning time. It adds somewhere
in the ballpark of 100ms to app spawning time on the flagship devices and is only very
noticeable on lower-end devices with a weaker CPU and slower storage. The spawning
time impact only applies when the app doesn't already have an app process and the OS
will try to keep app processes cached in the background until memory pressure forces
it to start killing them.</p>
<p>In the typical Zygote model, a template app process is created during boot and
every app is spawned as a clone of it. This results in every app sharing the same
initial memory content and layout, including sharing secrets that are meant to be
randomized for each process. It saves time by reusing the initialization work. The
initial memory usage is reduced due to copy-on-write semantics resulting in memory
written only during initialization being shared between app processes.</p>
<p>The Zygote model weakens the security provided by features based on random secrets
including Address Space Layout Randomization (ASLR), stack canaries, heap canaries,
randomized heap layout and memory tags. It cripples these security features since
every app has the values for every other app and the values don't change for fresh app
processes until reboot. Much of the OS itself is implemented via non-user-facing apps
with privileges reserved for OS components. The Zygote template is reused across user
profiles, so it also provides a temporary set of device identifiers across profiles
for each boot via the shared randomized values.</p>
</section>
<section id="bugs-uncovered-by-security-features">
<h2><a href="#bugs-uncovered-by-security-features">Bugs uncovered by security features</a></h2>
<p>GrapheneOS substantially expands the standard mitigations for memory corruption
vulnerabilities. Some of these features are designed to directly catch the memory
corruption bugs either via an explicit check or memory protection and abort the
program in order to prevent them from being exploited. Other features mitigate issues
a bit less directly such as zeroing data immediately upon free, isolated memory
regions, heap randomization, etc. and can also lead to latent memory corruption bugs
crashing instead of the program continuing onwards with corrupted memory. This means
that many latent memory corruption bugs in apps are caught along with some in the OS
itself. These bugs are not caused by GrapheneOS, but rather already existed and are
uncovered by the features. The features are aimed at preventing or hindering exploits,
not finding bugs, but they do that as part of doing their actual job.</p>
<p>Similarly, some of the other privacy and security improvements reduce the access
available to applications and they may crash. Some of these features are always
enabled under the hood, while others like the Network and Sensors toggles are
controlled by users via opt-in or opt-out toggles. Apps may not handle having access
taken away like this, although it generally doesn't cause any issues as it's all
designed to be friendly to apps and fully compatible rather than killing the
application when it violates the rules.</p>
<p>If you run into an application aborting, try to come up with a process for
reproducing the issue and then capture a bug report via the 'Take bug report'
feature in Developer options. Report an issue to <a
href="https://github.com/GrapheneOS/os-issue-tracker/issues">the GrapheneOS OS
issue tracker</a> and email the bug report capture zip to contact@grapheneos.org
with the issue tracker number in the subject like "Bug report capture for issue
#104". The bug report capture includes plain text 'tombstones' with logs,
tracebacks, address space layout, register content and a tiny bit of context
from memory from areas that are interesting for debugging. This may contain
some sensitive data. Feel free to provide only the tombstone for the relevant
crash and filter out information you don't want to send. However, it will be
more difficult to debug if you provide less of the information. If the app
doesn't work with sensitive information, just send the whole tombstone.</p>
</section>
<section id="wifi-privacy">
<h2><a href="#wifi-privacy">Wi-Fi privacy</a></h2>
<p>Wi-Fi on GrapheneOS is very privacy-friendly and is essentially anonymous as long
as apps do not leak uniquely identifying information to the network. GrapheneOS avoids
allowing itself to be fingerprinted as GrapheneOS, other than connections which are
documented (see the FAQ) and can be easily disabled or forced through a VPN
service.</p>
<section id="wifi-privacy-scanning">
<h3><a href="#wifi-privacy-scanning">Scanning</a></h3>
<p>MAC randomization is always performed for Wi-Fi scanning. Pixel
phones have firmware support for scanning MAC randomization going
<a href="https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html">significantly beyond a naive implementation</a>.
On many other devices, there are identifiers exposed by Wi-Fi scanning beyond the MAC
address such as the packet sequence number and assorted identifying information in the
probe requests.</p>
<p>Avoid using hidden APs (i.e. APs not broadcasting their SSID) since all
known hidden SSIDs end up being broadcast as part of scanning for networks to
find them again. SSIDs are not broadcast for standard non-hidden APs. Hidden
APs are only hidden when no devices are connected. It makes little sense as a
privacy feature, especially for a non-mobile AP where knowing the AP exists
can't be used for tracking it since it doesn't move. The feature reduces your
privacy rather than increasing it. If you need to use a hidden AP, make sure
to delete the saved network afterwards.</p>
<p>Wi-Fi and Bluetooth scanning for improving location detection are disabled by
default, unlike the stock OS. These can be toggled in Settings ➔ Location ➔ Wi-Fi and
Bluetooth scanning. These features enable scanning even when Wi-Fi or Bluetooth is
disabled, so these need to be kept disabled to fully disable the radios when Wi-Fi and
Bluetooth are disabled. GrapheneOS doesn't yet have an implementation of a coarse
location service to supplement GPS location, so enabling these options doesn't
actually do anything at the moment. Implementing a supplementary location service is
planned but we need a robust, secure and private implementation via a local database.
The initial focus will likely be a cell phone tower database, so these features still
wouldn't be relevant.</p>
</section>
<section id="wifi-privacy-associated">
<h3><a href="#wifi-privacy-associated">Associated with an Access Point (AP)</a></h3>
<p>Associated MAC randomization is performed by default. This can be controlled
per-network with Settings ➔ Network &amp; Internet ➔ Wi-Fi ➔ &lt;network&gt;
Advanced ➔ Privacy.</p>
<p>In the stock OS, the default is to use a unique persistent random MAC address for
each network. It has 2 options available: "Use randomized MAC (default)" and "Use
device MAC". In GrapheneOS, the default is generating a new random MAC address when
connecting to a network. It has 3 options available: "Use per-connection randomized MAC
(default)", "Use per-network randomized MAC" and "Use device MAC".</p>
<p>The DHCP client uses the anonymity profile rather than sending a hostname
so it doesn't compromise the privacy offered by MAC randomization. When the
per-connection MAC randomization added by GrapheneOS is being used, DHCP
client state is flushed before reconnecting to a network to avoid revealing
that it's likely the same device as before.</p>
<p>GrapheneOS also disables support for stable link-local IPv6 addresses, since these
have the potential to be used as identifiers. It's more sensible to use typical
link-local address generation based on the (randomized) MAC address since link-local
devices have access to both. As of Android 11, Android only uses stable link-local
privacy addresses when MAC randomization is disabled, so we no longer need to disable
the feature.</p>
</section>
</section>
<section id="lte-only-mode">
<h2><a href="#lte-only-mode">LTE-only mode</a></h2>
<p>If you have a reliable LTE connection from your carrier, you can reduce attack
surface by disabling 2G, 3G and 5G connectivity in Settings ➔ Network &amp; Internet ➔
Mobile network ➔ Preferred network type. Traditional voice calls will only work in
the LTE-only mode if you have either an LTE connection and VoLTE (Voice over LTE)
support or a Wi-Fi connection and VoWi-Fi (Voice over Wi-Fi) support. VoLTE /
VoWi-Fi works on GrapheneOS for most carriers unless they restrict it to carrier
phones. US carriers other than T-Mobile tend to be missing these features due to
us not including their proprietary apps.</p>
<p>This feature is not intended to improve the confidentiality of traditional calls and
texts, but it might somewhat raise the bar for some forms of interception. It's not a
substitute for end-to-end encrypted calls / texts or even transport layer encryption.
LTE does provide basic network authentication / encryption, but it's for the network
itself. The intention of the LTE-only feature is only hardening against remote
exploitation by disabling an enormous amount of legacy code.</p>
</section>
<section id="sandboxed-play-services">
<h2><a href="#sandboxed-play-services">Sandboxed Play services</a></h2>
<p>GrapheneOS has a compatibility layer providing the option to install and use
the official releases of Play services in the standard app sandbox. Play services
receives absolutely no special access or privileges on GrapheneOS as opposed to
bypassing the app sandbox and receiving a massive amount of highly privileged
access. Instead, the compatibility layer teaches it how to work within the full
app sandbox. It also isn't used as a backend for the OS services as it would be
elsewhere since GrapheneOS doesn't use Play services even when it's installed.</p>
<p>Since the Play services apps are simply regular apps on GrapheneOS, you install
them within a specific user or work profile and they're only available within that
profile. Only apps within the same profile can use it and they need to explicitly
choose to use it. It works the same way as any other app and has no special
capabilities. As with any other app, it can't access data of other apps and
requires explicit user consent to gain access to profile data or the standard
permissions. Apps within the same profile can communicate with mutual consent and
it's no different for sandboxed Play services.</p>
<p>The core functionality and APIs are almost entirely supported already since
GrapheneOS largely only has to coerce these apps into continuing to run without
being able to use any of the usual invasive OS integration. A compatibility layer
is also provided to support dynamically downloaded/loaded modules (dynamite
modules). The compatibility layer will be gradually expanded and improved in order
to get more of the Play services functionality working.</p>
<section id="sandboxed-play-services-installation">
<h3><a href="#sandboxed-play-services-installation">Installation</a></h3>
<p>Play services is divided up into 3 separate apps: Google Services Framework
(com.google.android.gsf), Google Play services (com.google.android.gms) and
Google Play Store (com.android.vending). To use sandboxed Play services, you
simply need to install the official releases of these 3 apps in the user and
work profiles where you want to use it.</p>
<p>The simplest approach is to only use the Owner user profile. Apps installed
in the Owner profile are sandboxed the same way as everywhere else and don't
receive any special access. If you want to choose which apps use Play services
rather than making it available to all of them, install it in a separate user
or work profile for apps depending on Play services. You could also do it the
other way around, but it makes more sense to try to use as much as possible
without Play services rather than treating not using it as the exceptional
case.</p>
<p>Install com.google.android.gsf, then com.google.android.gms and finally use
a split APK installer to install all 5 of the APKs for com.android.vending
together. Make sure to install all 3 in the correct order and don't skip
installing the Play Store since it provides services used by apps depending on
Play. You can obtain a split APK installer app from either Aurora Store,
F-Droid or the developers of the app via their GitHub releases, etc.</p>
<p>In the future, we'll have a client app for our repository so you'll be able
to install and update the official Play services apps through that app and you
won't need to deal with split APK installation manually.</p>
<ul>
<li><a href="https://apps.grapheneos.org/packages/com.google.android.gsf/">com.google.android.gsf</a></li>
<li><a href="https://apps.grapheneos.org/packages/com.google.android.gms/">com.google.android.gms</a></li>
<li><a href="https://apps.grapheneos.org/packages/com.android.vending/">com.android.vending</a></li>
</ul>
<p>You should give a battery optimization exception to Google Play services
for features like push notifications to work properly in the background. It
isn't needed for the other 2 apps.</p>
<p>After installing the apps, you should open the Play Store and press sign in
to trigger initialization. Signing into an account is optional and it will
work fine without it, but you do need to get it initialized and this is
currently the best way to mimic the initialization done by the stock OS setup
wizard.</p>
<p>You can obtain updates to these apps from our repository which will be easy
once we have a client app. The Play Store app can also be used to update
Google Play services. Updates to the Google Services Framework
(com.google.android.gsf) app are normally only distributed through OS updates
so you need to get those from our repository. The Play Store app isn't able to
update itself through the compatibility layer yet but it may be supported in
the future.</p>
</section>
<section id="sandboxed-play-services-limitations">
<h3><a href="#sandboxed-play-services-limitations">Limitations</a></h3>
<p>Functionality depending on privileged access such as special access to
hardware isn't available. We would need to implement compatibility layers
teaching it how to function as a regular app. This currently isn't within the
scope of the project beyond the existing support for dynamite modules and
partially implemented support for Play Store app installation/updates. The
official Android Auto interface is a good example of functionality heavily
depending on having highly invasive privileged access beyond what would be
realistic to get working with an expanded compatibility layer.</p>
<p>The Play Store app is designed to use privileged permissions for unattended
app installation, updates and removal which isn't possible on GrapheneOS since
it's not a privileged app. GrapheneOS provides a dedicated compatibility layer
for Play Store app installation teaching it to use the standard unprivileged
approach. It prompts the user to permit it as an app source and then prompts
for each app install/update. The Play Store currently doesn't get the result
for the install succeeding or failing so it will think the installation is
still in progress. You can work around this by force stopping the Play Store
after installing an app and then opening it again to install other apps.</p>
<p>Play Store feature delivery isn't currently supported, but this isn't
broadly used by current generation apps aside from large games.</p>
<p>Since there's no OS integration beyond fallback code to make it function
without any special privileges, there isn't a way to launch the Play services
settings activity. We'll need to make a tiny app providing a way to launch
it.</p>
</section>
</section>
<section id="banking-apps">
<h2><a href="#banking-apps">Banking apps</a></h2>
<p>Banking apps are a particularly problematic class of apps for compatibility
with alternate operating systems. Some of these work fine with any GrapheneOS
configuration but most of them have extensive dependencies on Play services. For
many of these apps, it's enough to set up the GrapheneOS sandboxed Play services
feature in the same profile. Unfortunately, there are further complications not
generally encountered with non-financial apps.</p>
<p>Many of these apps have their own crude anti-tampering mechanisms trying to
prevent inspecting or modifying the app in a weak attempt to hide their code and
API from security researchers. GrapheneOS allows users to disable native code
debugging via a toggle in Settings ➔ Security to improve the app sandbox and this
can interfere with apps debugging their own code to add a barrier to analyzing the
app. You should try enabling this again if you've disabled it and are encountering
compatibility issues with these kinds of apps.</p>
<p>Banking apps are increasingly using Google's SafetyNet attestation service to
check the integrity and certification status of the operating system. GrapheneOS
passes the <code>basicIntegrity</code> check but isn't certified by Google so it
fails the <code>ctsProfileMatch</code> check. Most apps currently only enforce
weak software-based attestation which can be bypassed by spoofing what it checks.
GrapheneOS doesn't attempt to bypass the checks since it would be very fragile and
would repeatedly break as the checks are improved. Devices launched with Android 8
or later have hardware attestation support which cannot be bypassed without leaked
keys or serious vulnerabilities so the era of being able to bypass these checks by
spoofing results is coming to an end regardless.</p>
<p>The hardware attestation feature is part of the Android Open Source Project and
is fully supported by GrapheneOS. SafetyNet attestation chooses to use it to
enforce using Google certified operating systems. However, app developers can use
it directly and permit other properly signed operating systems upholding the
security model. GrapheneOS has a
<a href="https://grapheneos.org/articles/attestation-compatibility-guide">a
detailed guide</a> for app developers on how to support GrapheneOS with the
hardware attestation API. Direct use of the hardware attestation API provides much
higher assurance than using SafetyNet so these apps have nothing to lose by using a
more meaningful API and supporting a more secure OS.</p>
</section>
</main>
<footer>
<a href="/"><img src="{{path|/mask-icon.svg}}" width="512" height="512" alt=""/>GrapheneOS</a>
<ul id="social">
<li><a href="https://twitter.com/GrapheneOS">Twitter</a></li>
<li><a href="https://github.com/GrapheneOS">GitHub</a></li>
<li><a href="https://reddit.com/r/GrapheneOS">Reddit</a></li>
<li><a href="https://www.linkedin.com/company/grapheneos/">LinkedIn</a></li>
</ul>
</footer>
</body>
</html>