Merge branch 'master' into 'master'
[bitmask_android.git] / README.md
1 # Bitmask Android Client
2
3 This repository contains the source code for the [Bitmask](https://bitmask.net/) Android client. Bitmask Android offers one-click free VPN service from trusted providers of the LEAP stack.
4
5 To learn about the stack, visit [leap.se](https://leap.se).
6
7 Please see the [issues](https://0xacab.org/leap/bitmask_android/issues) section to report any bugs or feature requests, and to see the list of known issues.
8
9 # Table Of Contents
10
11 * [License](#license)
12 * [Installing](#installing)
13   * [JDK](#jdk)
14   * [C Libraries](#c-libraries)
15   * [Android SDK](#android-sdk)
16     * [With Android Studio](#with-android-studio)
17     * [With Bash](#with-bash)
18     * [Updating Your PATH](#updating-your-path)
19     * [With Docker](#with-docker)
20   * [Submodules](#submodules)
21 * [Compiling](#compiling)
22   * [Just Build It!](#just-build-it)
23   * [Debug APKs](#debug-apks)
24   * [Release APKs](#release-apks)
25   * [Signed Release APKs](#signed-release-apks)
26 * [Running Tests](#running-tests)
27 * [Debugging in an Emulator](#debugging-in-an-emulator)
28   * [From Android Studio](#from-android-studio)
29   * [From The Shell](#from-the-shell)
30   * [Debian Gotchas](#debian-gotchas)
31     * [Virtualization Not Enabled](#virtualization-not-enabled)
32     * [Unpatched Filepaths Bug](#unpatched-filepaths-bug)
33     * [Outdated GL Libraries](#outdated-gl-libraries)
34 * [Updating Submodules](#updating-submodules)
35 * [Acknowledgments](#acknowledgments)
36 * [Contributing](#contributing)
37
38 ## License <a name="license"></a>
39
40 * [See LICENSE file](https://github.com/leapcode/bitmask_android/blob/master/LICENSE.txt)
41
42
43 ## Installing <a name="installing"></a>
44
45 We will assume for convenience that you are installing on a Debian- or Ubuntu-based GNU/Linux machine. (Patches welcome with instructions for Mac, Windows, or other GNU/Linux distributions!)
46
47 The Bitmask Android Client has the following system-level dependencies:
48
49 * JDK v. 1.8
50 * Assorted 32-bit C libraries
51 * Android SDK Tools, v. 27.0.3, with these packages:
52   * Platform-Tools, v. 27.0.3
53   * Build-Tools, API v. 23-27
54   * Platforms 23-27
55   * Android Support Repository
56   * Google Support Repository
57   * NDK v. r16b (enables C code in Android)
58 * For running the app in an emulator, you will also need these packages:
59   * Android Emulator
60   * System Images for Android APIs 23-27
61 * The ICS-OpenVpn submodule
62
63 You can install them as follows:
64
65 ### JDK <a name="jdk"></a>
66
67 Install with:
68
69 ```bash
70 sudo apt install default-jdk
71 ```
72
73 ### C Libraries <a name="c-libraries"></a>
74
75 These are necessary to make sure the program cross-compiles to 32-bit architectures successfully from 64-bit GNU/Linux machines:
76
77 ```
78 sudo apt install make gcc file install lib32stdc++ lib32z1
79 ```
80
81 ### Android SDK <a name="android-sdk"></a>
82
83 #### With Android Studio <a name="with-android-studio"></a>
84
85 All of the Android SDK and NDK packages are downloadable through Android Studio, which (sadly) is probably the most hassle-free way to go about things.
86
87 You can download Android studio here:
88
89 https://developer.android.com/studio/index.html
90
91 Once you've got it installed, use the `SDK Manager` tool (Android figure Icon with blue arrow second from the right in the tool pane) to download all the Android SDK and NDK depencencies listed above.
92
93 #### With Bash <a name="with-bash"></a>
94
95 Alternatively (eg: for build machines), you may download and unzip the `android-sdk` bundle from Google as follows (assuming an install location of `/opt/android-sdk-linux`:
96
97 ```
98 curl -L https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip -o sdk-tools.zip  \
99     && unzip -q sdk-tools.zip -d /opt/android-sdk-linux \
100     && rm -f sdk-tools.zip
101 ```
102
103 To download the NDK (for cross-compiling and running the C code used in `ics-openvpn`), use:
104
105 ```
106 curl -L http://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip -o ndk.zip  \
107     && unzip ndk.zip -d /opt/android-sdk-linux/android-ndk-r16b \
108     && rm -rf ndk.zip
109 ```
110
111 After updating your PATH (see next step), you may now use the `sdkmanager` tool bundled with `android-sdk` to browse and install new sdk packages from Google.
112
113 To browse all available packages, run:
114
115 ```shell
116 sdkmanager --list
117 ```
118
119 To search for available packages of a certain type (eg: `tools`), run:
120
121 ```shell
122 sdkmanager --list | grep tools
123 ```
124
125 To install all of the dependencies listed above (targetting SDK versions 23 - 26), run:
126
127 ```shell
128 sdkmanager tools
129 sdkmanager platform-tools
130 sdkmanager extras;android;m2repository
131 sdkmanager extras;google;m2repository
132 sdkmanager build-tools;27.0.3
133 sdkmanager build-tools;25.0.2
134 sdkmanager build-tools;23.0.3
135 sdkmanager platforms;android-27
136 sdkmanager platforms;android-25
137 sdkmanager platforms;android-23
138 ```
139
140 #### Updating Your Path <a name="updating-your-path"></a>
141
142 Once you've installed Android SDK & NDK packages, you need to modify your PATH so you can invoke all the programs you just installed. You can do that with something like the following in your `~/.shellrc` or `~/.bash_profile`:
143
144 ```shell
145 export ANDROID_HOME=<path/where/you/installed/android/sdk>
146 export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
147 export PATH=$ANDROID_NDK_HOME:$PATH
148 export PATH=$ANDROID_HOME/platform-tools:$PATH
149 export PATH=$ANDROID_HOME/tools/bin:$PATH
150 ```
151
152 NOTE: On GNU/Linux machines, Android Studio installs the Android SDK in `~/Android/Sdk/`. Our dockerfile installs it in `/opt/android-sdk-linux`. You can install it wherever you want! Just be sure to remember where so you can add it to your PATH! :)
153
154 #### With Docker <a name="with-docker"></a>
155
156 Geesh! If all that above seems like a lot, it is!
157
158 To keep ourselves from messing it up all the time everyone someone new joins the project, we made a Dockerfile that creates the above environment with one line. You can pull the image and run builds from inside it, or consult the [Dockerfile](/docker/android-sdk.dockerfile) itself for requirements that your system might need but be missing.
159
160 Assuming you've already [installed docker](https://docs.docker.com/engine/installation/), you can pull the image with:
161
162 ``` shell
163 docker pull 0xacab.org:4567/leap/bitmask_android/android-ndk:latest
164 ```
165
166 Run the image with:
167
168 ``` shell
169 docker run --rm -it 0xacab.org:4567/leap/bitmask_android/android-ndk:latest
170 ```
171 More likely than not, you'll want to run the image with the source code mounted. You can do that with:
172
173 ``` shell
174 cd <path/to/bitmask_android>
175 docker run --rm -it -v`pwd`:/bitmask_android -t 0xacab.org:4567/leap/bitmask_android/android-ndk:latest
176 ```
177
178
179 ### Submodules <a name="submodules"></a>
180
181 We depend on [ics-openvpn](https://github.com/schwabe/ics-openvpn) as an interface to Android's OpenVPN implementation. We include it as a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) in our project, which requires that we initialize and update it (and its respective upstream submodule dependencies) in order to compile and run Bitmask Android.
182
183 We do so with:
184
185 ```bash
186 cd <path/to/bitmask_android>
187 git submodule init
188 git submodule update --init --recursive
189 ```
190
191 ## Compiling <a name="compiling"></a>
192
193 You have lots of options for compiling, all of which will output Android-executable `apk` packages to `/bitmask_android/app/build/outputs/apk/`.
194
195 ### Just Build It! <a name="just-build-it"></a>
196
197 If you compile the project for the first time you'll have to compile the dependencies. This can be done with:
198
199 ```
200 ./build_deps.sh
201 ```
202 This command will create all libs we need for Bitmask.
203  
204 If you want to to have a clean build of all submodules run
205 ```
206 ./cleanProject.sh
207 ```
208 before you call `./build_deps.sh`. That script removes all build files and does the git submodule init and update job for you.  
209
210 You are then welcome to run:
211
212 ```
213 ./gradlew build
214 ```
215
216 This will compile the code and run the tests, but not output any `apk` packages. As such, it's not all that useful. :)
217
218 ### Debug APKs <a name="debug-apks"></a>
219
220 To assemble debug packages for running locally or testing in CI, run:
221
222 ```bash
223 ./build_deps.sh
224 ./gradlew assembleDebug
225 ```
226
227 This will output `app-insecure-debug.apk` and `app-production-debug.apk` to `/bitmask_android/app/build/outputs/apk/`.
228
229 ### Release APKs <a name="release-apks"></a>
230
231 To assemble release packages, run:
232
233 ```bash
234 ./build_deps.sh
235 ./gradlew assembleRelease
236 ```
237
238 This will output `app-insecure-release.apk` and `app-production-release.apk` to `/bitmask_android/app/build/outputs/apk/`.
239
240 ### Signed Release APKs <a name="signed-release-apks"></a>
241
242 If you want to release a signed APK (which you *must* do to publish the app to the Google Play store), you'll have to create a gradle.properties file in the project root with the following structure:
243
244 ```properties
245 storeFileProperty=<fullPath>
246 storePasswordProperty=<store password without quotation marks>
247 keyAliasProperty=<key alias without quotation marks>
248 keyPasswordProperty=<key password without quotation marks>
249 ```
250
251 ### Building In Docker <a name="building-in-docker"></a>
252
253 If you want to make sure the environment you use to build APKs matches exactly the environment that Gitlab will use to build and publish artifacts, you can run any of the above build commands from inside Docker. To assemble a release build this way, run the following commands:
254
255 ``` shell
256 $ cd <path/to/bitmask_android>
257 $ sudo docker run --rm -it -v `pwd`:/bitmask_android 0xacab.org:4567/leap/bitmask_android/android-ndk:latest
258 # cd /bitmask_android
259 # ./cleanProject.sh
260 # ./build_deps.sh
261 # ./gradlew assembleRelease
262 ```
263
264 ## Running Tests <a name="running-tests"></a>
265
266 To run the automated tests:
267
268    1. Run an emulator
269    2. Unlock Android
270    3. Issue the command ./gradlew connectedCheck
271    4. Pay attention and check the "Trust this app" checkbox, if you don't do so tests won't run.
272
273
274 ## Debugging in an Emulator <a name="debugging-in-an-emulator"></a>
275
276 You can run the app in an emulator running any version of Android and simulating (almost) any device. To run it you'll have to create an emulator, run the emulator, and then load an assembled APK of the app onto the emulator. (You can then use all sort of nifty tools in [Anroid Debug Bridge](https://developer.android.com/studio/command-line/adb.html) to tail the logs and debug the app.)
277
278 Assuming you've already tackled (or don't need to tackle) the [Debian Gotchas](#debian-gotchas) listed below, you can do that using either Android Studio or a bash shell as follows:
279
280 ### From Android Studio <a name="from-android-studio"></a>
281
282 To create an emulator:
283
284 * Select `Tools/Android/AVD Manager` from the application menu
285 * Follow the instructions
286
287 To run a pre-existing emulator:
288
289 * Open the `AVD Manager` as above
290 * Press the "Play" button next to the emulator you want to run
291
292 To run the app:
293
294 * Ensure you have an emulator running
295 * Open the left-hand project pane (Meta-1 or Cmd-1, depending on your keybindings)
296 * Navigate to `bitmask_android/app/src/main/java/se/leap/bitmaskclient/StartActivity`
297 * Right-click over the `StartActivity` filename and click the `Run 'StartActivity'` option (or use Shift-Ctl-F10 or Shift-Ctl-R, depending on your keybindings)
298 * After you have done this once, you should be able to simply select `StartActivity` from the dropdown menu next to the big green arrow in the toolbar, then click the green arrow to run the app.
299
300 ### From the Shell <a name="from-the-shell"></a>
301
302 To list the available avd images for creating an emulator:
303
304 ``` shell
305 avdmanager list
306 ```
307
308 To create an emulator:
309
310 ``` shell
311 avdmanager create avd
312 ```
313
314 To list the emulators you have already created:
315
316 ``` shell
317 avdmanager list avd
318 ```
319
320 To run a pre-existing emulator called `Nexus_5_API_25`:
321
322 ``` shell
323 emulator @Nexus_5_API_15
324 ```
325
326 Verify the device is running with:
327
328 ``` shell
329 adb devices
330 ```
331
332 You should see something like:
333
334 ``` shell
335 List of devices attached
336 emulator-5554 device
337 ```
338 Install APK with:
339
340 ``` shell
341 abd install <path/to/your>.apk
342 ```
343
344 Uninstall with:
345
346 ``` shell
347 abd uninstall se.leap.bitmaskclient
348 ```
349 Install with option to reinstall:
350
351 ``` shell
352 abd install -r <path/to/your/apk>
353 ```
354
355 ### Debian Gotchas <a name="debian-gotchas"></a>
356
357 If you are running Debian on a 64-bit machine, your emulator will likely not work out of the gate. Test to see if this is the case by:
358
359 * first creating an emulator in Android Studio (with name, eg, `Nexus_5_API_25`)
360 * then running:
361    ```shell
362    cd ~/
363    emulator @<name_of_your_emulator>
364    ```
365 If you can launch an emulator, HUZZAH! If not, you likely have one of 3 problems:
366
367 #### 1. Virtualization Not Enabled <a name="virtualization-not-enabled"></a>
368
369 Boo! Try turning it on. The second half of [this article](https://docs.fedoraproject.org/en-US/Fedora/13/html/Virtualization_Guide/sect-Virtualization-Troubleshooting-Enabling_Intel_VT_and_AMD_V_virtualization_hardware_extensions_in_BIOS.html) is a decent enough guide.
370
371 #### 2. Unpatched Filepaths Bug <a name="unpatched-filepaths-bug"></a>
372
373 **Symptoms:** If you have this bug, you will see something like the following when you try to spin up an emulator:
374
375 ``` shell
376 [140500439390016]:ERROR:./android/qt/qt_setup.cpp:28:Qt library not found at ../emulator/lib64/qt/lib
377 Could not launch '../emulator/qemu/linux-x86_64/qemu-system-i386': No such file or directory
378 ```
379 As [documented here](https://stackoverflow.com/questions/42554337/cannot-launch-avd-in-emulatorqt-library-not-found), there is a standing bug in the version of `emulator` packaged for emulator that assumes it always runs from within the `$ANDROID_HOME/emulator` directory, and can thus safely use relative filepaths, when in fact this is almost never the case. (Cool bug!)
380
381 **Fixes:**
382
383 You have a couple options. The second is more robust:
384
385 1. Always run emulator from within its own directory (clunky!):
386
387 ``` shell
388  cd "$(dirname "$(which emulator)")"
389  emulator <name_of_your_emulator>
390 ```
391
392 2. Insert a line in your `~/.bashrc` to automatically navigate to the correct directory (and back) whenever you invoke `emulator`:
393
394  ```shell
395 function emulator { pushd `pwd`; cd "$(dirname "$(which emulator)")" && ./emulator "$@"; popd;}
396 ```
397
398 #### 3. Outdated GL Libraries <a name="outdated-gl-libraries"></a>
399
400 **Symptoms:** If you have this bug, you will see something like the following:
401
402 ``` shell
403 libGL error: failed to load driver: swrast
404 X Error of failed request:  BadValue (integer parameter out of range for  operation)
405 # redacted incredibly long stack trace
406 ```
407
408 As documented [here](http://stackoverflow.com/questions/36554322/cannot-start-emulator-in-android-studio-2-0), the current emulator package ships without outdated versions of LibGL libraries. To work around this:
409
410 1. Install modern GL libriaries with:
411
412 ``` shell
413 sudo apt-get install mesa-utils
414 ```
415
416 2. Ensure that `emulator` always uses the correct libraries by either:
417
418   a. always calling `emulator` with the `-use-system-libs` flag, like so:
419
420   ``` shell
421   emulator -use-system-libs -avd Nexus_5_API_25
422   ```
423   b. adding the following line to your ~/.bashrc or ~/.bash_profile:
424
425   ```shell
426   export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1
427   ```
428
429 **Special Android Studio Debian Bonus Gotcha:**
430
431 Assuming you have made all the above fixes (great job!), to be able to launch emulators from Android Studio, you must either:
432
433 1. Use the environment variable solution above (option a), then *always* launch Android Studio from a bash shell with:
434
435 ``` shell
436 studio
437 ```
438
439 This means never using the desktop launcher. :(
440
441 2. If you want to use the desktop launcher:
442
443   * You must *always* launch emulators from the terminal. :(
444   * But: you can quickly access a terminal inside of Android Studio with `OPTION-F12`
445
446 ## Updating Submodules <a name="updating-submodules"></a>
447
448 If you need to refresh of our upstream dependency on ics-openvpn, you may do so with:
449
450 ``` shell
451 cd <path/to/bitmask_android>
452 ./gradlew updateIcsOpenVpn
453 ```
454
455 Alternately:
456
457 ```shell
458 cd <path/to/bitmask_android>
459 cd ics-openvpn
460 git remote add upstream https://github.com/schwabe/ics-openvpn.git
461 git pull --rebase upstream master
462 ```
463 A bunch of conflicts may arise. The guidelines are:
464
465     1. Methods in HEAD (upstream) completely removed from Bitmask should be removed again (e.g. askPW)
466     2. Sometimes, Dashboard.class is in Bitmask while in ics-openvpn it is replaced by MainActivity.class and other classes. Keep removing them to keep Dashboard.class in there.
467     3. Some resources files are stripped from several entries. Remove them if possible (check the code we compile is not using anything else new).
468
469 ## Acknowledgments <a name="acknowledgments"></a>
470
471 This project bases its work in [ics-openvpn project](https://code.google.com/p/ics-openvpn/).
472
473 ## Reporting Bugs <a name="reporting-bugs"></a>
474 Please file bug tickets on our main [development platform](https://0xacab.org/leap/bitmask_android/issues). You can either create an account on 0xacab.org or simply login with your github.com or gitlab.com account to create new tickets.
475
476 ## Contributing <a name="contributing"></a>
477
478 Please fork this repository and contribute back using [pull requests](https://0xacab.org/leap/bitmask_android/merge_requests).
479
480 Our preferred method for receiving translations is our [Transifex project](https://www.transifex.com/projects/p/bitmask-android).
481
482 Any contributions, large or small, major features, bug fixes, additional language translations, unit/integration tests are welcomed and appreciated but will be thoroughly reviewed and discussed.