Commit 734056ea authored by Mygod's avatar Mygod

Remove dependency on libsuperuser

There is no longer a reason to use this overkill.

* Turning on tcp_fastopen is replaced by manual su call;
* Call to chmod binary is replaced by Os.chmod, which is better at error reporting. (also bumps plugin library to 1.0.0)
parent 5627357a
...@@ -78,7 +78,6 @@ dependencies { ...@@ -78,7 +78,6 @@ dependencies {
api 'com.google.firebase:firebase-core:16.0.6' api 'com.google.firebase:firebase-core:16.0.6'
api 'com.squareup.okhttp3:okhttp:3.12.1' api 'com.squareup.okhttp3:okhttp:3.12.1'
api "com.takisoft.preferencex:preferencex:$preferencexVersion" api "com.takisoft.preferencex:preferencex:$preferencexVersion"
api 'eu.chainfire:libsuperuser:1.0.0.201811281328'
kapt "androidx.room:room-compiler:$roomVersion" kapt "androidx.room:room-compiler:$roomVersion"
testImplementation "androidx.room:room-testing:$roomVersion" testImplementation "androidx.room:room-testing:$roomVersion"
testImplementation "junit:junit:$junitVersion" testImplementation "junit:junit:$junitVersion"
......
...@@ -110,7 +110,7 @@ object Core { ...@@ -110,7 +110,7 @@ object Core {
// handle data restored/crash // handle data restored/crash
if (Build.VERSION.SDK_INT >= 24 && DataStore.directBootAware && if (Build.VERSION.SDK_INT >= 24 && DataStore.directBootAware &&
app.getSystemService<UserManager>()?.isUserUnlocked == true) DirectBoot.flushTrafficStats() app.getSystemService<UserManager>()?.isUserUnlocked == true) DirectBoot.flushTrafficStats()
if (DataStore.tcpFastOpen) TcpFastOpen.enabledAsync(true) if (DataStore.tcpFastOpen && !TcpFastOpen.sendEnabled) TcpFastOpen.enabledAsync()
if (DataStore.publicStore.getLong(Key.assetUpdateTime, -1) != packageInfo.lastUpdateTime) { if (DataStore.publicStore.getLong(Key.assetUpdateTime, -1) != packageInfo.lastUpdateTime) {
val assetManager = app.assets val assetManager = app.assets
for (dir in arrayOf("acl", "overture")) for (dir in arrayOf("acl", "overture"))
......
...@@ -26,17 +26,17 @@ import android.content.ContentResolver ...@@ -26,17 +26,17 @@ import android.content.ContentResolver
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.Signature import android.content.pm.Signature
import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.system.Os
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import com.github.shadowsocks.Core import com.github.shadowsocks.Core
import com.github.shadowsocks.Core.app import com.github.shadowsocks.Core.app
import com.github.shadowsocks.utils.Commandline
import com.github.shadowsocks.utils.printLog import com.github.shadowsocks.utils.printLog
import com.github.shadowsocks.utils.signaturesCompat import com.github.shadowsocks.utils.signaturesCompat
import eu.chainfire.libsuperuser.Shell
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
...@@ -162,7 +162,6 @@ object PluginManager { ...@@ -162,7 +162,6 @@ object PluginManager {
private fun initNativeSlow(cr: ContentResolver, options: PluginOptions, uri: Uri): String? { private fun initNativeSlow(cr: ContentResolver, options: PluginOptions, uri: Uri): String? {
var initialized = false var initialized = false
fun entryNotFound(): Nothing = throw IndexOutOfBoundsException("Plugin entry binary not found") fun entryNotFound(): Nothing = throw IndexOutOfBoundsException("Plugin entry binary not found")
val list = ArrayList<String>()
val pluginDir = File(Core.deviceStorage.noBackupFilesDir, "plugin") val pluginDir = File(Core.deviceStorage.noBackupFilesDir, "plugin")
(cr.query(uri, arrayOf(PluginContract.COLUMN_PATH, PluginContract.COLUMN_MODE), null, null, null) (cr.query(uri, arrayOf(PluginContract.COLUMN_PATH, PluginContract.COLUMN_MODE), null, null, null)
?: return null).use { cursor -> ?: return null).use { cursor ->
...@@ -177,12 +176,15 @@ object PluginManager { ...@@ -177,12 +176,15 @@ object PluginManager {
cr.openInputStream(uri.buildUpon().path(path).build())!!.use { inStream -> cr.openInputStream(uri.buildUpon().path(path).build())!!.use { inStream ->
file.outputStream().use { outStream -> inStream.copyTo(outStream) } file.outputStream().use { outStream -> inStream.copyTo(outStream) }
} }
list += Commandline.toString(arrayOf("chmod", cursor.getString(1), file.absolutePath)) Os.chmod(file.absolutePath, when (cursor.getType(1)) {
Cursor.FIELD_TYPE_INTEGER -> cursor.getInt(1)
Cursor.FIELD_TYPE_STRING -> cursor.getString(1).toInt(8)
else -> throw IllegalArgumentException()
})
if (path == options.id) initialized = true if (path == options.id) initialized = true
} while (cursor.moveToNext()) } while (cursor.moveToNext())
} }
if (!initialized) entryNotFound() if (!initialized) entryNotFound()
Shell.SH.run(list)
return File(pluginDir, options.id).absolutePath return File(pluginDir, options.id).absolutePath
} }
} }
...@@ -20,10 +20,12 @@ ...@@ -20,10 +20,12 @@
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import eu.chainfire.libsuperuser.Shell
import java.io.File import java.io.File
import java.io.IOException
object TcpFastOpen { object TcpFastOpen {
private const val PATH = "/proc/sys/net/ipv4/tcp_fastopen"
/** /**
* Is kernel version >= 3.7.1. * Is kernel version >= 3.7.1.
*/ */
...@@ -41,16 +43,19 @@ object TcpFastOpen { ...@@ -41,16 +43,19 @@ object TcpFastOpen {
} }
val sendEnabled: Boolean get() { val sendEnabled: Boolean get() {
val file = File("/proc/sys/net/ipv4/tcp_fastopen") val file = File(PATH)
// File.readText doesn't work since this special file will return length 0 // File.readText doesn't work since this special file will return length 0
return file.canRead() && file.bufferedReader().use { it.readText() }.trim().toInt() and 1 > 0 return file.canRead() && file.bufferedReader().use { it.readText() }.trim().toInt() and 1 > 0
} }
fun enabled(value: Boolean): String? = if (sendEnabled == value) null else Shell.run("su", arrayOf( fun enabled(): String? {
"if echo " + (if (value) 3 else 0) + " > /proc/sys/net/ipv4/tcp_fastopen; then", return try {
" echo Success.", val process = ProcessBuilder("su", "-c", "echo 3 > $PATH")
"else", .redirectErrorStream(true).start()
" echo Failed.", process.inputStream.bufferedReader().readText()
"fi"), null, true)?.joinToString("\n") } catch (e: IOException) {
fun enabledAsync(value: Boolean) = thread("TcpFastOpen") { enabled(value) }.join(1000) e.localizedMessage
}
}
fun enabledAsync() = thread("TcpFastOpen") { enabled() }.join(1000)
} }
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
<string name="direct_boot_aware_summary">Your selected profile information will be less protected</string> <string name="direct_boot_aware_summary">Your selected profile information will be less protected</string>
<string name="tcp_fastopen_summary">Toggling might require ROOT permission</string> <string name="tcp_fastopen_summary">Toggling might require ROOT permission</string>
<string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string> <string name="tcp_fastopen_summary_unsupported">Unsupported kernel version: %s &lt; 3.7.1</string>
<string name="tcp_fastopen_failure">Toggle failed</string>
<string name="udp_dns">DNS Forwarding</string> <string name="udp_dns">DNS Forwarding</string>
<string name="udp_dns_summary">Forward all DNS requests to remote</string> <string name="udp_dns_summary">Forward all DNS requests to remote</string>
......
...@@ -54,10 +54,13 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() { ...@@ -54,10 +54,13 @@ class GlobalSettingsPreferenceFragment : PreferenceFragmentCompat() {
val tfo = findPreference(Key.tfo) as SwitchPreference val tfo = findPreference(Key.tfo) as SwitchPreference
tfo.isChecked = DataStore.tcpFastOpen tfo.isChecked = DataStore.tcpFastOpen
tfo.setOnPreferenceChangeListener { _, value -> tfo.setOnPreferenceChangeListener { _, value ->
if (value as Boolean) { if (value as Boolean && !TcpFastOpen.sendEnabled) {
val result = TcpFastOpen.enabled(true) val result = TcpFastOpen.enabled()?.trim()
if (result != null && result != "Success.") (activity as MainActivity).snackbar(result).show() if (TcpFastOpen.sendEnabled) true else {
TcpFastOpen.sendEnabled (activity as MainActivity).snackbar(
if (result.isNullOrEmpty()) getText(R.string.tcp_fastopen_failure) else result).show()
false
}
} else true } else true
} }
if (!TcpFastOpen.supported) { if (!TcpFastOpen.supported) {
......
* 0.2.0: * 1.0.0:
* `PathProvider` now takes `Int` instead of `String` for file modes;
* Refactor to AndroidX; * Refactor to AndroidX;
* No longer depends on preference libraries. * No longer depends on preference libraries.
* 0.1.1: * 0.1.1:
......
...@@ -11,7 +11,7 @@ android { ...@@ -11,7 +11,7 @@ android {
minSdkVersion rootProject.minSdkVersion minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.sdkVersion targetSdkVersion rootProject.sdkVersion
versionCode 7 versionCode 7
versionName "0.2.0" versionName "1.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
......
...@@ -30,14 +30,14 @@ import java.io.File ...@@ -30,14 +30,14 @@ import java.io.File
class PathProvider internal constructor(baseUri: Uri, private val cursor: MatrixCursor) { class PathProvider internal constructor(baseUri: Uri, private val cursor: MatrixCursor) {
private val basePath = baseUri.path?.trim('/') ?: "" private val basePath = baseUri.path?.trim('/') ?: ""
fun addPath(path: String, mode: String = "644"): PathProvider { fun addPath(path: String, mode: Int = 0b110100100): PathProvider {
val trimmed = path.trim('/') val trimmed = path.trim('/')
if (trimmed.startsWith(basePath)) cursor.newRow() if (trimmed.startsWith(basePath)) cursor.newRow()
.add(PluginContract.COLUMN_PATH, trimmed) .add(PluginContract.COLUMN_PATH, trimmed)
.add(PluginContract.COLUMN_MODE, mode) .add(PluginContract.COLUMN_MODE, mode)
return this return this
} }
fun addTo(file: File, to: String = "", mode: String = "644"): PathProvider { fun addTo(file: File, to: String = "", mode: Int = 0b110100100): PathProvider {
var sub = to + file.name var sub = to + file.name
if (basePath.startsWith(sub)) if (file.isDirectory) { if (basePath.startsWith(sub)) if (file.isDirectory) {
sub += '/' sub += '/'
...@@ -45,7 +45,7 @@ class PathProvider internal constructor(baseUri: Uri, private val cursor: Matrix ...@@ -45,7 +45,7 @@ class PathProvider internal constructor(baseUri: Uri, private val cursor: Matrix
} else addPath(sub, mode) } else addPath(sub, mode)
return this return this
} }
fun addAt(file: File, at: String = "", mode: String = "644"): PathProvider { fun addAt(file: File, at: String = "", mode: Int = 0b110100100): PathProvider {
if (basePath.startsWith(at)) if (basePath.startsWith(at))
if (file.isDirectory) file.listFiles().forEach { addTo(it, at, mode) } else addPath(at, mode) if (file.isDirectory) file.listFiles().forEach { addTo(it, at, mode) } else addPath(at, mode)
return this return this
......
...@@ -170,10 +170,13 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti ...@@ -170,10 +170,13 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
tfo = findPreference(Key.tfo) as SwitchPreference tfo = findPreference(Key.tfo) as SwitchPreference
tfo.isChecked = DataStore.tcpFastOpen tfo.isChecked = DataStore.tcpFastOpen
tfo.setOnPreferenceChangeListener { _, value -> tfo.setOnPreferenceChangeListener { _, value ->
if (value as Boolean) { if (value as Boolean && !TcpFastOpen.sendEnabled) {
val result = TcpFastOpen.enabled(true) val result = TcpFastOpen.enabled()?.trim()
if (result != null && result != "Success.") Toast.makeText(activity, result, Toast.LENGTH_LONG).show() if (TcpFastOpen.sendEnabled) true else {
TcpFastOpen.sendEnabled Toast.makeText(activity, if (result.isNullOrEmpty())
getText(R.string.tcp_fastopen_failure) else result, Toast.LENGTH_SHORT).show()
false
}
} else true } else true
} }
if (!TcpFastOpen.supported) { if (!TcpFastOpen.supported) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment