From e624618be68d246ed3b9c61c22cec4ea52bbb6c7 Mon Sep 17 00:00:00 2001
From: Kr328 <39107975+Kr328@users.noreply.github.com>
Date: Fri, 15 Nov 2019 16:21:24 +0800
Subject: [PATCH] try
---
app/src/main/AndroidManifest.xml | 10 +++-
.../com/github/kr328/clash/IClashService.aidl | 6 ++
.../com/github/kr328/clash/ClashService.kt | 46 +++++++++++++++
.../com/github/kr328/clash/MainActivity.kt | 57 ++++++++++++++++++-
app/src/main/res/layout/activity_main.xml | 14 ++---
core/src/main/golang/init.go | 44 ++++++++++++++
core/src/main/golang/load.go | 48 +++++++++++++++-
core/src/main/golang/log/log.go | 27 ++++-----
.../com/github/kr328/clash/core/Clash.java | 2 +
.../kr328/clash/core/ClashException.java | 7 +++
10 files changed, 228 insertions(+), 33 deletions(-)
create mode 100644 app/src/main/aidl/com/github/kr328/clash/IClashService.aidl
create mode 100644 app/src/main/java/com/github/kr328/clash/ClashService.kt
create mode 100644 core/src/main/golang/init.go
create mode 100644 core/src/main/java/com/github/kr328/clash/core/ClashException.java
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0b6968d..7d3574c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,14 +1,18 @@
+
+
+ android:theme="@style/AppTheme"
+ tools:ignore="GoogleAppIndexingWarning">
@@ -16,6 +20,6 @@
+
-
\ No newline at end of file
diff --git a/app/src/main/aidl/com/github/kr328/clash/IClashService.aidl b/app/src/main/aidl/com/github/kr328/clash/IClashService.aidl
new file mode 100644
index 0000000..e22570f
--- /dev/null
+++ b/app/src/main/aidl/com/github/kr328/clash/IClashService.aidl
@@ -0,0 +1,6 @@
+// IClashService.aidl
+package com.github.kr328.clash;
+
+interface IClashService {
+ void loadProfile(String path);
+}
diff --git a/app/src/main/java/com/github/kr328/clash/ClashService.kt b/app/src/main/java/com/github/kr328/clash/ClashService.kt
new file mode 100644
index 0000000..b4ee905
--- /dev/null
+++ b/app/src/main/java/com/github/kr328/clash/ClashService.kt
@@ -0,0 +1,46 @@
+package com.github.kr328.clash
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import android.os.RemoteException
+import android.util.Log
+import com.github.kr328.clash.core.Clash
+import com.github.kr328.clash.core.ClashException
+import java.io.File
+import kotlin.concurrent.thread
+
+class ClashService : Service() {
+ private val binder = object: IClashService.Stub() {
+ override fun loadProfile(path: String?) {
+ if ( path == null || !File(path).exists() )
+ throw RemoteException("Invalid path")
+
+ thread {
+ try {
+ Clash.loadProfileFromPath(path)
+ }
+ catch (e: ClashException) {
+ Log.w("ClashForAndroid", "Load failure", e)
+ }
+ }
+ }
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ Clash.init(filesDir.resolve("clash").absolutePath)
+ Clash.loadDefault()
+ }
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return binder
+ }
+
+ override fun onDestroy() {
+ Clash.loadDefault()
+
+ super.onDestroy()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/kr328/clash/MainActivity.kt b/app/src/main/java/com/github/kr328/clash/MainActivity.kt
index 9f61b54..484313b 100644
--- a/app/src/main/java/com/github/kr328/clash/MainActivity.kt
+++ b/app/src/main/java/com/github/kr328/clash/MainActivity.kt
@@ -1,14 +1,65 @@
package com.github.kr328.clash
-import androidx.appcompat.app.AppCompatActivity
+import android.app.Activity
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.ServiceConnection
import android.os.Bundle
-import com.github.kr328.clash.core.Clash
+import android.os.IBinder
+import android.util.Log
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import kotlinx.android.synthetic.main.activity_main.*
+import java.io.FileOutputStream
+import java.lang.Exception
+import java.lang.RuntimeException
+import kotlin.concurrent.thread
class MainActivity : AppCompatActivity() {
+ companion object {
+ private const val REQUEST_CODE = 233
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
- Clash.loadDefault()
+ button.setOnClickListener {
+ startActivityForResult(Intent(Intent.ACTION_GET_CONTENT).setType("*/*"), REQUEST_CODE)
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ if ( requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK ) {
+ Toast.makeText(this, intent?.dataString, Toast.LENGTH_LONG).show()
+
+ thread {
+ FileOutputStream(cacheDir.resolve("config.yaml")).use {
+ contentResolver.openInputStream(data?.data ?: throw RuntimeException())?.apply { copyTo(it) }?.close()
+ }
+
+ bindService(Intent(this, ClashService::class.java), object: ServiceConnection {
+ override fun onServiceDisconnected(name: ComponentName?) {
+ Toast.makeText(this@MainActivity, "Disconnected", Toast.LENGTH_LONG).show()
+ }
+
+ override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
+ try {
+ val clash = IClashService.Stub.asInterface(service)
+
+ clash.loadProfile(cacheDir.resolve("config.yaml").absolutePath)
+ }
+ catch (e: Exception) {
+ Log.e("ClashForAndroid", "Load", e)
+ }
+ }
+
+ }, Context.BIND_AUTO_CREATE)
+ }
+ }
+ else {
+ super.onActivityResult(requestCode, resultCode, data)
+ }
}
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index ca0c0de..b1f1561 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -6,13 +6,13 @@
android:layout_height="match_parent"
tools:context=".MainActivity">
-
-
+ android:text="Open" />
\ No newline at end of file
diff --git a/core/src/main/golang/init.go b/core/src/main/golang/init.go
new file mode 100644
index 0000000..4a53df2
--- /dev/null
+++ b/core/src/main/golang/init.go
@@ -0,0 +1,44 @@
+package main
+
+/*
+#ifndef JNI_COMPILE
+#define JNI_COMPILE
+#include
+#include
+
+#define CLASH_EXCEPTION_CLASS "com/github/kr328/clash/core/ClashException"
+
+extern const char *_GoStringPtr(_GoString_ s);
+
+static void jni_throw_clash_exception(JNIEnv *env, _GoString_ message) {
+ (*env)->ThrowNew(env, CLASH_EXCEPTION_CLASS, _GoStringPtr(message));
+}
+
+static char *jni_get_string(JNIEnv *env, jstring string) {
+ const char *jni_string = (*env)->GetStringUTFChars(env, string, NULL);
+ char *result = strdup(jni_string);
+ (*env)->ReleaseStringUTFChars(env, string, jni_string);
+ return result;
+}
+#endif //JNI_COMPILE
+*/
+import "C"
+
+import (
+ "github.com/Dreamacro/clash/constant"
+)
+
+//export Java_com_github_kr328_clash_core_Clash_init
+func Java_com_github_kr328_clash_core_Clash_init(env *C.JNIEnv, class C.jclass, home C.jstring) {
+ cs := C.jni_get_string(env, home)
+ if cs == nil {
+ C.jni_throw_clash_exception(env, "Unable to get path")
+ return
+ }
+
+ p := C.GoString(cs)
+
+ C.free(unsafe.Pointer(cs))
+
+ constant.SetHomeDir(p)
+}
diff --git a/core/src/main/golang/load.go b/core/src/main/golang/load.go
index d5e5fb1..37b58e1 100644
--- a/core/src/main/golang/load.go
+++ b/core/src/main/golang/load.go
@@ -1,9 +1,34 @@
package main
-//#include
+/*
+#ifndef JNI_COMPILE
+#define JNI_COMPILE
+#include
+#include
+
+#define CLASH_EXCEPTION_CLASS "com/github/kr328/clash/core/ClashException"
+
+extern const char *_GoStringPtr(_GoString_ s);
+
+static void jni_throw_clash_exception(JNIEnv *env, _GoString_ message) {
+ (*env)->ThrowNew(env, CLASH_EXCEPTION_CLASS, _GoStringPtr(message));
+}
+
+static char *jni_get_string(JNIEnv *env, jstring string) {
+ const char *jni_string = (*env)->GetStringUTFChars(env, string, NULL);
+ char *result = strdup(jni_string);
+ (*env)->ReleaseStringUTFChars(env, string, jni_string);
+ return result;
+}
+#endif //JNI_COMPILE
+*/
import "C"
-import "github.com/kr328/clash-for-android/log"
-import "github.com/kr328/clash-for-android/profile"
+import "unsafe"
+
+import (
+ "github.com/kr328/clash-for-android/log"
+ "github.com/kr328/clash-for-android/profile"
+)
//export Java_com_github_kr328_clash_core_Clash_loadDefault
func Java_com_github_kr328_clash_core_Clash_loadDefault(env *C.JNIEnv, class C.jclass) {
@@ -11,3 +36,20 @@ func Java_com_github_kr328_clash_core_Clash_loadDefault(env *C.JNIEnv, class C.j
profile.LoadDefault()
}
+
+//export Java_com_github_kr328_clash_core_Clash_loadProfileFromPath
+func Java_com_github_kr328_clash_core_Clash_loadProfileFromPath(env *C.JNIEnv, class C.jclass, path C.jstring) {
+ cs := C.jni_get_string(env, path)
+ if cs == nil {
+ C.jni_throw_clash_exception(env, "Unable to get path")
+ return
+ }
+
+ p := C.GoString(cs)
+
+ C.free(unsafe.Pointer(cs))
+
+ if err := profile.LoadFromFile(p); err != nil {
+ C.jni_throw_clash_exception(env, err.Error())
+ }
+}
diff --git a/core/src/main/golang/log/log.go b/core/src/main/golang/log/log.go
index 44b7e02..2384515 100644
--- a/core/src/main/golang/log/log.go
+++ b/core/src/main/golang/log/log.go
@@ -8,35 +8,28 @@ package log
#define TAG "ClashForAndroid"
-static void log_info(const char *msg) {
- __android_log_print(ANDROID_LOG_INFO, "ClashForAndroid", "%s", msg);
+static void log_info(_GoString_ msg) {
+ __android_log_print(ANDROID_LOG_INFO, "ClashForAndroid", "%s", _GoStringPtr(msg));
}
-static void log_error(const char *msg) {
- __android_log_print(ANDROID_LOG_ERROR, "ClashForAndroid", "%s", msg);
+static void log_error(_GoString_ msg) {
+ __android_log_print(ANDROID_LOG_ERROR, "ClashForAndroid", "%s", _GoStringPtr(msg));
}
-static void log_warn(const char *msg) {
- __android_log_print(ANDROID_LOG_WARN, "ClashForAndroid", "%s", msg);
+static void log_warn(_GoString_ msg) {
+ __android_log_print(ANDROID_LOG_WARN, "ClashForAndroid", "%s", _GoStringPtr(msg));
}
*/
import "C"
-import "unsafe"
func Info(msg string) {
- log := C.CString(msg)
- C.log_info(log)
- C.free(unsafe.Pointer(log))
+ C.log_info(msg)
}
func Error(msg string) {
- log := C.CString(msg)
- C.log_error(log)
- C.free(unsafe.Pointer(log))
+ C.log_error(msg)
}
func Warn(msg string) {
- log := C.CString(msg)
- C.log_warn(log)
- C.free(unsafe.Pointer(log))
-}
\ No newline at end of file
+ C.log_warn(msg)
+}
diff --git a/core/src/main/java/com/github/kr328/clash/core/Clash.java b/core/src/main/java/com/github/kr328/clash/core/Clash.java
index df9b758..08f6b8b 100644
--- a/core/src/main/java/com/github/kr328/clash/core/Clash.java
+++ b/core/src/main/java/com/github/kr328/clash/core/Clash.java
@@ -1,7 +1,9 @@
package com.github.kr328.clash.core;
public final class Clash {
+ public static native void init(String home);
public static native void loadDefault();
+ public static native void loadProfileFromPath(String path) throws ClashException;
static {
System.loadLibrary("clash");
diff --git a/core/src/main/java/com/github/kr328/clash/core/ClashException.java b/core/src/main/java/com/github/kr328/clash/core/ClashException.java
new file mode 100644
index 0000000..3dda390
--- /dev/null
+++ b/core/src/main/java/com/github/kr328/clash/core/ClashException.java
@@ -0,0 +1,7 @@
+package com.github.kr328.clash.core;
+
+public class ClashException extends Exception {
+ public ClashException(String message) {
+ super(message);
+ }
+}