summaryrefslogtreecommitdiff
path: root/static/usage.html
blob: ded0bf32ee37b2a3e99532fa537222176634abb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
<!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="#usb-peripherals">USB peripherals</a></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-google-play">Sandboxed Google Play</a>
                        <ul>
                            <li><a href="#sandboxed-google-play-installation">Installation</a></li>
                            <li><a href="#sandboxed-google-play-configuration">Configuration</a></li>
                            <li><a href="#sandboxed-google-play-limitations">Limitations</a></li>
                            <li><a href="#sandboxed-google-play-esim">Privileged eSIM management</a></li>
                        </ul>
                    </li>
                    <li><a href="#banking-apps">Banking apps</a></li>
                    <li><a href="#app-link-verification">App link verification</a></li>
                    <li><a href="#carrier-functionality">Carrier functionality</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 controls ➔ 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 ➔ System update.</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>

                    <p>The "Notification settings" option is a shortcut to the System Updater notification
                    settings which allows you to control notification settings from System Updater such as
                    notification dot, lock screen, and noisy / silent notifications. These notifications
                    include updater errors, progress, already up to date, and reboot prompts. By default all
                    notifications are enabled.</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 raven-ota_update-2021122018.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 focused on privacy and
                    security. It includes modes for capturing images, videos and QR / barcode
                    scanning along with additional modes based on CameraX vendor extensions
                    (Portrait, HDR, Night Sight, Face Retouch and Auto) on <a
                    href="https://developer.android.com/training/camerax/devices">devices where
                    they're available</a> (not available on Pixels yet).</p>

                    <p>Modes are displayed as tabs at the bottom of the screen. You can switch
                    between modes using the tab interface or by swiping left/right anywhere on the
                    screen. 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 app has an in-app gallery and video player for images/videos taken with
                    it. It currently opens an external editor activity for the edit action.
                    GrapheneOS comes with AOSP Gallery which provides an editor activity. You can
                    install a nicer photo editor and the Camera app will be able to use it. We
                    plan to replace AOSP Gallery with a standalone variant of the gallery we're
                    developing for the Camera app in the future.</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 will be provided in
                    the future.</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. The torch can be toggled with the button
                    at the bottom center. The auto toggle at the bottom left can be used to toggle
                    scanning for all supported barcode types. Alternatively, you can select which
                    barcode types it should scan via the menu at the top. It only scans QR codes
                    by default since that provides quick and reliable scanning. Most other types
                    of barcodes can result in false positives. Each enabled type will slow down
                    the scanning and will make it more prone to false positives especially with
                    difficult to scan barcodes such as a dense QR code.</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>By default, EXIF metadata is stripped for captured images and only includes
                    the orientation. Stripping metadata for videos is planned but not supported
                    yet. Orientation metadata isn't stripped since it's fully visible from how the
                    image is displayed so it doesn't count as hidden metadata and is needed for
                    proper display. You can toggle off stripping EXIF metadata in the More
                    Settings menu opened from the settings dialog. Disabling metadata stripping
                    will leave the timestamp, phone model, exposure configuration and other
                    metadata. Location tagging is disabled by default and won't be stripped if you
                    enable it.</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-google-play">sandboxed
                    Google Play compatibility layer</a> and can take full advantage of the
                    available cameras and image processing hardware as it can on the stock OS. It
                    currently only depends on GSF and can be used without Play services (GMS) or
                    the Play Store.</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
                    frame 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 <a
                href="mailto:contact@grapheneos.org">contact@grapheneos.org</a> 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 <a href="/faq#default-connections">default connections FAQ</a>)
                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 ➔
                    Location Services ➔ 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 itself doesn't currently include a supplementary location service
                    based on Wi-Fi and Bluetooth scanning. These options impact whether apps such
                    as sandboxed Google Play are able to use the functionality if you grant them
                    the Location permission. GrapheneOS plans to eventually include an OS service
                    based on local databases rather than a network-based service giving the user's
                    location to a server whenever location is being used.</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 in Settings ➔ Network &amp; Internet ➔ Internet ➔ &lt;network&gt; ➔ 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 ➔ SIMs ➔ 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. Some carriers may be missing VoWi-Fi due to us not including their
                proprietary apps. Please note that AT&amp;T users may see "5Ge" being used when
                LTE Only mode is enabled as AT&amp;T intentionally mislabel LTE services as "5Ge"
                to mislead users.</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-google-play">
                <h2><a href="#sandboxed-google-play">Sandboxed Google Play</a></h2>

                <p>GrapheneOS has a compatibility layer providing the option to install and use
                the official releases of Google Play in the standard app sandbox. Google Play
                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 Google Play even when it's installed.</p>

                <p>Since the Google Play 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 Google Play.</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 Google Play functionality working.</p>

                <p>GrapheneOS provides a dedicated compatibility layer for Play Store app
                installation/updates/removal teaching it to use the standard unprivileged approach
                available to sandboxed apps. It prompts the user to permit it as an app source and
                then prompts for the initial app install/update or removal. It will use Android
                12's support for unattended updates when possible which means it can do unattended
                updates of modern (API 29+) apps where it was the installer for the currently
                installed version already.</p>

                <section id="sandboxed-google-play-installation">
                    <h3><a href="#sandboxed-google-play-installation">Installation</a></h3>

                    <p>Google Play is divided up into 3 separate apps:</p>

                    <ul>
                        <li>Google Services Framework (com.google.android.gsf)</li>
                        <li>Google Play services (com.google.android.gms)</li>
                        <li>Google Play Store (com.android.vending)</li>
                    </ul>

                    <p>To use sandboxed Google Play, 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 Google Play
                    rather than making it available to all of them, install it in a separate user
                    or work profile for apps depending on Google Play. You could also do it the
                    other way around, but it makes more sense to try to use as much as possible
                    without Google Play rather than treating not using it as the exceptional
                    case.</p>

                    <p>You can open our app repository client (Apps) and install the 3 core Google
                    Play apps mirrored in our repository. Our app repository client has support
                    for dependency installation so you can simply directly install the Play Store
                    and it will install GSF and then GMS as dependencies.</p>

                    <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>The Play Store provides many services used by apps including Play Asset
                    Delivery, Play Feature Delivery, in-app purchases and license checks for paid
                    apps. You can use sandboxed Google Play without the Play Store but many apps
                    won't work correctly without it. The Play Store app is also the most secure
                    way to install and update apps from the Play Store. Installing it is highly
                    recommended for general purpose usage but you can install only GSF or only
                    GSF/GMS if you know it's all you need for what you want to use.</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 app repository client. Our
                    compatibility layer supports the Play Store updating itself and also Play
                    services but we've chosen to block it from being able to update them in order
                    to ship the updates through our repository after testing them. They use long
                    staged rollouts for these app updates and it results in confusion when users
                    can't install older versions in another user, which is resolved by us handling
                    the updates ourselves.</p>

                    <p>Our compatibility layer has support for Play Games Services which you can
                    obtain by installing Google Play Games from the Play Store. Many games on the
                    Play Store depend on having Google Play Games installed.</p>
                </section>

                <section id="sandboxed-google-play-configuration">
                    <h3><a href="#sandboxed-google-play-configuration">Configuration</a></h3>

                    <p>The compatibility layer has a configuration menu available at Settings ➔
                    Apps ➔ Sandboxed Google Play.</p>

                    <p>By default, apps using Google Play geolocation are redirected to our own
                    implementation on top of the standard OS geolocation service. If you want to
                    use Google's geolocation service instead, you can disable the "Reroute
                    location requests to OS APIs" toggle and manually grant "Allow all the time"
                    Location access to Google Play services. For it to be fully functional, you
                    also need to use "Google Location Accuracy" link to access the Google Play
                    services menu for opting into their network location service. This will send
                    the nearby Wi-Fi and cellular networks provided via the Location permission to
                    their service to retrieve a location estimate. The Nearby Devices permission
                    can also be granted to give it access to nearby Bluetooth device IDs. If you
                    stick with the default enabled redirection mode, none of this needs to be
                    granted for working geolocation in apps. In order to fully take advantage of
                    Wi-Fi and Bluetooth scanning, you also need to enable the scanning toggles in
                    Settings ➔ Location ➔ Location services which are disabled by default rather
                    than enabled by default like the stock OS.</p>

                    <p>Re-routing location to the OS geolocation service will use more power than
                    using the Google Play geolocation service since we do not provide a
                    network-based location service and implement it via GNSS / A-GPS only. In the
                    future, we plan on providing a pseudo-network geolocation service for the OS
                    by using a local database of cell towers, and the location redirection feature
                    can also make use of this future OS implementation for network location
                    requests once it's available.</p>

                    <p>The Google Location Accuracy and Google settings activities would normally
                    be integrated into the OS but we don't include any of the standard Google Play
                    integration so there needs to be an app providing a way to access them.</p>

                    <p>The menu also provides links to this usage guide, Play services system
                    settings, Play Store system settings and Google settings. The Play services
                    and Play Store system settings are only included for convenience since they
                    can be accessed the same way as any other app via Settings ➔ Apps.</p>
                </section>

                <section id="sandboxed-google-play-limitations">
                    <h3><a href="#sandboxed-google-play-limitations">Limitations</a></h3>

                    <p>Our compatibility layer has to be expanded on a case-by-case basis to teach
                    Play services to work as a regular app without any of the invasive access
                    and integration it expects. In many cases, it doesn't truly need the access or
                    we can teach it to use the regular approach available to a normal app. In some
                    cases, the functionality it offers fundamentally requires privileged
                    access and cannot be supported. For example, it's unlikely Android Auto will be
                    supported. The same applies to other highly invasive OS integration / control
                    or privileged access to hardware. There are also a lot of features such as the
                    FIDO2 security key support which could be made to fully work despite reliance
                    on a lot of privileged APIs (their FIDO2 service is partially working
                    already). In the case of FIDO2, we could also eventually support redirecting
                    to our own implementation similarly to how we do that by default for
                    geolocation. Our compatibility layer is a very actively developed work in
                    progress and most of the remaining unavailable functionality is quickly
                    becoming supported.</p>

                    <p>Functionality depending on the OS integrating Play services and using it as
                    a backend is unavailable. An OS integrating Play uses it as the backend for OS
                    services such as geolocation. GrapheneOS never uses it as the backend/provider
                    for OS services. In cases such as text-to-speech (TTS) where the OS allows the
                    user to choose the provider, Play services can often be used. It's on a level
                    playing field with other apps on GrapheneOS.</p>

                    <p>Play Store assumes that uninstallation always succeeds so it will stall if
                    it tries to uninstall an app and you reject it. You can work around this by
                    force stopping and then reopening it.</p>
                </section>

                <section id="sandboxed-google-play-esim">
                    <h3><a href="#sandboxed-google-play-esim">Privileged eSIM management</a></h3>

                    <p>By default GrapheneOS always has shipped with baseline support for eSIM,
                    where users can use any eSIMs installed previously on the device. However, in
                    order to manage and add eSIMs, proprietary Google functionality is needed. This
                    is fully disabled by default.</p>

                    <p>Privileged eSIM management can be enabled in Settings ➔ Network &amp; 
                    Internet ➔ Privileged eSIM management. The toggle will be greyed out and unusable
                    if sandboxed Google Play is not installed, as the functionality is reliant on it.</p>

                    <p>By enabling the toggle, the proprietary Google functionality is enabled and
                    will be used by the OS to provision and manage eSIMs.</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 Google Play
                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">
                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>

            <section id="app-link-verification">
                <h2><a href="#app-link-verification">App link verification</a></h2>

                <p>Android apps can declare associations with domains in order to handle those
                URLs in the app automatically. For security reasons, app links are disabled by
                default to prevent apps intercepting arbitrary URLs. First party apps associated
                with a domain are expected to be authorized by the domain. Apps can ask for their
                app links to be verified by the OS by marking them with <code>autoVerify</code> in
                their manifest. The OS will securely confirm that the domain authorizes the app to
                handle the domain's URLs. Users can also manually enable an app's link
                associations via Settings ➔ Apps ➔ App name ➔ Open by default ➔ Add link. Apps can
                ask users to enable the associations and send them to this page in the Settings
                app.</p>

                <p>As an example, the first party YouTube app will have the app links verified by
                the OS automatically while the NewPipe app requires manually enabling handling
                links for YouTube and other sites.</p>

                <p>Verification of app links by the OS is done by the Intent Filter Verification
                Service system app. It will use an HTTPS GET request to fetch
                <code>https://example.com/.well-known/assetlinks.json</code> in order to process a
                request to verify that an app can handle <code>example.com</code> links. The app
                needs to have their app id and signing keys authorized by the domain in order for
                the verification to succeed.</p>

                <p>These network requests by the Intent Filter Verification Service to verify app
                associations with domains are commonly confused for network requests made by the
                apps. It's simply an HTTPS GET request without identifying information and doesn't
                offer a communication channel with the app. Redirects won't be followed so there
                will be a single request for each attempt to verify a domain.</p>

                <p>If you don't want automatic app link verification, you can disable the Network
                permission added by GrapheneOS for the Intent Filter Verification Service system
                app. In the future, we may provide a way to disable verification directly instead
                of stopping it from working. It will make heavily throttled attempts to verify a
                domain after the check failed which won't negatively impact battery life due to
                the conservative JobScheduler-based implementation.</p>

                <p>For more details, see the
                <a href="https://developer.android.com/training/app-links/verify-site-associations">developer
                documentation on app link verification</a>.</p>
            </section>

            <section id="carrier-functionality">
                <h2><a href="#carrier-functionality">Carrier functionality</a></h2>

                <p>GrapheneOS aims to work with all carriers that are officially supported by Google
                on the stock operating system on Pixel devices. Wi-Fi Calling, VoLTE, Visual Voicemail,
                MMS, SMS, Calling and 5G (SA and NSA) all are supported, however some functionality may
                not be usable due to Google not supporting carriers on the stock OS officially or
                due to GrapheneOS not shipping proprietary apps required in order for this
                functionality to work on some carriers. GrapheneOS extracts CarrierConfigs, APNs,
                modem configurations, Visual Voicemail configurations and MMS configurations from the
                stock operating system to ensure users get easy carrier support that "just works".</p>

                <p>Please note that in some regions, LTE is referred to as 4G.</p>

                <p>Generally Visual Voicemail, SMS, MMS, Calls and VoLTE will work fine on GrapheneOS
                with officially supported carriers by Google. Wi-Fi calling may vary due to a reliance
                on proprietary Google apps which GrapheneOS does not ship.</p>

                <p>If you are having problems sending or receiving SMS/MMS messages, we suggest that 
                you perform the following steps:</p>

                <ul>
                    <li>Deregister your phone number from <a href="https://selfsolve.apple.com/deregister-imessage">Apple iMessage</a></li>
                    <li>Deregister your phone number from <a href="https://messages.google.com/disable-chat">Google Chat Features</a></li>
                    <li>Deregister your phone number from your carrier's RCS service</li>
                </ul>

                <p>If you continue to have problems despite following the instructions above or you 
                have another carrier related issue, we suggest that you perform the following steps:</p>

                <ul>
                    <li>Some carriers require you to explicitly opt in to use services such as Wi-Fi calling.
                        Consult your carrier's documentation on the process for this or contact them.</li>
                    <li>Reset Mobile Network settings in Settings ➔ System ➔ Reset options ➔ Reset Wi-Fi,
                        mobile &amp; Bluetooth and then reboot the device.</li>
                    <li>USA users only: You may need to request your carrier to enable CDMA-less mode if
                        you have issues.</li>
                    <li>Follow your carrier's instructions for setting up APNs, this can be found in
                        Settings ➔ Network &amp; Internet ➔ SIMs ➔ Access Point Names</li>
                    <li>If calls do not work and you have <a href="#lte-only-mode">LTE-only mode</a> enabled,
                        try toggling it off. Your carrier may not properly support VoLTE.</li>
                    <li>As a last resort you may need to ask your carrier for a replacement SIM card.</li>
                </ul>

                <p>GrapheneOS includes bypasses for carrier restrictions on APN editing, tethering via
                USB, Ethernet, Bluetooth and Wi-Fi and the ability to disable 2G, actions which would not
                have been possible on the stock operating system.</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>