├── Distribution.txt
├── PE_for_Android.keystore
├── PE_for_Android_whitepaper.pdf
├── README.md
├── addon-sys-img.xml
├── addon.xml
├── architecture.png
└── howto
├── apps
├── apps.md
├── instant-run.png
├── policy-settings-1.png
├── policy-settings-2.png
├── policy.md
├── sdk-add-site.png
├── sdk-installed.png
├── sdk-path.png
├── sdk-project.md
├── sdk.md
└── upal.md
├── phone
└── installation.md
└── platform
└── platform.md
/Distribution.txt:
--------------------------------------------------------------------------------
1 | Distribution Statement A. Approved for Public Release; Distribution Unlimited.
2 |
3 | Copyright © 2020 by Two Six Labs, LLC.
4 |
5 | This material is based upon work supported by DARPA and AFRL under Contract No. FA8750-16-C-0006.
6 |
7 | DISCLAIMER LANGUAGE
8 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
9 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
10 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
11 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
12 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
13 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
14 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
15 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 |
--------------------------------------------------------------------------------
/PE_for_Android.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/PE_for_Android.keystore
--------------------------------------------------------------------------------
/PE_for_Android_whitepaper.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/PE_for_Android_whitepaper.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Privacy Enhancements for Android
2 |
3 | ## Overview
4 |
5 | Privacy Enhancements for Android (PE for Android) is a platform for exploring
6 | concepts in regulating access to private information on mobile devices. We
7 | developed PE for Android as a fork of the [Android Open Source Project
8 | (AOSP)](https://source.android.com) release for Android 9 "Pie."
9 |
10 | PE for Android offers new APIs that facilitate the development of swappable
11 | componenents that are invoked when apps request private data. This includes
12 | *Policy Managers* that can log and decide on requests to access sensitive
13 | information. Additionally, PE for Android offers the *Private Data Service*
14 | and associated modules dubbed *uPALs*, which transform private data into
15 | less sensitive forms (e.g., from full-resolution GPS coordinates to just
16 | a zip code). This modular architecture allows for the experimentation of
17 | various models for how apps use sensitive data and how users can gain
18 | insight into that.
19 |
20 | 
21 | *Apps interface with the Privacy [Abstraction] Layer (PAL). This contains
22 | the Policy Manager for regulating access to sensitive services, and uPALs
23 | to transform sensitive data prior to returning it to the requesting app.*
24 |
25 | For more details: [Full PE for Android whitepaper](PE_for_Android_whitepaper.pdf)
26 |
27 | ## How-to's
28 |
29 | * Modifying and installing PE for Android
30 | + [Building PE for Android](howto/platform/platform.md)
31 | + [Installing PE for Android](howto/phone/installation.md)
32 |
33 | * Developing apps for PE for Android
34 | + [Installing the SDK addons](howto/apps/sdk.md)
35 | + [Including the SDK addons to your project](howto/apps/sdk-project.md)
36 | + [Using PE for Android in apps](howto/apps/apps.md)
37 | + [Developing Policy Managers](howto/apps/policy.md)
38 | + [Developing uPAL modules](howto/apps/upal.md)
39 |
40 | ## Examples
41 |
42 | * [uPALs](https://github.com/twosixlabs/PE_for_Android_example_upals):
43 | various privacy-enhancing data transformations
44 | * [Signal Private Messenger](https://github.com/twosixlabs/PE_for_Android_example_signal):
45 | remove full access to contact list
46 | * [Forecastie](https://github.com/twosixlabs/PE_for_Android_example_forecastie):
47 | remove full access to location data
48 | * [Privacy Checkup](https://github.com/twosixlabs/PE_for_Android_privacycheckup):
49 | inform user of apps accessing sensitive data
50 |
51 |
--------------------------------------------------------------------------------
/addon-sys-img.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 1
7 | PE for Android System Image, API 28
8 | 28
9 | x86_64
10 | pe_android
11 | PE for Android
12 |
13 | two_six_labs
14 | Two Six Labs
15 |
16 |
17 |
18 | 620625027
19 | 393f0d01947b8cdb0508e77073a4644a81cdecd3
20 | https://github.com/twosixlabs/PE_for_Android/releases/download/peandroid_v5.0.0/pea_pie_system-images_v1.zip
21 | macosx
22 |
23 |
24 | 620625027
25 | 393f0d01947b8cdb0508e77073a4644a81cdecd3
26 | https://github.com/twosixlabs/PE_for_Android/releases/download/peandroid_v5.0.0/pea_pie_system-images_v1.zip
27 | linux
28 |
29 |
30 | 620625027
31 | 393f0d01947b8cdb0508e77073a4644a81cdecd3
32 | https://github.com/twosixlabs/PE_for_Android/releases/download/peandroid_v5.0.0/pea_pie_system-images_v1.zip
33 | windows
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/addon.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | two_six_labs
7 | Two Six Labs
8 | peandroid_add-on
9 | PE for Android
10 | PE for Android Add-on
11 | 28
12 | 1
13 |
14 | com.twosixlabs.peandroid
15 | com.twosixlabs.peandroid.pal
16 | com.twosixlabs.peandroid.privacymanager
17 |
18 |
19 |
20 | 1486330
21 | d2b2b397813914a2d43529b8badd2603aa386085
22 | https://github.com/twosixlabs/PE_for_Android/releases/download/peandroid_v5.0.0/pea_pie_sdk_addon_v1.zip
23 | macosx
24 |
25 |
26 | 1486330
27 | d2b2b397813914a2d43529b8badd2603aa386085
28 | https://github.com/twosixlabs/PE_for_Android/releases/download/peandroid_v5.0.0/pea_pie_sdk_addon_v1.zip
29 | linux
30 |
31 |
32 | 1486330
33 | d2b2b397813914a2d43529b8badd2603aa386085
34 | https://github.com/twosixlabs/PE_for_Android/releases/download/peandroid_v5.0.0/pea_pie_sdk_addon_v1.zip
35 | windows
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/architecture.png
--------------------------------------------------------------------------------
/howto/apps/apps.md:
--------------------------------------------------------------------------------
1 | # How-to: develop apps for PE for Android
2 |
3 | * [Overview](#overview)
4 | * [Example Private Data Service Call](#example-private-data-service-call)
5 | * [Specify the data source](#specify-the-data-source)
6 | - [Data type parameter helpers](#data-type-parameter-helpers)
7 | * [Specify the purpose](#specify-the-purpose)
8 | * [Specify the callback](#specify-the-callback)
9 | * [Issue the request](#issue-the-request)
10 |
11 | ## Overview
12 |
13 | Apps can take advantage of PE for Android's new Private Data Service API. This
14 | API allows apps to receive sensitive user and device data in a least-privileges
15 | manner. For example, rather than calling Android's `LocationManager`, which
16 | exposes full-fidelity location data, apps can request location data from the
17 | Private Data Service and reduce its fidelity using a uPAL (micro-PAL) module.
18 |
19 | Apps invoke the Private Data Service by by populating a `DataRequest` object
20 | and passing it to the `PrivateDataManager`. In order to avoid apps from hanging
21 | or producing ANR warnings, these requests are handled asynchronously, with the
22 | result being returned via a callback declared in the request.
23 |
24 | This guide steps through an example code snippet that calls the Private Data
25 | Service to request [zip-code-level location
26 | data](https://github.com/twosixlabs/PE_for_Android_example_upals/blob/master/app/src/main/java/com/twosixlabs/exampleupals/ZipcodeMicroPAL.java).
27 | These instructions assume that the SDK addons are [installed in your Android
28 | Studio Environment](sdk.md) and that they're [included in your
29 | project](sdk-project.md).
30 |
31 | ## Example Private Data Service call
32 |
33 | ```java
34 | // Assuming this code is in a Context-derived class (e.g., Activity, Service, etc.)
35 | Context context = this;
36 |
37 | // Specify the data source
38 | DataRequest.DataType dt = DataRequest.DataType.LOCATION;
39 | Bundle locationParams = new DataRequest.LocationParamsBuilder()
40 | .setUpdateMode(DataRequest.LocationParamsBuilder.MODE_LAST_LOCATION)
41 | .setTimeoutMillis(60000)
42 | .build();
43 |
44 | // Specify the uPAL
45 | String pal = "com.twosixlabs.examplepals.ZipcodeMicroPAL";
46 | Bundle palParams = null;
47 |
48 | // Specify the purpose
49 | DataRequest.Purpose purpose = DataRequest.Purpose.ADS("Paying the bills");
50 |
51 | // Specify the callback
52 | ResultReceiver callback = new ResultReceiver(null) {
53 | @Override
54 | protected void onReceiveResult(int resultCode, Bundle resultData) {
55 | if(resultCode == PrivateDataManager.RESULT_SUCCESS) {
56 | Log.d(TAG, "Received callback");
57 | for(String key : resultData.keySet()) {
58 | Log.d(TAG, String.format("Received data key=%s , value=%s", key, resultData.get(key).toString()));
59 | }
60 | }
61 | }
62 | };
63 |
64 | // Issue the request
65 | DataRequest request = new DataRequest(context,
66 | dt, locationParams,
67 | pal, palParams,
68 | purpose, callback);
69 | PrivateDataManager pdm = PrivateDataManager.getInstance();
70 | pdm.requestData(request);
71 | ```
72 |
73 | The following sections detail discuss the key parts of making a Private Data
74 | Service Request.
75 |
76 | ## Specify the data source
77 |
78 | ```java
79 | DataRequest.DataType dt = DataRequest.DataType.LOCATION;
80 | Bundle locationParams = new DataRequest.LocationParamsBuilder()
81 | .setUpdateMode(DataRequest.LocationParamsBuilder.MODE_LAST_LOCATION)
82 | .setTimeoutMillis(60000)
83 | .build();
84 | ```
85 |
86 | The first step to build a Private Data Service request is to specify what
87 | sensitive data reosurce from which to retrieve information. In this example,
88 | the code specifies a request for location data. Some data types require
89 | additional parameters, detailed below.
90 |
91 | ### Data type parameter helpers
92 |
93 | The `DataRequest` class includes builder classes to construct parameters for
94 | the LOCATION, CALENDAR, and SMS data types. Other data types don't require
95 | parameters, and so the params argument can be set to anything (including
96 | `null`) in those cases.
97 |
98 | The `LocationParamsBuilder` specifies the mode of the location request (i.e.,
99 | either using the last known cached location, or performing an actual location
100 | update using geolocation hardware) and how long the request can be active
101 | before it times out:
102 |
103 | ```java
104 | new DataRequest.LocationParamsBuilder()
105 | .setUpdateMode(DataRequest.LocationParamsBuilder.MODE_LAST_LOCATION)
106 | .setTimeoutMillis(60000)
107 | .build();
108 |
109 | ```
110 |
111 | The `MessageParamsBuilder` and `CalendarParamsBuilder` define the time window
112 | for which SMSs and calendar events, respectively, will be returned:
113 |
114 | ```java
115 | new DataRequest.MessageParamsBuilder()
116 | .setStartUtcMillis(0l)
117 | .setEndUtcMillis(1572459040000l)
118 | .build();
119 | ```
120 |
121 | ## Specify the uPAL
122 |
123 | ```java
124 | String pal = "com.twosixlabs.examplepals.ZipcodeMicroPAL";
125 | Bundle palParams = null;
126 | ```
127 |
128 | A Private Data Service request must specify the uPAL that will transform the
129 | sensitive data before returning it to the calling app. The uPAL developer
130 | is responsible for documenting the uPAL identifier, parameters (if any), and
131 | accepted data types.
132 |
133 | Note that that uPALs can be installed separately from the calling app. Calling
134 | an unavailable uPAL will result in a `null` data bundle passed back to the
135 | requesting app.
136 |
137 | ## Specify the purpose
138 |
139 | ```java
140 | DataRequest.Purpose purpose = DataRequest.Purpose.ADS("Paying the bills");
141 | ```
142 |
143 | PE for Android requires Private Data Service requests to specify the purpose
144 | for the data access. [Policy managers](policy.md) can operate on declared
145 | purposes in granting or denying access to sensitive resources.
146 |
147 | The `DataRequest.Purpose` inner class defines available purposes. To
148 | declare a purpose, select the desired purpose and provide a human-readable
149 | explanation for the request.
150 |
151 | ```java
152 | DataRequest.Purpose.ADS("Paying the bills");
153 | DataRequest.Purpose.SOCIAL("Integration with Facebook");
154 | ```
155 |
156 | ## Specify the callback
157 |
158 | ```java
159 | ResultReceiver callback = new ResultReceiver(null) {
160 | @Override
161 | protected void onReceiveResult(int resultCode, Bundle resultData) {
162 | if(resultCode == PrivateDataManager.RESULT_SUCCESS) {
163 | Log.d(TAG, "Received callback");
164 | for(String key : resultData.keySet()) {
165 | Log.d(TAG, String.format("Received data key=%s , value=%s", key, resultData.get(key).toString()));
166 | }
167 | }
168 | }
169 | };
170 | ```
171 |
172 | After the uPAL finishes transforming the requested data, it returns its result
173 | via callback. Callbacks should check the result code before processing the
174 | incoming data. In this example, the callback simply prints out all the
175 | key-value pairs inside the incoming data bundle sent by the uPAL.
176 |
177 | ## Issue the request
178 |
179 | ```java
180 | DataRequest request = new DataRequest(context,
181 | dt, locationParams,
182 | pal, palParams,
183 | purpose, callback);
184 | PrivateDataManager pdm = PrivateDataManager.getInstance();
185 | pdm.requestData(request);
186 | ```
187 |
188 | The `PrivateDataManager` is the entry-point for the Private Data Service. Use
189 | an instance of the `PrivateDataManager` to issue the request for uPAL-transformed
190 | data. The callback specified in the request will run asynchronously upon the
191 | completion of the request.
192 |
193 |
--------------------------------------------------------------------------------
/howto/apps/instant-run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/howto/apps/instant-run.png
--------------------------------------------------------------------------------
/howto/apps/policy-settings-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/howto/apps/policy-settings-1.png
--------------------------------------------------------------------------------
/howto/apps/policy-settings-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/howto/apps/policy-settings-2.png
--------------------------------------------------------------------------------
/howto/apps/policy.md:
--------------------------------------------------------------------------------
1 | # How-to: develop policy managers
2 |
3 | * [Overview](#overview)
4 | * [Example Policy Manager](#example-policy-manager)
5 | * [Permission hooks](#permission-hooks)
6 | * [Registering the service](#registering-the-service)
7 | * [Deploying a Policy Manager](#deploying-a-policy-manager)
8 |
9 | ## Overview
10 |
11 | Policy Managers are trusted apps that have the ability to grant or deny access
12 | to sensitive resources. PE for Android invokes the current active Policy
13 | Manager when apps are installed, as well as when apps request
14 | [dangerous permissions](https://developer.android.com/guide/topics/permissions/overview)
15 | or use the [Private Data Service](apps.md).
16 |
17 | Given this component's privileged position in PE for Android's permission
18 | system, Developers can implement novel permission controls and transparency
19 | tools as Policy Managers. And developers can do so using standard Android app
20 | development and deployment processes, without needing to modify the platform
21 | code itself.
22 |
23 | This guide serves as an introduction to the main concepts of Policy Manager
24 | development. The following assumes that the PE for Android SDK addons
25 | are already [installed in Android Studio](sdk.md) and that the addons
26 | have been [included in the project](sdk-project.md). Additionally, as
27 | Policy Managers are trusted components, PE for Android requires that
28 | Policy Manager apps are [properly signed](sdk-project.md#signing-policy-managers-and-upals).
29 |
30 | ## Example Policy Manager
31 |
32 | ```java
33 | public class DummyPolicyManagerService extends PolicyManagerService {
34 | @Override
35 | public boolean onAppInstall(String packageName, String odp) {
36 | return true;
37 | }
38 |
39 | @Override
40 | public void onDangerousPermissionRequest(String packageName, String permission,
41 | String purpose,
42 | List stackTrace,
43 | int flags,
44 | ComponentName callingComponent,
45 | ComponentName topActivity,
46 | ResultReceiver recv) {
47 | Bundle bundle = new Bundle();
48 | bundle.putBoolean("allowPerm", true);
49 | recv.send(0, bundle);
50 | }
51 |
52 | @Override
53 | public void onPrivateDataRequest(String packageName, String permission,
54 | String purpose, String pal,
55 | String description, ResultReceiver recv) {
56 | Bundle bundle = new Bundle();
57 | bundle.putBoolean("allowPerm", true);
58 | recv.send(0, bundle);
59 | }
60 | }
61 | ```
62 |
63 | ## Permission hooks
64 |
65 | The `PolicyManagerService` base class exposes three abstract methods that a
66 | Policy Manager implementation must define:
67 |
68 | * `boolean onAppInstall()`: Called when an app is installed
69 | * `void onDangerousPermissionRequest()`: Called when a dangerous permission is requested via the stock Android API
70 | * `void onPrivateDataRequest()`: Called when an app makes a request to the [Private Data Service](apps.md)
71 |
72 | All three of these hooks return a true/false result indicating if the corresponding
73 | action was granted. `onDangerousPermissionRequest()` and `onPrivateDataRequest()` do
74 | this via a callback, as those permission checks are done asynchronously.
75 |
76 | ## Registering the service
77 |
78 | ```xml
79 |
84 |
85 |
86 |
87 |
88 | ```
89 |
90 | The Policy Manager's core service must declare the `POLICY_MANAGER_SERVICE`
91 | permission in order to use hooks exposed by the PE for Android API.
92 | Additionally, the service needs to listen for broadcasts of the
93 | `android.app.action.DEVICE_POLICY_MANAGER_START` in order to be set
94 | as the active Policy Manager.
95 |
96 | ## Deploying a Policy Manager
97 |
98 | As Policy Managers are regular Android apps (albeit with additional permissions
99 | and a specific signing key), developers and users can install them as they
100 | would any other app: via Android Studio, or with the `adb install` command.
101 |
102 | Multiple Policy Managers can be present on a device simultaneously. However,
103 | only one can be set as the active one. The user can set the active Policy
104 | Manager by opening the device's system Settings and using the PE for Android
105 | Settings panel.
106 |
107 |  
108 |
109 |
--------------------------------------------------------------------------------
/howto/apps/sdk-add-site.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/howto/apps/sdk-add-site.png
--------------------------------------------------------------------------------
/howto/apps/sdk-installed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/howto/apps/sdk-installed.png
--------------------------------------------------------------------------------
/howto/apps/sdk-path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twosixlabs/PE_for_Android/bc4dc76ca1bb7953c2273b2bc12d1d12b8ba239c/howto/apps/sdk-path.png
--------------------------------------------------------------------------------
/howto/apps/sdk-project.md:
--------------------------------------------------------------------------------
1 | # How-to: including the SDK addons to your project
2 |
3 | * [Overview](#overview)
4 | * [build.gradle changes](#buildgradle-changes)
5 | - [Signing Policy Managers and uPALs](#signing-policy-managers-and-upals)
6 | - [local.properties workaround](#localproperties-workaround)
7 | * [AndroidManifest.xml changes](#androidmanifestxml-changes)
8 | * [Enabling inline Javadocs](#enabling-inline-javadocs)
9 |
10 | ## Overview
11 |
12 | The PE for Android SDK addons enable apps to use PE for Android's new
13 | APIs. Apps that implement Policy Managers, uPALs, or use the Private Data
14 | Service must integrate with the SDK addons.
15 |
16 | After [installing the addons](sdk.md), the following steps will allow an Android Studio
17 | project to take advantage of PE for Android's features.
18 |
19 | ## build.gradle changes
20 |
21 | The app-level `build.gradle` file specifies the target platform for the
22 | project. Apps that use PE for Android's features must specify this
23 | accordingly:
24 |
25 | ```
26 | android {
27 | ...
28 |
29 | compileSdkVersion 'Two Six Labs:PE for Android:28'
30 |
31 | ...
32 |
33 | defaultConfig {
34 | ...
35 | minSdkVersion 28
36 | targetSdkVersion 28
37 | ...
38 | }
39 |
40 | ...
41 | }
42 | ```
43 |
44 | ### Signing Policy Managers and uPALs
45 |
46 | PE for Android considers Policy Managers and uPAL modules as trusted software.
47 | Implementations of these must be signed by the system key, else PE for Android
48 | will block their installation. The following will tell Android Studio to
49 | generate a properly signed APK when compiling the project:
50 |
51 | 1. Obtain the [PE for Android signing key](https://github.com/twosixlabs/PE_for_Android/raw/master/PE_for_Android.keystore) and save it in the same directory as the app-level `build.gradle`
52 |
53 | 2. Add the following lines to the app-level `build.gradle`:
54 |
55 | ```
56 | android {
57 | ...
58 |
59 | signingConfigs {
60 | PAL_config {
61 | keyAlias 'peandroid'
62 | keyPassword 'peandroid'
63 | storeFile file('PE_for_Android.keystore')
64 | storePassword 'peandroid'
65 | }
66 | }
67 |
68 | ...
69 |
70 | buildTypes {
71 | release {
72 | ...
73 | signingConfig signingConfigs.PAL_config
74 | ...
75 | }
76 |
77 | debug{
78 | ...
79 | signingConfig signingConfigs.PAL_config
80 | ...
81 | }
82 | }
83 |
84 | ...
85 | ```
86 |
87 | ### local.properties workaround
88 |
89 | There's an unresolved bug that prevents newer versions of Gradle from properly
90 | finding and including the SDK addons library. Explicitly declaring the path to
91 | your Android SDK directory serves as a workaround for this bug.
92 |
93 | You can find your Android SDK directory using Android Studio:
94 |
95 | 1. Open any Android Studio project
96 | 2. Open the "Tools" menu and select "SDK Manager"
97 | 3. The Android SDK location will be shown near the top of the window
98 |
99 | 
100 |
101 | After obtaining this information, create a `local.properties` file in your Android
102 | Studio project's top-level directory (if it doesn't already exist). Include the
103 | following line to declare the path to your Android SDK. Change accordingly to
104 | where the SDK is installed on your system.
105 |
106 | ```
107 | sdk.dir=/home/user/Android/Sdk
108 | ```
109 |
110 | ## AndroidManifest.xml changes
111 |
112 | You will need to include the appropriate PE for Android library within your app's manifest. The library you include will vary
113 | depending on if you are creating a PE for Android App, a Policy Manager, or a uPAL
114 |
115 | | Project Type | Library |
116 | |--------------------|-------------------------------------------|
117 | | PE for Android App | `com.twosixlabs.peandroid` |
118 | | Policy Manager | `com.twosixlabs.peandroid.privacymanager` |
119 | | uPAL | `com.twosixlabs.peandroid.pal` |
120 |
121 | The necessary library can be included by adding a `uses-library` line to the `` tag of your apps manifest.
122 |
123 | ```xml
124 |
125 | ```
126 |
127 | ## Enabling inline Javadocs and code autocomplete
128 |
129 | The PE for Android SDK addons come with Javadocs-style inline documentation. The
130 | following steps will enable Android Studio to show this documentation in the
131 | editor:
132 |
133 | 1. In the 'Project' pane on the left of Android Studio, switch the view to
134 | **'Project'**
135 | 2. Expand **Exeternal Libraries** and right click on the library you would
136 | like to add JavaDocs for
137 | 1. This will correspond to the library you specified in your
138 | AndroidManifest.xml (i.e. **privacymanager-android-28**)
139 | 3. Click on **'Library Properties'**
140 | 4. Click the **'+'** button to open a file browser dialog
141 | 1. It should open to the **'libs'** directory of the SDK Addon
142 | 5. Expand the **'docs'** directory and select the documentation
143 | directory for the library you are using.
144 | 6. Android Studio should detect these as JavaDocs, and you can select "OK"
145 |
146 | After completing this process you should now be able to launch **'Quick
147 | Documentation'** or **'External Documentation'** through Android Studio's
148 | shortcuts or by clicking on **View->Quick Documentation**
149 |
150 | To enable proper autocomplete features in Android Studio, you will also need
151 | to add the peandroid stubbed source files. Enabling this is essentially the
152 | same as enabling JavaDocs.
153 |
154 | 1. Like before, open **'Library Properties'** for the specified library.
155 | 2. Click the **'+'** button to open a file browser dialog
156 | 3. Expand the **'src'** dialog, and select the proper .jar file for your
157 | library (i.e. **privacymanager.jar**)
158 | 4. Android Studio should detect these as Sources, and you can select "OK"
159 |
160 | The latest version of standalone Javadocs may be found on the PE for Android webpage [here](https://android-privacy.org/#documentation)
--------------------------------------------------------------------------------
/howto/apps/sdk.md:
--------------------------------------------------------------------------------
1 | # How-to: install the SDK addons
2 |
3 | ## Overview
4 |
5 | These instructions show how to install the SDK addons in Android Studio.
6 | Specific usage instructions are detailed in the individual how-to's for
7 | developing [apps that use the Private Data Service](apps.md), [Policy
8 | Managers](policy.md), and [uPAL modules](upal.md).
9 |
10 | ## Installing the SDK addons
11 |
12 | We offer precompiled SDK addons that can be installed using Android Studio's
13 | built-in SDK manager.
14 |
15 | 1. Open any Android Studio project.
16 | 2. Open the "Tools" menu and select the "SDK Manager" tab
17 | 3. Click the "SDK Update Sites" tab
18 | 4. On the right side of the window, click the `+` button to add a site
19 | 5. Enter the following details:
20 |
21 | ```
22 | Name: PE for Android SDK Addons
23 | URL: https://raw.githubusercontent.com/twosixlabs/PE_for_Android/master/addon.xml
24 | ```
25 |
26 | 
27 |
28 | 6. After adding the site, enable it by checking the box
29 | 7. Click "OK" in the SDK Manager to accept this new site
30 | 8. Open the SDK manager again and wait for the "SDK Platforms" tab to populate
31 | 9. Check the box for "Show Package Details"
32 | 10. Expand the options under "Android 9.0 (Pie)" and ensure that PE for
33 | Android, Android SDK Platform 28, and Sources for Android 28 are enabled as shown:
34 |
35 | 
36 |
37 | 11. Click "OK" in the SDK Manager to accept these SDK options
38 |
39 | ### Custom SDK addons
40 |
41 | If you compiled your own version of PE for Android, you can generate
42 | corresponding SDK addons that capture any API changes you may have implemented.
43 | See the [build instructions](../platform/platform.md) for details about
44 | packaging your own SDK addons. To install custom versions of the SDK addons in
45 | Android Studio, simply change the URL in step 5 above to point to local file
46 | path of the generated `addon.xml`.
47 |
48 |
--------------------------------------------------------------------------------
/howto/apps/upal.md:
--------------------------------------------------------------------------------
1 | # How-to: develop uPAL modules
2 |
3 | * [Overview](#overview)
4 | * [Example uPAL](#example-upal)
5 | * [Extending the base class](#extending-the-base-class)
6 | + [Declaring the constructor](#declaring-the-constructor)
7 | + [Implementing the abstract methods](#implementing-the-abstract-methods)
8 | * [Registering the uPAL](#registering-the-upal)
9 | * [Recommended practices](#recommended-practices)
10 |
11 | ## Overview
12 |
13 | PE for Android allows apps to access sensitive data via the [Private Data
14 | Service](apps.md), in lieu of standard Android APIs like `LocationManager` and
15 | `ContactsContract`. Full-resolution data (e.g., GPS coordinates, whole contact
16 | lists) stays entirely within the Private Data Service, which uses uPAL modules
17 | ("micro-Privacy Abstraction Layer modules") to reduce the resolution of that
18 | information down to just what the app needs.
19 |
20 | Developers can implement their own uPAL modules and distribute them as
21 | modular transformations, reusable in any app that interfaces with the Private
22 | Data Service.
23 |
24 | As an example demonstrating the development of uPALs, this guide steps through a uPAL
25 | that receives contact list data from the system and a known phone number from the
26 | calling app. The uPAL then returns the name associated with that phone number, if
27 | available from the contact list. The requesting app only receives this result,
28 | without gaining access to the entire contact list.
29 |
30 | ## Example uPAL
31 |
32 | ```java
33 | public class NumberToNamePAL extends MicroPALProviderService> {
34 | private static final String TAG = NumberToNamePAL.class.getSimpleName();
35 | private static final String DESCRIPTION = "Get the matching name from the contact list given a known phone number";
36 |
37 | public static final String PHONE_KEY = "phone";
38 | public static final String NAME_KEY = "name";
39 |
40 | public NumberToNamePAL() {
41 | super(DataRequest.DataType.CONTACTS);
42 | }
43 |
44 | @Override
45 | public Bundle onReceive(ListItem contactItemList, Bundle paramsFromApp) {
46 | if(paramsFromApp.containsKey(PHONE_KEY)) {
47 | String inputPhoneNumber = normalizePhoneNumber(paramsFromApp.getString(PHONE_KEY));
48 | Log.i(TAG, "Checking for phone number " + inputPhoneNumber);
49 |
50 | for(ContactItem contact : contactItemList.getStoredItems()) {
51 | // Contacts could have more than one phone number
52 | ArrayList phoneNumbers = contact.getPhoneNumbers();
53 | for(String phoneNumber : phoneNumbers) {
54 | String contactPhoneNumber = normalizePhoneNumber(phoneNumber);
55 |
56 | if(inputPhoneNumber.equals(contactPhoneNumber)) {
57 | String name = contact.getName();
58 | Log.i(TAG, "Found name " + name + " corresponding to phone number " + inputPhoneNumber);
59 |
60 | Bundle result = new Bundle();
61 | result.putString(PHONE_KEY, inputPhoneNumber);
62 | result.putString(NAME_KEY, name);
63 |
64 | return result;
65 | }
66 | }
67 | }
68 |
69 | Log.w(TAG, "No contact name found for " + inputPhoneNumber);
70 |
71 | } else {
72 | Log.e(TAG, String.format("Need to provide an input bundle with key '%s' corresponding to the phone number", PHONE_KEY));
73 | }
74 |
75 | return null;
76 | }
77 |
78 | @Override
79 | public String getDescription() {
80 | return DESCRIPTION;
81 | }
82 |
83 | /**
84 | *
85 | * @param phoneNumber
86 | * @return The phone number only containing numerics; all other symbols are stripped out
87 | */
88 | private String normalizePhoneNumber(String phoneNumber) {
89 | return phoneNumber.replaceAll("\\D+", "");
90 | }
91 | }
92 | ```
93 |
94 | ## Extending the base class
95 |
96 | All uPALs must extend the `MicroPALProviderService` base class and declare the
97 | type of system API data they expect to receive.
98 |
99 | ```java
100 | public class NumberToNamePAL extends MicroPALProviderService> {
101 | // ...
102 | }
103 |
104 | ```
105 |
106 | The parameterized type must be an `Item` or any class derived from it. The following
107 | `Item` types are available:
108 |
109 | | Item type | DataRequest.DataType type | Notes
110 | | ------------------------------------- | --------------------------------- | --------------------------------------------------------------------- |
111 | | Item | ANY | uPAL will operate on any Item-derived data type |
112 | | EmptyItem | EMPTY | uPAL will ignore the Item and only operate on the PAL params Bundle |
113 | | ListItem\ | CALL\_LOGS | List of incoming and outgoing calls |
114 | | ListItem\ | CONTACTS | Full contact list |
115 | | ListItem\ | CALENDAR | List of calendar events within a given time |
116 | | ListItem\ | SMS | List of incoming and outgoing SMS within given time. See note below |
117 | | LocationItem | LOCATION | Latitude/longitude data |
118 | | DeviceStateItem | PHONE\_STATE | Information about the phone |
119 |
120 | **Note**: The current implementation only operates on text-only messages
121 | between individual contacts. Group SMS and MMS are unsupported.
122 |
123 | ### Declaring the constructor
124 |
125 | The uPAL's constructor must declare the matching `DataRequest.DataType` and
126 | pass it up to the superclass.
127 |
128 | ```java
129 | public NumberToNamePAL() {
130 | super(DataRequest.DataType.CONTACTS);
131 | }
132 | ```
133 |
134 | ### Implementing the abstract methods
135 |
136 | uPALs must implement two abstract methods from the superclass: `onReceive()` and
137 | `getDescription`.
138 |
139 | #### onReceive()
140 |
141 | ```java
142 | public Bundle onReceive(ListItem contactItemList, Bundle paramsFromApp) {
143 | // ...
144 | }
145 | ```
146 |
147 | This method transforms sensitive data as received from system API calls (i.e.,
148 | the `Item`-typed first parameter) and given by the app (i.e., the `Bundle`-typed
149 | second parameter). You may choose to ignore either one or both of these parameters
150 | in your uPAL transformation.
151 |
152 | The result of this method is sent back to the calling app. Returning `null` will
153 | indicate to the calling app that a failure occurred.
154 |
155 | #### getDescription()
156 |
157 | ```java
158 | public String getDescription() {
159 | return DESCRIPTION;
160 | }
161 | ```
162 |
163 | This method defines a human-readable description of the uPAL.
164 |
165 | ## Registering the uPAL
166 |
167 | uPALs must declare their ability to listen for data transformation requests from
168 | the Private Data Service. Ensure that the uPAL's core service has has the
169 | `android.permission.PRIVATE_DATA_PROVIDER_SERVICE` permission and the
170 | `android.privatedata.MicroPALProviderService` intent filter in the app's
171 | manifest.
172 |
173 | ```xml
174 |
178 |
179 |
180 |
181 |
182 | ```
183 |
184 | ## Recommended practices
185 |
186 | Although uPALs are executed asynchronously, they're meant to be lightweight
187 | functions that [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy).
188 | uPAL developers should try to abide by the following practices to ensure
189 | their transformations follow this design goal.
190 |
191 | * uPALs should be stateless. Any state should be maintained by the calling app
192 | and passed back to the uPAL using the params `Bundle` in subsequent calls.
193 | * uPALs should avoid I/O operations such as disk and network functions. I/O
194 | is relatively slow and can be unreliable, leading to uPALs that potentially
195 | don't terminate.
196 | * A single APK can hold many distinct independent uPALs. Split up disparate
197 | loosely-related transformations into individual uPAL services.
198 |
199 |
200 |
--------------------------------------------------------------------------------
/howto/phone/installation.md:
--------------------------------------------------------------------------------
1 | # How-to: Install PE for Android on a phone
2 |
3 | * [Overview](#overview)
4 | * [Initial device preparation](#initial-device-preparation)
5 | + [Unlocking the bootloader](#unlocking-the-bootloader)
6 | + [Flashing the correct base Android version](#flashing-the-correct-base-android-version)
7 | * [Flashing PE for Android](#flashing-pe-for-android)
8 | * [Google Play installation](#google-play-installation)
9 | + [Installing Open GApps](#installing-open-gapps)
10 | + [Register custom ROM with Google Play Services](#register-custom-rom-with-google-play-services)
11 |
12 | ## Overview
13 |
14 | PE for Android was forked from AOSP's [Generic System Images
15 | (GSI)](https://developer.android.com/topic/generic-system-image) for Android Pie and should be
16 | compatible with any [Project Treble-compliant
17 | device](https://play.google.com/store/apps/details?id=com.kevintresuelo.treble&hl=en_US) that meet
18 | [these requirements](https://source.android.com/setup/build/gsi#flashing-gsis). Through our
19 | development we have tested PE for Android with the Pixel 2XL and Pixel 3aXL, although other
20 | Pixel devices should behave similarly to those. Below is a table of Google Pixel devices
21 | and the corresponding images that should be compatible with the phone. The images for the various
22 | types of GSI builds are available [here](https://github.com/twosixlabs/PE_for_Android/releases).
23 |
24 |
25 | | Device | Codename | GSI Image Type |
26 | |--------|----------|----------------|
27 | | Pixel 2 | walleye | gsi_ab |
28 | | Pixel 2XL | taimen | gsi_ab |
29 | | Pixel 3 | blueline | gsi|
30 | |Pixel 3XL | crosshatch | gsi |
31 | |Pixel 3a | sargo | gsi |
32 | |Pixel 3aXL | bonito | gsi |
33 |
34 |
35 | While we have only tested on Pixel devices, installing PE for Android on other GSI-compatible
36 | devices will take similar steps to these specified here. Please refer to the [official GSI
37 | documentation](https://source.android.com/setup/build/gsi) for more information on GSI's
38 | in general. Additionally, the [XDA Developer forums](https://forum.xda-developers.com/)
39 | contain a wealth of information that may be useful in flashing the PE for Android GSI
40 | to your phone.
41 |
42 |
43 | These instructions assume familiarity with the command line and that the
44 | Android command-line tools (e.g., _adb_ and _fastboot_) are already installed
45 | on your system. These tools are part of Android Studio but may also be
46 | installed separately. This software is available for download on the [Android
47 | Studio downloads page](https://developer.android.com/studio/#downloads).
48 |
49 | ## Initial device preparation
50 |
51 | These steps are only necessary for bootloader-locked devices running stock
52 | Android. If your device's bootloader is already unlocked, you may skip that
53 | process. Likewise, if your bootloader-unlocked device is already running an
54 | appropriate version of Android, you may skip this section altogether.
55 |
56 | ### Unlocking the bootloader
57 |
58 | Unlocking the bootloader allows users to manipulate the device's partitions and
59 | install new system images, including PE for Android GSI images. While each device
60 | may have different steps below is a link to the process to unlock Google Devices.
61 | Again, if you do not have a Google device it is best to refer to the
62 | [XDA Developer forums](https://forum.xda-developers.com/) to see if and how your
63 | device bootloader may be unlocked.
64 |
65 | **WARNING**: The process of unlocking the bootloader will factory-reset your
66 | device. Please ensure you have a backup of your data before proceeding.
67 |
68 | * [Unlocking the Bootloader on Google Devices](https://source.android.com/setup/build/running#unlocking-the-bootloader)
69 |
70 | **NOTE**: Unlocking the bootloader will cause the device to display a boot
71 | warning that reads "The bootloader is unlocked and software integrity
72 | cannot be guaranteed." You may ignore this message.
73 |
74 | ### Flashing the correct base Android version
75 |
76 | For flashing GSIs we have discovered some nuances to both installing on the Pixel 3aXL,
77 | as well as the 2XL.
78 |
79 | We have found the for the Pixel 3aXL, you must start from a stock
80 | Android 9 base image to ensure the appropriate vendor binaries are on the device
81 | to allow the various hw components to work. We have not found a method for installing the
82 | the PE for Android GSI over a stock Android 10 Pixel 3aXL.
83 |
84 | For the Pixel 2XL, we have discovered only a specific version of stock firmware that
85 | allows for a clean boot. If flashing for the Pixel 2XL, please first flash the
86 | [PQ3A.190605.003, Jun 2019](https://dl.google.com/dl/android/aosp/taimen-pq3a.190605.003-factory-59303ad9.zip)
87 | build.
88 |
89 | For flashing instructions and stock images for Pixel devices, please refer to Google's
90 | website.
91 |
92 | [Pixel Factory Images](https://developers.google.com/android/images)
93 |
94 |
95 | ## Flashing PE for Android
96 |
97 | After following the above instructions to [prepare a new
98 | device](#initial-device-preparation), the device will be ready to install PE
99 | for Android.
100 |
101 | 1. Download *vbmeta.img* and *system.img* for the appropriate PE for Android
102 | release available
103 | [here](https://github.com/twosixlabs/PE_for_Android/releases). Alternatively,
104 | these files may be generated by [building PE for Android from
105 | source](https://github.com/twosixlabs/PE_for_Android/blob/master/howto/platform/platform.md).
106 | 2. Connect the device to your computer via USB
107 | 2. Boot into the bootloader with `adb reboot bootloader`
108 | 3. Run the following commands to install the downloaded *.img* files:
109 |
110 | ```
111 | $ fastboot --disable-verification flash vbmeta vbmeta.img
112 | $ fastboot erase system
113 | $ fastboot flash system system.img
114 | $ fastboot -w
115 | $ fastboot reboot
116 | ```
117 |
118 | ## Google Play Installation
119 |
120 | PE for Android does not come with proprietary Google apps (e.g., Google Maps,
121 | Play Store, Gmail, etc.) commonly found on most Android phones. These must
122 | be installed separately after flashing PE for Android. This is commonly achieved
123 | through a custom device recovery and appropriate download from OpenGapps
124 |
125 | ### Installing Open Gapps
126 |
127 | To install OpenGapps, the TWRP custom recovery is commonly used and generally
128 | widely supported for various devices. The TWRP custom recovery allows the user
129 | to install packages (such as Google apps) to the normally write-protected system
130 | partition. The following instructions show how to boot to TWRP and install OpenGapps.
131 |
132 | PE for Android increased the system partition size to more easily allow for
133 | the installation of OpenGapps. However, this increase is only suitable for installing
134 | the *pico* variant for Android 9.0 on ARM64 found [here](https://opengapps.org/).
135 |
136 | **Note:** If the device already has TWRP, you may skip to step ***#5*** in instructions and
137 | continue installing the Open GApps package.
138 |
139 | 1. Download the latest version of TWRP for your device from
140 | [TWRP's webpage](https://twrp.me/Devices/). You will only need the *img* file, unless you want to permanently install TWRP.
141 | 2. Download Open GApps (*pico* variant) for Android 9.0 on ARM64 [here](https://opengapps.org/)
142 | 3. Enter fastboot mode on your phone either by key combination or `adb reboot bootloader` if your phone is powered on
143 | 4. Temporarily boot into TWRP with `fastboot boot twrp--a.b.c-d.img`
144 | 5. When TWRP boots up, run `*adb push open_gapps-arm64-9.0-pico-yyyymmdd.zip /sdcard/*`
145 | 6. Select "Install" and navigate to /sdcard and select '*open_gapps-arm64-9.0-pico-yyyymmdd.zip*'
146 | 7. Activate the slider to install Open GApps
147 | 9. When finished, reboot the device back to the home screen
148 |
149 | **NOTE**: If the screen is unresponsive in step 5, try issuing the following
150 | commands from the shell:
151 |
152 | ```shell
153 | $ adb shell
154 | $ twrp install /sdcard/open_gapps-arm64-9.0-pico-yyyymmdd.zip
155 | $ reboot
156 | ```
157 |
158 | If you re-flash *system.img* on the device (i.e., update to a newer
159 | version of PE for Android), you will need to follow the [Installing Open GApps](#installing-open-gapps)
160 | steps again. Failing to re-install Open GApps will result in Google Play
161 | Services constantly crashing.
162 |
163 | ### Register custom ROM with Google Play Services
164 |
165 | The phone will have a constant stream of notifications saying the device is not
166 | compliant with Google policies. Tapping on the notification will take you to a
167 | URL that's hard to read on the phone. Go
168 | [here](https://g.co/AndroidDeviceRegistration) to register the phone.
169 |
170 | The commands on the page generate a long number to paste into the page and
171 | click Register. Once you've done that, reboot the phone.
172 |
173 | Within a couple of minutes, the Play Protect messages should stop and you will
174 | see ones related to updating Play Services and app update availability in the
175 | Play Store.
176 |
177 |
--------------------------------------------------------------------------------
/howto/platform/platform.md:
--------------------------------------------------------------------------------
1 | # How-to: build the PE for Android platform
2 |
3 | * [Overview](#overview)
4 | * [Initializing the source tree](#initializing-the-source-tree)
5 | * [Docker environment initialization](#docker-environment-initialization)
6 | * [Using Docker to build PE for Android](#using-docker-to-build-pe-for-android)
7 |
8 | ## Overview
9 |
10 | PE for Android is an open-source fork of the Android Open Source Project
11 | release for Android 9 (Pie). While the its Policy Manager and uPAL paradigms
12 | offer much flexibility in implementing privacy-enhancing concepts as user-space
13 | apps, we understand that there could be use cases where the platform still
14 | needs to be modified. We invite other developers and researchers to extend PE
15 | for Android for their own needs. This is a guide for how to clone and build
16 | PE for Android from source.
17 |
18 | These instructions assume familiarity with the Linux shell, the AOSP code
19 | structure, and that Docker and [Google's `repo`
20 | tool](https://source.android.com/setup/build/downloading#installing-repo) are
21 | already installed on the system. For minimal complications, we recommend
22 | building PE for Android on a 64-bit Linux system with at least 750 GBs of free
23 | disk space. Additional CPU cores, memory, and solid-state storage will speed up
24 | the compilation process.
25 |
26 | ## Initializing the source tree
27 |
28 | The AOSP source tree is organized as a collection of [several hundred Git
29 | repositories](https://android-review.googlesource.com/admin/repos), each
30 | corresponding to a particular directory in the tree. Developers use the `repo`
31 | tool to manage these Git repositories and perform batch operations on them.
32 | Different AOSP builds exist for each target device. To simplify management of
33 | all the component Git repositories, each target device has a `manifest.xml`
34 | file that defines particular repositories and branches needed to build AOSP for
35 | that target.
36 |
37 | For PE for Android, we use the Generic System Image (GSI) target for Android 9
38 | ("Pie"). The following commands will initialize the metadata for this target.
39 |
40 | ```shell
41 | > mkdir $PE_ANDROID_ROOT
42 | > cd $PE_ANDROID_ROOT
43 | > repo init -u https://android.googlesource.com/platform/manifest -b pie-gsi
44 | ```
45 |
46 | After initializing the for metadata for Android 9, we include the
47 | `local_manifests` metadata that points to the code specific to PE for Android.
48 |
49 | ```shell
50 | > cd .repo
51 | > git clone https://github.com/twosixlabs/pea_local_manifests.git local_manifests
52 | > cd ..
53 | ```
54 |
55 | With all the metadata in place, we can download the specified source files. Note that
56 | this step may take many minutes or hours, depending on your Internet connection.
57 |
58 | ```shell
59 | > repo sync -c -j8
60 | ```
61 | **FOR TEAMS**: These commands will download the AOSP source from Google's
62 | servers. These servers have rate-limiting restrictions. If multiple team members
63 | are cloning the source tree simultaneously, the rate-limiting will likely
64 | trigger and cause errors in the cloning process. In order to mitigate this,
65 | teams may wish to [set up a local mirror](https://source.android.com/setup/build/downloading#using-a-local-mirror)
66 | so files are cloned from Google's servers only once. Developers subsequently
67 | clone from the local mirror, and thus are not subject to rate-limiting. If
68 | cloning from a local mirror, ensure that the `repo init` command above is
69 | pointing to the mirror's manifest.
70 |
71 | ## Docker environment initialization
72 |
73 | For convenience, we offer a Docker container preconfigured with all the
74 | dependencies settings needed to build PE for Android. The following commands
75 | will initialize the Docker container and launch it. These commands should
76 | be done in a path *outside* the `$PE_ANDROID_ROOT` directory used in the
77 | previous section.
78 |
79 | ```shell
80 | > mkdir $PE_ANDROID_DOCKER
81 | > cd $PE_ANDROID_DOCKER
82 | > curl https://raw.githubusercontent.com/twosixlabs/PE_for_Android_dockerfile/master/Dockerfile > Dockerfile
83 | > sudo docker build --no-cache -t peandroid:pie ./
84 | ```
85 |
86 | ## Using Docker to build PE for Android
87 |
88 | After Docker builds the image for the environment, the following commands will
89 | start an interactive session in a new Docker container. Let `$PE_ANDROID_ROOT`
90 | be the path to your PE for Android source tree, defined earlier.
91 |
92 | ```shell
93 | > cd $PE_ANDROID_DOCKER
94 | > sudo docker run -v $PE_ANDROID_ROOT:/src/ -w /src -it --rm peandroid:pie
95 | ```
96 | This maps `$PE_ANDROID_ROOT` to the Docker container's `/src` directory
97 | and launches the container. From `/src` there are three shell scripts
98 | to build different variants of PE for Android:
99 |
100 | * `make_gsi.sh`: Builds a GSI
101 | * `make_gsi_a.sh`: Builds a GSI for legacy A-partition devices
102 | * `make_gsi_ab.sh`: Builds a GSI for legacy AB-partition devices
103 | * `make_peandroid.sh`: Builds the SDK addons and emulator image
104 |
105 | These scripts save their terminal outputs to `build_gsi.log`, `build_gsi_a.log`,
106 | `build_gsi_ab.log`, and `addons.log`.
107 |
108 | System image files are saved under
109 | `$PE_ANDROID_ROOT/out/target/product/generic_arm64`, `$PE_ANDROID_ROOT/out/target/product/generic_arm64_a`, and `$PE_ANDROID_ROOT/out/target/product/generic_arm64_ab` for `make_gsi.sh`, `make_gsi_a.sh`, and`make_gsi_ab.sh`, respectively.
110 |
111 | `make_peandroid.sh` saves the SDK addons under
112 | `$PE_ANDROID_ROOT/out/host/linux-x86/sdk_addon/`. Despite the path name, SDK
113 | addons are platform-agnostic and should work with Linux, Windows, and Mac
114 | versions of Android Studio alike. Emulator can be found under
115 | `$PE_ANDROID_ROOT/out/target/product/generic_x86_64/`.
116 |
117 |
--------------------------------------------------------------------------------