Merge branch 'main' into main
65
.github/workflows/android.yml
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
name: Android
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Check out Yggdrasil
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: yggdrasil-network/yggdrasil-go
|
||||||
|
path: yggdrasil-go
|
||||||
|
ref: develop
|
||||||
|
|
||||||
|
- name: Setup Go environment
|
||||||
|
uses: actions/setup-go@v3.3.1
|
||||||
|
|
||||||
|
- name: Install gomobile
|
||||||
|
run: |
|
||||||
|
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||||
|
~/go/bin/gomobile init
|
||||||
|
|
||||||
|
- name: Set up JDK 11
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'temurin'
|
||||||
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Install NDK
|
||||||
|
uses: nttld/setup-ndk@v1
|
||||||
|
id: setup-ndk
|
||||||
|
with:
|
||||||
|
ndk-version: r21e
|
||||||
|
add-to-path: false
|
||||||
|
|
||||||
|
- name: Build Yggdrasil
|
||||||
|
run: |
|
||||||
|
mkdir app/libs
|
||||||
|
cd yggdrasil-go
|
||||||
|
PATH=$PATH:~/go/bin/ ./contrib/mobile/build -a
|
||||||
|
cp {yggdrasil.aar,yggdrasil-sources.jar} ../app/libs
|
||||||
|
env:
|
||||||
|
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||||
|
|
||||||
|
- name: Gradle build
|
||||||
|
run: |
|
||||||
|
chmod +x gradlew
|
||||||
|
./gradlew build
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: yggdrasil-android
|
||||||
|
path: app/release/app-release.apk
|
62
.github/workflows/nightlylink.yml
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
name: Comment
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ['Build']
|
||||||
|
types: [completed]
|
||||||
|
jobs:
|
||||||
|
pr_comment:
|
||||||
|
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
# This snippet is public-domain, taken from
|
||||||
|
# https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml
|
||||||
|
script: |
|
||||||
|
async function upsertComment(owner, repo, issue_number, purpose, body) {
|
||||||
|
const {data: comments} = await github.rest.issues.listComments(
|
||||||
|
{owner, repo, issue_number});
|
||||||
|
|
||||||
|
const marker = `<!-- bot: ${purpose} -->`;
|
||||||
|
body = marker + "\n" + body;
|
||||||
|
|
||||||
|
const existing = comments.filter((c) => c.body.includes(marker));
|
||||||
|
if (existing.length > 0) {
|
||||||
|
const last = existing[existing.length - 1];
|
||||||
|
core.info(`Updating comment ${last.id}`);
|
||||||
|
await github.rest.issues.updateComment({
|
||||||
|
owner, repo,
|
||||||
|
body,
|
||||||
|
comment_id: last.id,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
core.info(`Creating a comment in issue / PR #${issue_number}`);
|
||||||
|
await github.rest.issues.createComment({issue_number, body, owner, repo});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const {owner, repo} = context.repo;
|
||||||
|
const run_id = ${{github.event.workflow_run.id}};
|
||||||
|
|
||||||
|
const pull_requests = ${{ toJSON(github.event.workflow_run.pull_requests) }};
|
||||||
|
if (!pull_requests.length) {
|
||||||
|
return core.error("This workflow doesn't match any pull requests!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const artifacts = await github.paginate(
|
||||||
|
github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id});
|
||||||
|
if (!artifacts.length) {
|
||||||
|
return core.error(`No artifacts found`);
|
||||||
|
}
|
||||||
|
let body = `Download the artifacts for this pull request:\n`;
|
||||||
|
for (const art of artifacts) {
|
||||||
|
body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info("Review thread message body:", body);
|
||||||
|
|
||||||
|
for (const pr of pull_requests) {
|
||||||
|
await upsertComment(owner, repo, pr.number,
|
||||||
|
"nightly-link", body);
|
||||||
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
<application
|
<application
|
||||||
android:name=".GlobalApplication"
|
android:name=".GlobalApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@drawable/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Yggdrasil">
|
android:theme="@style/Theme.Yggdrasil">
|
||||||
<activity android:name=".SettingsActivity"
|
<activity android:name=".SettingsActivity"
|
||||||
|
|
|
@ -77,11 +77,25 @@ class PacketTunnelProvider: VpnService() {
|
||||||
var builder = Builder()
|
var builder = Builder()
|
||||||
.addAddress(address, 7)
|
.addAddress(address, 7)
|
||||||
.addRoute("200::", 7)
|
.addRoute("200::", 7)
|
||||||
.allowBypass()
|
// We do this to trick the DNS-resolver into thinking that we have "regular" IPv6,
|
||||||
|
// and therefore we need to resolve AAAA DNS-records.
|
||||||
|
// See: https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/dns/net/getaddrinfo.c#1935
|
||||||
|
// and: https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/dns/net/getaddrinfo.c#365
|
||||||
|
// If we don't do this the DNS-resolver just doesn't do DNS-requests with record type AAAA,
|
||||||
|
// and we can't use DNS with Yggdrasil addresses.
|
||||||
|
.addRoute("2000::", 128)
|
||||||
.allowFamily(OsConstants.AF_INET)
|
.allowFamily(OsConstants.AF_INET)
|
||||||
|
.allowBypass()
|
||||||
.setBlocking(true)
|
.setBlocking(true)
|
||||||
.setMtu(yggdrasil.mtu.toInt())
|
.setMtu(yggdrasil.mtu.toInt())
|
||||||
.setSession("Yggdrasil")
|
.setSession("Yggdrasil")
|
||||||
|
// On Android API 29+ apps can opt-in/out to using metered networks.
|
||||||
|
// If we don't set metered status of VPN it is considered as metered.
|
||||||
|
// If we set it to false, then it will inherit this status from underlying network.
|
||||||
|
// See: https://developer.android.com/reference/android/net/VpnService.Builder#setMetered(boolean)
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
||||||
|
builder.setMetered(false)
|
||||||
|
}
|
||||||
|
|
||||||
parcel = builder.establish()
|
parcel = builder.establish()
|
||||||
val parcel = parcel
|
val parcel = parcel
|
||||||
|
@ -170,7 +184,7 @@ class PacketTunnelProvider: VpnService() {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
} catch (e: java.lang.InterruptedException) {
|
} catch (e: InterruptedException) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
app/src/main/res/drawable-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
app/src/main/res/drawable-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable-mdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
|
@ -1,30 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000" />
|
|
||||||
</vector>
|
|
BIN
app/src/main/res/drawable-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 16 KiB |
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 16 KiB |
37
readme.md
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
## build instructions
|
||||||
|
|
||||||
|
* install gomobile
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
* build yggdrasil-go for android:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/yggdrasil-network/yggdrasil-go /tmp/yggdrasil-go
|
||||||
|
cd /tmp/yggdrasil-go
|
||||||
|
./contrib/mobile/build -a
|
||||||
|
```
|
||||||
|
|
||||||
|
* clone yggdrasil for android and copy over the built go library
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/yggdrasil-network/yggdrasil-android /tmp/yggdrasil-android
|
||||||
|
mkdir /tmp/yggdrasil-android/app/libs
|
||||||
|
cp /tmp/yggdrasil-go/yggdrasil.aar /tmp/yggdrasil-android/app/libs/
|
||||||
|
```
|
||||||
|
|
||||||
|
* build yggdrasil-android
|
||||||
|
|
||||||
|
```
|
||||||
|
cd /tmp/yggdrasil-android
|
||||||
|
./gradew assemble
|
||||||
|
```
|
||||||
|
|
||||||
|
note: you will need to use jdk-11 as jdk-16 `"doesn't work" ™`
|
||||||
|
|
||||||
|
on debian/ubuntu you can set which jdk used with the `JAVA_HOME` env var:
|
||||||
|
```
|
||||||
|
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/
|
||||||
|
```
|