mirror of https://github.com/oxen-io/lokinet
commit
13af82474c
@ -1,18 +0,0 @@
|
|||||||
gen
|
|
||||||
tests
|
|
||||||
bin
|
|
||||||
libs
|
|
||||||
log*
|
|
||||||
obj
|
|
||||||
.gradle
|
|
||||||
.idea
|
|
||||||
.externalNativeBuild
|
|
||||||
ant.properties
|
|
||||||
local.properties
|
|
||||||
build.sh
|
|
||||||
android.iml
|
|
||||||
build
|
|
||||||
gradle
|
|
||||||
gradlew
|
|
||||||
gradlew.bat
|
|
||||||
gradle.properties
|
|
@ -1,46 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="network.loki.lokinet"
|
|
||||||
android:installLocation="auto"
|
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="0.8.4">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" /> <!-- normal perm, per https://developer.android.com/guide/topics/permissions/normal-permissions.html -->
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
<!-- normal perm -->
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:icon="@drawable/icon"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
|
|
||||||
>
|
|
||||||
<receiver android:name=".NetworkStateChangeReceiver">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".LokiNetActivity"
|
|
||||||
android:label="@string/app_name">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<service android:name=".LokinetDaemon"
|
|
||||||
android:enabled="true"
|
|
||||||
android:exported="true"
|
|
||||||
android:permission="android.permission.BIND_VPN_SERVICE">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.net.VpnService"/>
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
@ -1,81 +0,0 @@
|
|||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
google()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
maven {
|
|
||||||
url 'https://maven.google.com'
|
|
||||||
}
|
|
||||||
google()
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
compileSdkVersion 28
|
|
||||||
defaultConfig {
|
|
||||||
applicationId "network.loki.lokinet"
|
|
||||||
targetSdkVersion 28
|
|
||||||
minSdkVersion 23
|
|
||||||
versionCode 1
|
|
||||||
versionName '0.8.4'
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
targets "lokinet-android"
|
|
||||||
arguments "-DWITH_LTO=OFF", "-DCXXOPTS_BUILD_TESTS=OFF","-DWITH_TESTS=OFF", "-DCMAKE_CROSSCOMPILING=ON", "-DNATIVE_BUILD=OFF", "-DANDROID=ON", "-DANDROID_STL=c++_static", "-DBUILD_STATIC_DEPS=ON", "-DBUILD_SHARED_LIBS=OFF", "-DSTATIC_LINK=ON", "-DANDROID_ARM_MODE=arm", "-DFORCE_OXENMQ_SUBMODULE=ON", "-DBUILD_LIBLOKINET=OFF"
|
|
||||||
cppFlags "-std=c++17"
|
|
||||||
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
|
||||||
// abiFilters 'armeabi-v7a'
|
|
||||||
// abiFilters 'arm64-v8a', 'x86_64', 'armeabi-v7a'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
path "../CMakeLists.txt"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
|
||||||
java.srcDirs = ['src']
|
|
||||||
res.srcDirs = ['res']
|
|
||||||
jniLibs.srcDirs = ['libs']
|
|
||||||
assets.srcDirs = ['assets']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signingConfigs {
|
|
||||||
jeff {
|
|
||||||
storeFile file("jeff-apk.jks")
|
|
||||||
keyAlias "jeff-apk"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
minifyEnabled true
|
|
||||||
//signingConfig signingConfigs.jeff
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
|
|
||||||
debuggable false
|
|
||||||
}
|
|
||||||
debug {
|
|
||||||
// jniDebuggable true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project name="lokinet" default="help">
|
|
||||||
|
|
||||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
|
||||||
It contains the path to the SDK. It should *NOT* be checked into
|
|
||||||
Version Control Systems. -->
|
|
||||||
<property file="local.properties" />
|
|
||||||
|
|
||||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
|
||||||
'android' tool to add properties to it.
|
|
||||||
This is the place to change some Ant specific build properties.
|
|
||||||
Here are some properties you may want to change/update:
|
|
||||||
|
|
||||||
source.dir
|
|
||||||
The name of the source directory. Default is 'src'.
|
|
||||||
out.dir
|
|
||||||
The name of the output directory. Default is 'bin'.
|
|
||||||
|
|
||||||
For other overridable properties, look at the beginning of the rules
|
|
||||||
files in the SDK, at tools/ant/build.xml
|
|
||||||
|
|
||||||
Properties related to the SDK location or the project target should
|
|
||||||
be updated using the 'android' tool with the 'update' action.
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property file="ant.properties" />
|
|
||||||
|
|
||||||
<!-- if sdk.dir was not set from one of the property file, then
|
|
||||||
get it from the ANDROID_HOME env var.
|
|
||||||
This must be done before we load project.properties since
|
|
||||||
the proguard config can use sdk.dir -->
|
|
||||||
<property environment="env" />
|
|
||||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
|
||||||
<isset property="env.ANDROID_HOME" />
|
|
||||||
</condition>
|
|
||||||
|
|
||||||
<!-- The project.properties file is created and updated by the 'android'
|
|
||||||
tool, as well as ADT.
|
|
||||||
|
|
||||||
This contains project specific properties such as project target, and library
|
|
||||||
dependencies. Lower level build properties are stored in ant.properties
|
|
||||||
(or in .classpath for Eclipse projects).
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems. -->
|
|
||||||
<loadproperties srcFile="project.properties" />
|
|
||||||
|
|
||||||
<!-- quick check on sdk.dir -->
|
|
||||||
<fail
|
|
||||||
message="sdk.dir is missing. Insert sdk.dir=... into './local.properties'. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
|
||||||
unless="sdk.dir"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<fail
|
|
||||||
message="ndk.dir is missing. Insert ndk.dir=... into './local.properties'."
|
|
||||||
unless="ndk.dir"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Import per project custom build rules if present at the root of the project.
|
|
||||||
This is the place to put custom intermediary targets such as:
|
|
||||||
-pre-build
|
|
||||||
-pre-compile
|
|
||||||
-post-compile (This is typically used for code obfuscation.
|
|
||||||
Compiled code location: ${out.classes.absolute.dir}
|
|
||||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
|
||||||
-post-package
|
|
||||||
-post-build
|
|
||||||
-pre-clean
|
|
||||||
-->
|
|
||||||
<import file="custom_rules.xml" optional="true" />
|
|
||||||
|
|
||||||
<!-- Import the actual build file.
|
|
||||||
|
|
||||||
To customize existing targets, there are two options:
|
|
||||||
- Customize only one target:
|
|
||||||
- copy/paste the target into this file, *before* the
|
|
||||||
<import> task.
|
|
||||||
- customize it to your needs.
|
|
||||||
- Customize the whole content of build.xml
|
|
||||||
- copy/paste the content of the rules files (minus the top node)
|
|
||||||
into this file, replacing the <import> task.
|
|
||||||
- customize to your needs.
|
|
||||||
|
|
||||||
***********************
|
|
||||||
****** IMPORTANT ******
|
|
||||||
***********************
|
|
||||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
|
||||||
in order to avoid having your file be overridden by tools such as "android update project"
|
|
||||||
-->
|
|
||||||
<!-- version-tag: 1 -->
|
|
||||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
|
||||||
</project>
|
|
@ -1,20 +0,0 @@
|
|||||||
# To enable ProGuard in your project, edit project.properties
|
|
||||||
# to define the proguard.config property as described in that file.
|
|
||||||
#
|
|
||||||
# Add project specific ProGuard rules here.
|
|
||||||
# By default, the flags in this file are appended to flags specified
|
|
||||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
|
||||||
# You can edit the include path and order by changing the ProGuard
|
|
||||||
# include property in project.properties.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# Add any project specific keep options here:
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
@ -1,14 +0,0 @@
|
|||||||
# This file is automatically generated by Android Tools.
|
|
||||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
|
||||||
#
|
|
||||||
# This file must be checked in Version Control Systems.
|
|
||||||
#
|
|
||||||
# To customize properties used by the Ant build system edit
|
|
||||||
# "ant.properties", and override values to adapt the script to your
|
|
||||||
# project structure.
|
|
||||||
#
|
|
||||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
|
||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
|
||||||
|
|
||||||
# Project target.
|
|
||||||
target=android-28
|
|
@ -1,33 +0,0 @@
|
|||||||
# lokinet android
|
|
||||||
|
|
||||||
this directory contains basic stuff for lokinet on android.
|
|
||||||
|
|
||||||
## Prerequsites
|
|
||||||
|
|
||||||
To build you need the following:
|
|
||||||
|
|
||||||
* Gradle (6.x)
|
|
||||||
* Android SDK (latest version)
|
|
||||||
* Android NDK (latest version)
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
Next set up the path to Android SDK and NDK in `local.properties`
|
|
||||||
|
|
||||||
```
|
|
||||||
sdk.dir=/path/to/android/sdk
|
|
||||||
ndk.dir=/path/to/android/ndk
|
|
||||||
```
|
|
||||||
|
|
||||||
Then build:
|
|
||||||
|
|
||||||
$ gradle assemble
|
|
||||||
|
|
||||||
This fetches a large amount (several dozen Gigabytes) of files from some
|
|
||||||
server somewhere dumping it on your filesystem to make the thing do the
|
|
||||||
building, then proceeds to peg all your cores for several dozen minutes
|
|
||||||
while it does the required incantations to build 2 apks.
|
|
||||||
|
|
||||||
The build outputs apks to to subdirectories in `build/outputs/apk/`
|
|
||||||
one called `debug` for debug builds and one called `release` for release builds.
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.4 KiB |
@ -1,27 +0,0 @@
|
|||||||
<LinearLayout android:id="@+id/main_layout"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/vertical_page_margin"
|
|
||||||
android:paddingLeft="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingRight="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingTop="@dimen/vertical_page_margin"
|
|
||||||
tools:context=".PermsAskerActivity">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_retry"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
|
||||||
android:visibility="gone"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_request_write_ext_storage_perms"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Retry requesting VPN"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
</LinearLayout>
|
|
@ -1,27 +0,0 @@
|
|||||||
<LinearLayout android:id="@+id/layout_prompt"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/vertical_page_margin"
|
|
||||||
android:paddingLeft="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingRight="@dimen/horizontal_page_margin"
|
|
||||||
android:paddingTop="@dimen/vertical_page_margin"
|
|
||||||
tools:context=".PermsAskerActivity">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_explanation"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
|
||||||
android:text="VPN permissions are required for lokinet usage."
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_ok"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="OK"
|
|
||||||
/>
|
|
||||||
</LinearLayout>
|
|
@ -1,16 +0,0 @@
|
|||||||
<menu
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:context=".LokiNetActivity">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_start"
|
|
||||||
android:title="@string/action_start"
|
|
||||||
android:orderInCategory="98"
|
|
||||||
/>
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_stop"
|
|
||||||
android:title="@string/action_stop"
|
|
||||||
android:orderInCategory="99"
|
|
||||||
/>
|
|
||||||
</menu>
|
|
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">lokinet</string>
|
|
||||||
<string name="action_start">Start</string>
|
|
||||||
<string name="action_stop">Stop</string>
|
|
||||||
<string name="already_stopped">Already stopped</string>
|
|
||||||
<string name="loaded">lokinet loaded</string>
|
|
||||||
<string name="starting">lokinet is starting</string>
|
|
||||||
<string name="jniLibraryLoaded">lokinet: loaded JNI libraries</string>
|
|
||||||
<string name="startedOkay">lokinet started</string>
|
|
||||||
<string name="startFailed">lokinet start failed</string>
|
|
||||||
<string name="stopped">lokinet has stopped</string>
|
|
||||||
<string name="remaining">remaining</string>
|
|
||||||
<string name="title_activity_perms_asker_prompt">Prompt</string>
|
|
||||||
<string name="bootstrap_ok">got bootstrap node info</string>
|
|
||||||
<string name="bootstrap_fail">failed to bootstrap</string>
|
|
||||||
<string name="netdb_create_fail">failed to create netdb directory</string>
|
|
||||||
<string name="vpn_setup_fail">failed to set up vpn tunnel</string>
|
|
||||||
</resources>
|
|
@ -1,16 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
|
|
||||||
|
|
||||||
<dimen name="margin_tiny">4dp</dimen>
|
|
||||||
<dimen name="margin_small">8dp</dimen>
|
|
||||||
<dimen name="margin_medium">16dp</dimen>
|
|
||||||
<dimen name="margin_large">32dp</dimen>
|
|
||||||
<dimen name="margin_huge">64dp</dimen>
|
|
||||||
|
|
||||||
<!-- Semantic definitions -->
|
|
||||||
|
|
||||||
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
|
|
||||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
|
||||||
|
|
||||||
</resources>
|
|
@ -1 +0,0 @@
|
|||||||
rootProject.name = "lokinet"
|
|
@ -1,185 +0,0 @@
|
|||||||
package network.loki.lokinet;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.Manifest;
|
|
||||||
|
|
||||||
import android.net.VpnService;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
|
|
||||||
public class LokiNetActivity extends Activity {
|
|
||||||
private static final String TAG = "lokinet-activity";
|
|
||||||
private TextView textView;
|
|
||||||
private static final String DefaultBootstrapURL = "https://seed.lokinet.org/lokinet.signed";
|
|
||||||
|
|
||||||
private AsyncBootstrap bootstrapper;
|
|
||||||
|
|
||||||
public static final String LOG_TAG = "LokinetDaemon";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
textView = new TextView(this);
|
|
||||||
setContentView(textView);
|
|
||||||
System.loadLibrary("lokinet-android");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void writeFile(File out, InputStream instream) throws IOException {
|
|
||||||
OutputStream outstream = new FileOutputStream(out);
|
|
||||||
byte[] buffer = new byte[512];
|
|
||||||
int len;
|
|
||||||
try {
|
|
||||||
do {
|
|
||||||
len = instream.read(buffer);
|
|
||||||
if (len > 0) {
|
|
||||||
outstream.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (len != -1);
|
|
||||||
} finally {
|
|
||||||
outstream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startLokinet()
|
|
||||||
{
|
|
||||||
if(bootstrapper != null)
|
|
||||||
return;
|
|
||||||
bootstrapper = new AsyncBootstrap();
|
|
||||||
bootstrapper.execute(DefaultBootstrapURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runLokinetService()
|
|
||||||
{
|
|
||||||
Intent intent = VpnService.prepare(getApplicationContext());
|
|
||||||
if (intent != null)
|
|
||||||
{
|
|
||||||
Log.d(LOG_TAG, "VpnService.prepare() returned an Intent, so launch that intent.");
|
|
||||||
startActivityForResult(intent, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.w(LOG_TAG, "VpnService.prepare() returned null, not running.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
|
||||||
{
|
|
||||||
if (resultCode == RESULT_OK)
|
|
||||||
{
|
|
||||||
Log.d(LOG_TAG, "VpnService prepared intent RESULT_OK, launching LokinetDaemon Service");
|
|
||||||
startService(new Intent(LokiNetActivity.this,
|
|
||||||
LokinetDaemon.class));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.d(LOG_TAG, "VpnService prepared intent NOT RESULT_OK, shit.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
textView = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getRootDir()
|
|
||||||
{
|
|
||||||
return getFilesDir();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AsyncBootstrap extends AsyncTask<String, String, String>
|
|
||||||
{
|
|
||||||
public String doInBackground(String ... urls) {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File bootstrapFile = new File(getRootDir(), "bootstrap.signed");
|
|
||||||
URL bootstrapURL = new URL(urls[0]);
|
|
||||||
InputStream instream = bootstrapURL.openStream();
|
|
||||||
writeFile(bootstrapFile, instream);
|
|
||||||
instream.close();
|
|
||||||
return getString(R.string.bootstrap_ok);
|
|
||||||
}
|
|
||||||
catch(Exception thrown)
|
|
||||||
{
|
|
||||||
return getString(R.string.bootstrap_fail) + ": " + throwableToString(thrown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void onPostExecute(String val) {
|
|
||||||
textView.setText(val);
|
|
||||||
if(val.equals(getString(R.string.bootstrap_ok)))
|
|
||||||
runLokinetService();
|
|
||||||
bootstrapDone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bootstrapDone()
|
|
||||||
{
|
|
||||||
bootstrapper = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CharSequence throwableToString(Throwable tr) {
|
|
||||||
StringWriter sw = new StringWriter(8192);
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
tr.printStackTrace(pw);
|
|
||||||
pw.close();
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
|
||||||
getMenuInflater().inflate(R.menu.options_main, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
// Handle action bar item clicks here. The action bar will
|
|
||||||
// automatically handle clicks on the Home/Up button, so long
|
|
||||||
// as you specify a parent activity in AndroidManifest.xml.
|
|
||||||
int id = item.getItemId();
|
|
||||||
|
|
||||||
switch(id){
|
|
||||||
case R.id.action_start:
|
|
||||||
startLokinet();
|
|
||||||
return true;
|
|
||||||
case R.id.action_stop:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package network.loki.lokinet;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
|
|
||||||
public class NetworkStateChangeReceiver extends BroadcastReceiver {
|
|
||||||
|
|
||||||
private static final String TAG = "lokinet";
|
|
||||||
|
|
||||||
//api level 1
|
|
||||||
@Override
|
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
|
||||||
Log.d(TAG,"Network state change");
|
|
||||||
try {
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
|
|
||||||
boolean isConnected = activeNetworkInfo!=null && activeNetworkInfo.isConnected();
|
|
||||||
// https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html?hl=ru
|
|
||||||
// boolean isWiFi = activeNetworkInfo!=null && (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
|
|
||||||
} catch (Throwable tr) {
|
|
||||||
Log.d(TAG,"",tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,173 +0,0 @@
|
|||||||
package network.loki.lokinet;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
//dangerous perms, per https://developer.android.com/guide/topics/permissions/normal-permissions.html :
|
|
||||||
//android.permission.WRITE_EXTERNAL_STORAGE
|
|
||||||
public class PermsAskerActivity extends Activity {
|
|
||||||
|
|
||||||
private static final int PERMISSION_VPN = 0;
|
|
||||||
|
|
||||||
private Button button_request_write_ext_storage_perms;
|
|
||||||
private TextView textview_retry;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
startMainActivity();
|
|
||||||
/*
|
|
||||||
//if less than Android 6, no runtime perms req system present
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < 23) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_perms_asker);
|
|
||||||
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms);
|
|
||||||
textview_retry = (TextView) findViewById(R.id.textview_retry);
|
|
||||||
|
|
||||||
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
request_write_ext_storage_perms();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
request_write_ext_storage_perms();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private void request_write_ext_storage_perms() {
|
|
||||||
|
|
||||||
textview_retry.setVisibility(TextView.GONE);
|
|
||||||
button_request_write_ext_storage_perms.setVisibility(Button.GONE);
|
|
||||||
|
|
||||||
Method methodCheckPermission;
|
|
||||||
Method method_shouldShowRequestPermissionRationale;
|
|
||||||
Method method_requestPermissions;
|
|
||||||
try {
|
|
||||||
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class);
|
|
||||||
method_shouldShowRequestPermissionRationale =
|
|
||||||
getClass().getMethod("shouldShowRequestPermissionRationale", String.class);
|
|
||||||
method_requestPermissions =
|
|
||||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
Integer resultObj;
|
|
||||||
try {
|
|
||||||
resultObj = (Integer) methodCheckPermission.invoke(
|
|
||||||
this, Manifest.permission.BIND_VPN_SERVICE);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultObj != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
// Should we show an explanation?
|
|
||||||
Boolean aBoolean;
|
|
||||||
try {
|
|
||||||
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this,
|
|
||||||
Manifest.permission.BIND_VPN_SERVICE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
if (aBoolean) {
|
|
||||||
|
|
||||||
// Show an explanation to the user *asynchronously* -- don't block
|
|
||||||
// this thread waiting for the user's response! After the user
|
|
||||||
// sees the explanation, try again to request the permission.
|
|
||||||
|
|
||||||
showExplanation();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// No explanation needed, we can request the permission.
|
|
||||||
|
|
||||||
try {
|
|
||||||
method_requestPermissions.invoke(this,
|
|
||||||
new String[]{Manifest.permission.BIND_VPN_SERVICE},
|
|
||||||
PERMISSION_VPN);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else startMainActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
|
||||||
String permissions[], int[] grantResults) {
|
|
||||||
switch (requestCode) {
|
|
||||||
case PERMISSION_VPN: {
|
|
||||||
// If request is cancelled, the result arrays are empty.
|
|
||||||
if (grantResults.length > 0
|
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
// permission was granted, yay! Do the
|
|
||||||
// contacts-related task you need to do.
|
|
||||||
|
|
||||||
startMainActivity();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// permission denied, boo! Disable the
|
|
||||||
// functionality that depends on this permission.
|
|
||||||
textview_retry.setText("you need to allow this to continue");
|
|
||||||
textview_retry.setVisibility(TextView.VISIBLE);
|
|
||||||
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// other 'case' lines to check for other
|
|
||||||
// permissions this app might request.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startMainActivity() {
|
|
||||||
startActivity(new Intent(this, LokiNetActivity.class));
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
|
|
||||||
private void showExplanation() {
|
|
||||||
Intent intent = new Intent(this, PermsExplanationActivity.class);
|
|
||||||
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
// Check which request we're responding to
|
|
||||||
if (requestCode == SHOW_EXPLANATION_REQUEST) {
|
|
||||||
// Make sure the request was successful
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
// Request the permission
|
|
||||||
Method method_requestPermissions;
|
|
||||||
try {
|
|
||||||
method_requestPermissions =
|
|
||||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
method_requestPermissions.invoke(this,
|
|
||||||
new String[]{Manifest.permission.BIND_VPN_SERVICE},
|
|
||||||
PERMISSION_VPN);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
finish(); //close the app
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package network.loki.lokinet;
|
|
||||||
|
|
||||||
import android.app.ActionBar;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
public class PermsExplanationActivity extends Activity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_perms_explanation);
|
|
||||||
ActionBar actionBar = getActionBar();
|
|
||||||
if(actionBar!=null)actionBar.setHomeButtonEnabled(false);
|
|
||||||
Button button_ok = (Button) findViewById(R.id.button_ok);
|
|
||||||
button_ok.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
returnFromActivity();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void returnFromActivity() {
|
|
||||||
Intent data = new Intent();
|
|
||||||
Activity parent = getParent();
|
|
||||||
if (parent == null) {
|
|
||||||
setResult(Activity.RESULT_OK, data);
|
|
||||||
} else {
|
|
||||||
parent.setResult(Activity.RESULT_OK, data);
|
|
||||||
}
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set +x
|
||||||
|
|
||||||
|
default_abis="armeabi-v7a arm64-v8a x86 x86_64"
|
||||||
|
build_abis=${ABIS:-$default_abis}
|
||||||
|
|
||||||
|
test x$NDK = x && echo "NDK env var not set"
|
||||||
|
test x$NDK = x && exit 1
|
||||||
|
|
||||||
|
echo "building abis: $build_abis"
|
||||||
|
|
||||||
|
root="$(readlink -f $(dirname $0)/../)"
|
||||||
|
out=$root/lokinet-jni-$(git describe)
|
||||||
|
mkdir -p $out
|
||||||
|
mkdir -p $root/build-android
|
||||||
|
cd $root/build-android
|
||||||
|
|
||||||
|
for abi in $build_abis; do
|
||||||
|
mkdir -p build-$abi $out/$abi
|
||||||
|
cd build-$abi
|
||||||
|
cmake \
|
||||||
|
-G 'Unix Makefiles' \
|
||||||
|
-DANDROID=ON \
|
||||||
|
-DANDROID_ABI=$abi \
|
||||||
|
-DANDROID_ARM_MODE=arm \
|
||||||
|
-DANDROID_PLATFORM=android-23 \
|
||||||
|
-DANDROID_STL=c++_static \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
|
||||||
|
-DBUILD_STATIC_DEPS=ON \
|
||||||
|
-DBUILD_PACKAGE=ON \
|
||||||
|
-DBUILD_SHARED_LIBS=OFF \
|
||||||
|
-DBUILD_TESTING=OFF \
|
||||||
|
-DBUILD_LIBLOKINET=OFF \
|
||||||
|
-DWITH_TESTS=OFF \
|
||||||
|
-DNATIVE_BUILD=OFF \
|
||||||
|
-DSTATIC_LINK=ON \
|
||||||
|
-DWITH_SYSTEMD=OFF \
|
||||||
|
-DFORCE_OXENMQ_SUBMODULE=ON \
|
||||||
|
-DSUBMODULE_CHECK=OFF \
|
||||||
|
-DWITH_LTO=OFF \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
$@ $root
|
||||||
|
make lokinet-android -j${JOBS:-$(nproc)}
|
||||||
|
cp jni/liblokinet-android.so $out/$abi/liblokinet-android.so
|
||||||
|
cd -
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "build artifacts outputted to $out"
|
@ -1,3 +1,3 @@
|
|||||||
FROM debian:stable
|
FROM debian:stable
|
||||||
RUN /bin/bash -c 'echo "man-db man-db/auto-update boolean false" | debconf-set-selections'
|
RUN /bin/bash -c 'echo "man-db man-db/auto-update boolean false" | debconf-set-selections'
|
||||||
RUN /bin/bash -c 'apt-get -o=Dpkg::Use-Pty=0 -q update && apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y && apt-get -o=Dpkg::Use-Pty=0 -q install -y eatmydata gdb cmake git ninja-build pkg-config ccache g++ libsodium-dev libsystemd-dev python3-dev libuv1-dev libunbound-dev nettle-dev libssl-dev libevent-dev libsqlite3-dev libboost-thread-dev liboost-serialization-dev libboost-program-options-dev libgtest-dev libminiupnpc-dev libunwind8-dev libreadline-dev libhidapi-dev libusb-1.0.0-dev qttools5-dev libcurl4-openssl-dev'
|
RUN /bin/bash -c 'apt-get -o=Dpkg::Use-Pty=0 -q update && apt-get -o=Dpkg::Use-Pty=0 -q dist-upgrade -y && apt-get -o=Dpkg::Use-Pty=0 -q install -y eatmydata gdb cmake git ninja-build pkg-config ccache g++ libsodium-dev libsystemd-dev python3-dev libuv1-dev libunbound-dev nettle-dev libssl-dev libevent-dev libsqlite3-dev libboost-thread-dev libboost-serialization-dev libboost-program-options-dev libgtest-dev libminiupnpc-dev libunwind8-dev libreadline-dev libhidapi-dev libusb-1.0.0-dev qttools5-dev libcurl4-openssl-dev'
|
||||||
|
Loading…
Reference in New Issue