summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock118
-rw-r--r--Cargo.toml3
-rw-r--r--android/build.gradle39
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt29
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt27
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt10
-rw-r--r--mullvad-daemon/src/main.rs11
-rw-r--r--mullvad-daemon/src/version.rs9
-rw-r--r--mullvad-jni/Cargo.toml23
-rw-r--r--mullvad-jni/src/daemon_interface.rs17
-rw-r--r--mullvad-jni/src/lib.rs102
11 files changed, 377 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4b66ca292e..60bfb33769 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -44,6 +44,11 @@ dependencies = [
]
[[package]]
+name = "ascii"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "assert_matches"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -141,6 +146,11 @@ version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "cfg-if"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -195,6 +205,18 @@ dependencies = [
]
[[package]]
+name = "combine"
+version = "3.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -351,6 +373,11 @@ dependencies = [
]
[[package]]
+name = "either"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "env_logger"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -670,6 +697,24 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "jni"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "jsonrpc-client-core"
version = "0.5.0"
source = "git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b#68aac55b6ddff5e1242594b54f7f9149fe215ff7"
@@ -891,6 +936,14 @@ dependencies = [
]
[[package]]
+name = "lock_api"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1108,6 +1161,22 @@ dependencies = [
]
[[package]]
+name = "mullvad-jni"
+version = "0.1.0"
+dependencies = [
+ "err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mullvad-daemon 2019.4.0",
+ "mullvad-paths 0.1.0",
+ "mullvad-types 0.1.0",
+ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "talpid-types 0.1.0",
+]
+
+[[package]]
name = "mullvad-paths"
version = "0.1.0"
dependencies = [
@@ -1435,6 +1504,16 @@ dependencies = [
]
[[package]]
+name = "parking_lot"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "parking_lot_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1459,6 +1538,21 @@ dependencies = [
]
[[package]]
+name = "parking_lot_core"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1800,6 +1894,11 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "scopeguard"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2492,6 +2591,14 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "unreachable"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "utf8-ranges"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2662,6 +2769,7 @@ dependencies = [
"checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841"
"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
+"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335"
"checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
@@ -2675,12 +2783,14 @@ dependencies = [
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2"
+"checksum cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9"
+"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
@@ -2698,6 +2808,7 @@ dependencies = [
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
"checksum duct 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3640af123c78bedc20c1d3928e43cc0621e57011899d1ef917900c12fdb7a1ee"
+"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a"
"checksum err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8ff65eb6c2fc68e76557239d16f5698fd56603925b89856d3f0f7105fd4543"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
@@ -2734,6 +2845,8 @@ dependencies = [
"checksum ipnetwork 0.14.0 (git+https://github.com/mullvad/ipnetwork?branch=fix-deserialization)" = "<none>"
"checksum ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3d862c86f7867f19b693ec86765e0252d82e53d4240b9b629815675a0714ad1"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
+"checksum jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "294eca097d1dc0bf59de5ab9f7eafa5f77129e9f6464c957ed3ddeb705fb4292"
+"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
"checksum jsonrpc-client-core 0.5.0 (git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b)" = "<none>"
"checksum jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f29cb249837420fb0cee7fb0fbf1d22679e121b160e71bb5e0d90b9df241c23e"
"checksum jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e642eb74423b9dfcb4512fda167148746b76f788a823cd712fadf409f31d302"
@@ -2756,6 +2869,7 @@ dependencies = [
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
"checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
+"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae0136257df209261daa18d6c16394757c63e032e27aafd8b07788b051082bef"
@@ -2793,8 +2907,10 @@ dependencies = [
"checksum parity-tokio-ipc 0.1.0 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
+"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7"
"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
+"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum pfctl 0.2.1 (git+https://github.com/mullvad/pfctl-rs?rev=9f31b5ddcab941862470075eab83bb398195f3d6)" = "<none>"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
@@ -2836,6 +2952,7 @@ dependencies = [
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
+"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560"
@@ -2899,6 +3016,7 @@ dependencies = [
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
+"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
diff --git a/Cargo.toml b/Cargo.toml
index 20d61b7d1d..04d05658d9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,6 +4,7 @@ members = [
"mullvad-cli",
"mullvad-problem-report",
"mullvad-ipc-client",
+ "mullvad-jni",
"mullvad-paths",
"mullvad-types",
"mullvad-rpc",
@@ -12,4 +13,4 @@ members = [
"talpid-core",
"talpid-ipc",
]
-exclude = ["dist-assets/binaries/shadowsocks-rust"] \ No newline at end of file
+exclude = ["dist-assets/binaries/shadowsocks-rust"]
diff --git a/android/build.gradle b/android/build.gradle
index 5be82b79d7..d511691624 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -4,6 +4,10 @@ import org.jmailen.gradle.kotlinter.tasks.LintTask
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
+def repoRootPath = projectDir.absoluteFile.parentFile.absolutePath
+def extraAssetsDirectory = "$project.buildDir/extraAssets"
+def extraJniDirectory = "$project.buildDir/extraJni"
+
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
@@ -22,6 +26,28 @@ android {
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
+
+ sourceSets {
+ main {
+ assets {
+ srcDirs = files(extraAssetsDirectory)
+ }
+
+ jniLibs {
+ srcDirs = files(extraJniDirectory)
+ }
+ }
+ }
+
+ applicationVariants.all { variant ->
+ variant.mergeAssetsProvider.configure {
+ dependsOn copyApiRootCertificate
+ }
+
+ variant.ndkCompileProvider.configure {
+ dependsOn copyMullvadJni
+ }
+ }
}
repositories {
@@ -33,6 +59,7 @@ dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.3.21'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
}
buildscript {
@@ -65,3 +92,15 @@ task format(type: FormatTask, group: 'formatting') {
}
lint.dependsOn lintKotlin
+
+task copyMullvadJni(type: Copy) {
+ from "$repoRootPath/target/aarch64-linux-android/debug"
+ include 'libmullvad_jni.so'
+ into "$extraJniDirectory/arm64-v8a"
+}
+
+task copyApiRootCertificate(type: Copy) {
+ from "$repoRootPath/dist-assets"
+ include "api_root_ca.pem"
+ into extraAssetsDirectory
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt
new file mode 100644
index 0000000000..dc8af32ce2
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt
@@ -0,0 +1,29 @@
+package net.mullvad.mullvadvpn
+
+import java.io.File
+import java.io.FileOutputStream
+import java.io.InputStream
+
+import android.content.Context
+
+private const val API_ROOT_CA_FILE = "api_root_ca.pem"
+private const val API_ROOT_CA_PATH = "/data/data/net.mullvad.mullvadvpn/api_root_ca.pem"
+
+class ApiRootCaFile {
+ fun extract(context: Context) {
+ if (!File(API_ROOT_CA_PATH).exists()) {
+ extractFile(context, API_ROOT_CA_FILE, API_ROOT_CA_PATH)
+ }
+ }
+
+ private fun extractFile(context: Context, asset: String, destination: String) {
+ val destinationStream = FileOutputStream(destination)
+
+ context
+ .assets
+ .open(asset)
+ .copyTo(destinationStream)
+
+ destinationStream.close()
+ }
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
index b7b0e8fa8c..b751bf63d9 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt
@@ -1,24 +1,51 @@
package net.mullvad.mullvadvpn
+import kotlinx.coroutines.async
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+
import android.os.Bundle
import android.support.v4.app.FragmentActivity
class MainActivity : FragmentActivity() {
+ val activityCreated = CompletableDeferred<Unit>()
+
+ val asyncDaemon = startDaemon()
+ val daemon
+ get() = runBlocking { asyncDaemon.await() }
+
var selectedRelayItemCode: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
+ activityCreated.complete(Unit)
+
if (savedInstanceState == null) {
addInitialFragment()
}
}
+ override fun onDestroy() {
+ asyncDaemon.cancel()
+
+ super.onDestroy()
+ }
+
private fun addInitialFragment() {
supportFragmentManager?.beginTransaction()?.apply {
add(R.id.main_fragment, LoginFragment())
commit()
}
}
+
+ private fun startDaemon() = GlobalScope.async(Dispatchers.Default) {
+ activityCreated.await()
+ ApiRootCaFile().extract(this@MainActivity)
+ MullvadDaemon()
+ }
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
new file mode 100644
index 0000000000..d5ab845f89
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt
@@ -0,0 +1,10 @@
+package net.mullvad.mullvadvpn
+
+class MullvadDaemon {
+ init {
+ System.loadLibrary("mullvad_jni")
+ initialize()
+ }
+
+ private external fun initialize()
+}
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index 8deae9f489..9d4ca0fb56 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -48,7 +48,7 @@ fn init_logging(config: &cli::Config) -> Result<Option<PathBuf>, String> {
)
.map_err(|e| e.display_chain_with_msg("Unable to initialize logger"))?;
log_panics::init();
- log_version();
+ version::log_version();
if let Some(ref log_dir) = log_dir {
info!("Logging to {}", log_dir.display());
}
@@ -119,15 +119,6 @@ fn create_daemon(log_dir: Option<PathBuf>) -> Result<Daemon, String> {
.map_err(|e| e.display_chain_with_msg("Unable to initialize daemon"))
}
-fn log_version() {
- info!(
- "Starting {} - {} {}",
- env!("CARGO_PKG_NAME"),
- version::PRODUCT_VERSION,
- version::COMMIT_DATE,
- )
-}
-
#[cfg(unix)]
fn running_as_admin() -> bool {
let uid = unsafe { libc::getuid() };
diff --git a/mullvad-daemon/src/version.rs b/mullvad-daemon/src/version.rs
index f02e2b5fda..72c28144ff 100644
--- a/mullvad-daemon/src/version.rs
+++ b/mullvad-daemon/src/version.rs
@@ -3,3 +3,12 @@ pub const PRODUCT_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/produc
/// Contains the date of the git commit this was built from
pub const COMMIT_DATE: &str = include_str!(concat!(env!("OUT_DIR"), "/git-commit-date.txt"));
+
+pub fn log_version() {
+ log::info!(
+ "Starting {} - {} {}",
+ env!("CARGO_PKG_NAME"),
+ PRODUCT_VERSION,
+ COMMIT_DATE,
+ )
+}
diff --git a/mullvad-jni/Cargo.toml b/mullvad-jni/Cargo.toml
new file mode 100644
index 0000000000..9b87aa07a3
--- /dev/null
+++ b/mullvad-jni/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "mullvad-jni"
+version = "0.1.0"
+authors = ["Mullvad VPN <admin@mullvad.net>"]
+description = "JNI interface for the Mullvad daemon"
+license = "GPL-3.0"
+edition = "2018"
+
+[lib]
+crate_type = ["cdylib"]
+
+[dependencies]
+err-derive = "0.1.5"
+jni = "0.11"
+lazy_static = "1"
+log = "0.4"
+log-panics = "2"
+parking_lot = "0.8"
+
+mullvad-daemon = { path = "../mullvad-daemon" }
+mullvad-paths = { path = "../mullvad-paths" }
+mullvad-types = { path = "../mullvad-types" }
+talpid-types = { path = "../talpid-types" }
diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs
new file mode 100644
index 0000000000..b682660edf
--- /dev/null
+++ b/mullvad-jni/src/daemon_interface.rs
@@ -0,0 +1,17 @@
+use mullvad_daemon::DaemonCommandSender;
+
+pub struct DaemonInterface {
+ command_sender: Option<DaemonCommandSender>,
+}
+
+impl DaemonInterface {
+ pub fn new() -> Self {
+ DaemonInterface {
+ command_sender: None,
+ }
+ }
+
+ pub fn set_command_sender(&mut self, sender: DaemonCommandSender) {
+ self.command_sender = Some(sender);
+ }
+}
diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs
new file mode 100644
index 0000000000..ce6d953fcd
--- /dev/null
+++ b/mullvad-jni/src/lib.rs
@@ -0,0 +1,102 @@
+#![cfg(target_os = "android")]
+
+mod daemon_interface;
+
+use crate::daemon_interface::DaemonInterface;
+use jni::{objects::JObject, JNIEnv};
+use lazy_static::lazy_static;
+use mullvad_daemon::{logging, version, Daemon, DaemonCommandSender, EventListener};
+use mullvad_types::{relay_list::RelayList, settings::Settings};
+use parking_lot::Mutex;
+use std::{path::PathBuf, sync::mpsc, thread};
+use talpid_types::{tunnel::TunnelStateTransition, ErrorExt};
+
+const LOG_FILENAME: &str = "daemon.log";
+
+lazy_static! {
+ static ref DAEMON_INTERFACE: Mutex<DaemonInterface> = Mutex::new(DaemonInterface::new());
+}
+
+#[derive(Debug, err_derive::Error)]
+pub enum Error {
+ #[error(display = "Failed to get cache directory path")]
+ GetCacheDir(#[error(cause)] mullvad_paths::Error),
+
+ #[error(display = "Failed to initialize the mullvad daemon")]
+ InitializeDaemon(#[error(cause)] mullvad_daemon::Error),
+}
+
+#[no_mangle]
+#[allow(non_snake_case)]
+pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_initialize(_: JNIEnv, _: JObject) {
+ let log_dir = start_logging();
+
+ if let Err(error) = initialize(log_dir) {
+ log::error!("{}", error.display_chain());
+ }
+}
+
+fn start_logging() -> PathBuf {
+ let log_dir = mullvad_paths::log_dir().unwrap();
+ let log_file = log_dir.join(LOG_FILENAME);
+
+ logging::init_logger(log::LevelFilter::Debug, Some(&log_file), true).unwrap();
+ log_panics::init();
+ version::log_version();
+
+ log_dir
+}
+
+fn initialize(log_dir: PathBuf) -> Result<(), Error> {
+ let daemon_command_sender = spawn_daemon(log_dir)?;
+
+ DAEMON_INTERFACE
+ .lock()
+ .set_command_sender(daemon_command_sender);
+
+ Ok(())
+}
+
+fn spawn_daemon(log_dir: PathBuf) -> Result<DaemonCommandSender, Error> {
+ let (tx, rx) = mpsc::channel();
+
+ thread::spawn(move || match create_daemon(log_dir) {
+ Ok(daemon) => {
+ let _ = tx.send(Ok(daemon.command_sender()));
+ match daemon.run() {
+ Ok(()) => log::info!("Mullvad daemon has stopped"),
+ Err(error) => log::error!("{}", error.display_chain()),
+ }
+ }
+ Err(error) => {
+ let _ = tx.send(Err(error));
+ }
+ });
+
+ rx.recv().unwrap()
+}
+
+fn create_daemon(log_dir: PathBuf) -> Result<Daemon<DummyListener>, Error> {
+ let resource_dir = mullvad_paths::get_resource_dir();
+ let cache_dir = mullvad_paths::cache_dir().map_err(Error::GetCacheDir)?;
+
+ let daemon = Daemon::start_with_event_listener(
+ DummyListener,
+ Some(log_dir),
+ resource_dir,
+ cache_dir,
+ version::PRODUCT_VERSION.to_owned(),
+ )
+ .map_err(Error::InitializeDaemon)?;
+
+ Ok(daemon)
+}
+
+#[derive(Clone, Copy, Debug)]
+struct DummyListener;
+
+impl EventListener for DummyListener {
+ fn notify_new_state(&self, _: TunnelStateTransition) {}
+ fn notify_settings(&self, _: Settings) {}
+ fn notify_relay_list(&self, _: RelayList) {}
+}