diff --git a/app/executableSo/.gitignore b/app/executableSo/.gitignore new file mode 100644 index 0000000..140f8cf --- /dev/null +++ b/app/executableSo/.gitignore @@ -0,0 +1 @@ +*.so diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt index 41e43e6..fe2a126 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt @@ -352,7 +352,7 @@ class BaseService { stopRunner(false, getString(R.string.invalid_server)) } catch (e: PluginManager.PluginNotFoundException) { Toast.makeText(this@Interface, e.readableMessage, Toast.LENGTH_SHORT).show() - Logs.d(e.readableMessage) + Logs.w(e) data.binder.missingPlugin(e.plugin) stopRunner(false, null) } catch (exc: Throwable) { diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt index bf1cb2e..fbbf4ea 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt @@ -456,7 +456,7 @@ fun buildConfig( } if (Plugins.isUsingMatsuriExe(pluginId)) { needExternal = false - } else if (Plugins.getPlugin(pluginId) != null) { + } else if (Plugins.getPluginExternal(pluginId) != null) { throw Exception("You are using an unsupported $pluginId, please download the correct plugin.") } } diff --git a/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt b/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt index 76fd704..ca8aa0d 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/plugin/PluginManager.kt @@ -32,7 +32,8 @@ object PluginManager { val result = initNative(pluginId) if (result != null) return result } catch (t: Throwable) { - if (throwable == null) throwable = t else Logs.w(t) + throwable = t + Logs.w(t) } throw throwable ?: PluginNotFoundException(pluginId) @@ -41,16 +42,41 @@ object PluginManager { private fun initNative(pluginId: String): InitResult? { val info = Plugins.getPlugin(pluginId) ?: return null + // internal so + if (info.applicationInfo == null) { + try { + initNativeInternal(pluginId)!!.let { return InitResult(it, info) } + } catch (t: Throwable) { + Logs.w("initNativeInternal failed", t) + } + return null + } + try { - initNativeFaster(info)?.also { return InitResult(it, info) } + initNativeFaster(info)!!.let { return InitResult(it, info) } } catch (t: Throwable) { - Logs.w("Initializing native plugin faster mode failed", t) + Logs.w("initNativeFaster failed", t) } Logs.w("Init native returns empty result") return null } + private fun initNativeInternal(pluginId: String): String? { + fun soIfExist(soName: String): String? { + val f = File(SagerNet.application.applicationInfo.nativeLibraryDir, soName) + if (f.canExecute()) { + return f.absolutePath + } + return null + } + return when (pluginId) { + "tuic-v5-plugin" -> soIfExist("libtuic.so") + "hysteria-plugin" -> soIfExist("libhysteria.so") + else -> null + } + } + private fun initNativeFaster(provider: ProviderInfo): String? { return provider.loadString(Plugins.METADATA_KEY_EXECUTABLE_PATH) ?.let { relativePath -> @@ -64,6 +90,7 @@ object PluginManager { is String -> value is Int -> SagerNet.application.packageManager.getResourcesForApplication(applicationInfo) .getString(value) + null -> null else -> error("meta-data $key has invalid type ${value.javaClass}") } diff --git a/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt b/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt index 677710d..d8f41f1 100644 --- a/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt +++ b/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt @@ -54,13 +54,19 @@ object Plugins { } fun getPlugin(pluginId: String): ProviderInfo? { + getPluginExternal(pluginId)?.let { return it } + // internal so + return ProviderInfo().apply { authority = AUTHORITIES_PREFIX_NEKO_EXE } + } + + fun getPluginExternal(pluginId: String): ProviderInfo? { if (pluginId.isBlank()) return null // try queryIntentContentProviders - var providers = getPluginOld(pluginId) + var providers = getExtPluginOld(pluginId) // try PackageCache - if (providers.isEmpty()) providers = getPluginNew(pluginId) + if (providers.isEmpty()) providers = getExtPluginNew(pluginId) // not found if (providers.isEmpty()) return null @@ -81,7 +87,7 @@ object Plugins { return providers[0] } - fun getPluginNew(pluginId: String): List { + private fun getExtPluginNew(pluginId: String): List { PackageCache.awaitLoadSync() val pkgs = PackageCache.installedPluginPackages .map { it.value } @@ -95,7 +101,7 @@ object Plugins { .path("/$id") .build() - private fun getPluginOld(pluginId: String): List { + private fun getExtPluginOld(pluginId: String): List { var flags = PackageManager.GET_META_DATA if (Build.VERSION.SDK_INT >= 24) { flags = diff --git a/buildSrc/src/main/kotlin/Helpers.kt b/buildSrc/src/main/kotlin/Helpers.kt index 9d1801f..63c1324 100644 --- a/buildSrc/src/main/kotlin/Helpers.kt +++ b/buildSrc/src/main/kotlin/Helpers.kt @@ -31,10 +31,12 @@ fun Project.requireFlavor(): String { flavor = taskName.substringAfter("assemble") return flavor } + taskName.contains("install") -> { flavor = taskName.substringAfter("install") return flavor } + taskName.contains("bundle") -> { flavor = taskName.substringAfter("bundle") return flavor @@ -252,5 +254,8 @@ fun Project.setupApp() { } } + sourceSets.getByName("main").apply { + jniLibs.srcDir("executableSo") + } } } \ No newline at end of file