Compare commits

...

14 Commits

Author SHA1 Message Date
2dust 45805d6df7 Merge pull request #644 from yuhan6665/clean-dependency
Clean dependency
2020-10-04 19:16:27 +08:00
2dust 4437e6699b Merge pull request #635 from rurirei/diff
issues of VPNService.kt
2020-10-04 19:16:14 +08:00
2dust fa409f91e4 Merge pull request #626 from yuhan6665/go
Clean up tun2socks
2020-10-04 19:16:00 +08:00
yuhan6665 89be5f077b Say goodbye to Anko
replace with support lib PreferenceManager
replace LayoutInflater
2020-10-03 11:19:46 -04:00
yuhan6665 896889778f Replace Anko with support lib AlertDialog
replace some property setter
2020-10-03 11:19:46 -04:00
yuhan6665 10f705a8b2 Use standard startActivity 2020-10-03 11:19:46 -04:00
yuhan6665 2956fa2030 Replace doasync with Kotlin coroutine
Using a custom coroutine scope, we don't need to keep track of the
running job. We can simply call cancel children for the scope.
2020-10-03 11:19:46 -04:00
yuhan6665 c2a704a6ea Deprecate some anko function
- Replace toast with inline function
- Use standard startActivityForResult
2020-10-03 11:19:46 -04:00
yuhan6665 78cac0cd90 Replace divider with standard library
Also, cleanup some unused classes
2020-10-03 11:19:46 -04:00
Rurirei 3ffb2e8e05 catch exception for lateinit
PropertyNotInitialized exception needs catch for lateinit var
2020-10-03 20:23:43 +08:00
Rurirei e2d667e0bb sendFd() should not called twice 2020-10-01 17:36:07 +08:00
Rurirei 3ae0777d7f useless bool 2020-10-01 17:07:51 +08:00
Rurirei 5e6348676c ignore err of registerNetworkConnectivity 2020-10-01 15:32:08 +08:00
yuhan6665 94f2bec329 Clean up tun2socks 2020-09-27 23:17:47 -04:00
34 changed files with 228 additions and 351 deletions
+1 -4
View File
@@ -8,9 +8,6 @@ asset:
# cd assets;curl https://raw.githubusercontent.com/2dust/AndroidLibV2rayLite/master/data/geosite.dat > geosite.dat # cd assets;curl https://raw.githubusercontent.com/2dust/AndroidLibV2rayLite/master/data/geosite.dat > geosite.dat
# cd assets;curl https://raw.githubusercontent.com/2dust/AndroidLibV2rayLite/master/data/geoip.dat > geoip.dat # cd assets;curl https://raw.githubusercontent.com/2dust/AndroidLibV2rayLite/master/data/geoip.dat > geoip.dat
shippedBinary:
cd shippedBinarys; $(MAKE) shippedBinary
fetchDep: fetchDep:
-go get github.com/2dust/AndroidLibV2rayLite -go get github.com/2dust/AndroidLibV2rayLite
go get github.com/2dust/AndroidLibV2rayLite go get github.com/2dust/AndroidLibV2rayLite
@@ -30,5 +27,5 @@ downloadGoMobile:
BuildMobile: BuildMobile:
@echo Stub @echo Stub
all: asset pb shippedBinary fetchDep all: asset pb fetchDep
@echo DONE @echo DONE
+5 -9
View File
@@ -34,14 +34,10 @@ $NDK_HOME/ndk-build \
NDK_OUT=$TMPDIR/tmp \ NDK_OUT=$TMPDIR/tmp \
APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -j4 APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -j4
install -v -m755 libs/armeabi-v7a/tun2socks $__dir/shippedBinarys/ArchDep/arm/ install -v -m755 libs/armeabi-v7a/tun2socks $__dir/../V2rayNG/app/src/main/jniLibs/armeabi-v7a/libtun2socks.so
install -v -m755 libs/arm64-v8a/tun2socks $__dir/shippedBinarys/ArchDep/arm64/ install -v -m755 libs/arm64-v8a/tun2socks $__dir/../V2rayNG/app/src/main/jniLibs/arm64-v8a/libtun2socks.so
install -v -m755 libs/x86/tun2socks $__dir/shippedBinarys/ArchDep/386/ install -v -m755 libs/x86/tun2socks $__dir/../V2rayNG/app/src/main/jniLibs/x86/libtun2socks.so
install -v -m755 libs/x86_64/tun2socks $__dir/shippedBinarys/ArchDep/amd64/ install -v -m755 libs/x86_64/tun2socks $__dir/../V2rayNG/app/src/main/jniLibs/x86_64/libtun2socks.so
popd popd
pushd $__dir/shippedBinarys rm -rf $TMPDIR
make clean && make shippedBinary
popd
rm -rf $TMPDIR
-7
View File
@@ -11,7 +11,6 @@ import (
"github.com/2dust/AndroidLibV2rayLite/CoreI" "github.com/2dust/AndroidLibV2rayLite/CoreI"
"github.com/2dust/AndroidLibV2rayLite/Process/Escort" "github.com/2dust/AndroidLibV2rayLite/Process/Escort"
"github.com/2dust/AndroidLibV2rayLite/VPN" "github.com/2dust/AndroidLibV2rayLite/VPN"
"github.com/2dust/AndroidLibV2rayLite/shippedBinarys"
mobasset "golang.org/x/mobile/asset" mobasset "golang.org/x/mobile/asset"
v2core "v2ray.com/core" v2core "v2ray.com/core"
@@ -227,12 +226,6 @@ func NewV2RayPoint(s V2RayVPNServiceSupportsSet) *V2RayPoint {
} }
func (v V2RayPoint) runTun2socks() error { func (v V2RayPoint) runTun2socks() error {
shipb := shippedBinarys.FirstRun{Status: v.status}
if err := shipb.CheckAndExport(); err != nil {
log.Println(err)
return err
}
v.escorter.EscortingUp() v.escorter.EscortingUp()
go v.escorter.EscortRun( go v.escorter.EscortRun(
v.status.GetApp("libtun2socks.so"), v.status.GetApp("libtun2socks.so"),
@@ -1,13 +0,0 @@
Platdep=shippedBinary.386 shippedBinary.amd64 shippedBinary.arm64 shippedBinary.arm
shippedBinaryDep:
go get -u github.com/jteeuwen/go-bindata/...
shippedBinary.%:
go-bindata -nometadata -nomemcopy -pkg shippedBinarys -o ./binary_$*.go -tags $* ArchIndep/ ArchDep/$*/
shippedBinary:shippedBinaryDep $(Platdep)
@echo "Done"
clean:
-rm binary*
@@ -1,69 +0,0 @@
package shippedBinarys
import (
"log"
"os"
"strconv"
"github.com/2dust/AndroidLibV2rayLite/CoreI"
)
type FirstRun struct {
Status *CoreI.Status
}
func (v *FirstRun) checkIfRcExist() error {
datadir := v.Status.GetDataDir()
if _, err := os.Stat(datadir + strconv.Itoa(CoreI.CheckVersion())); !os.IsNotExist(err) {
log.Println("file exists")
return nil
}
IndepDir, err := AssetDir("ArchIndep")
log.Println(IndepDir)
if err != nil {
return err
}
for _, fn := range IndepDir {
log.Println(datadir+"ArchIndep/"+fn)
err := RestoreAsset(datadir, "ArchIndep/"+fn)
log.Println(err)
//GrantPremission
os.Chmod(datadir+"ArchIndep/"+fn, 0700)
log.Println(os.Remove(datadir + fn))
log.Println(os.Symlink(datadir+"ArchIndep/"+fn, datadir + fn))
}
DepDir, err := AssetDir("ArchDep")
log.Println(DepDir)
if err != nil {
return err
}
for _, fn := range DepDir {
DepDir2, err := AssetDir("ArchDep/" + fn)
log.Println("ArchDep/" + fn)
if err != nil {
return err
}
for _, FND := range DepDir2 {
log.Println(datadir+"ArchDep/"+fn+"/"+FND)
RestoreAsset(datadir, "ArchDep/"+fn+"/"+FND)
os.Chmod(datadir+"ArchDep/"+fn+"/"+FND, 0700)
log.Println(os.Remove(datadir + FND))
log.Println(os.Symlink(datadir+"ArchDep/"+fn+"/"+FND, datadir+FND))
}
}
s, _ := os.Create(datadir + strconv.Itoa(CoreI.CheckVersion()))
s.Close()
return nil
}
func (v *FirstRun) CheckAndExport() error {
return v.checkIfRcExist()
}
-7
View File
@@ -81,20 +81,13 @@ dependencies {
implementation 'com.android.support.constraint:constraint-layout:2.0.1' implementation 'com.android.support.constraint:constraint-layout:2.0.1'
// DSL // DSL
implementation "org.jetbrains.anko:anko-sdk15:$ankoVersion"
implementation "org.jetbrains.anko:anko-support-v4:$ankoVersion"
implementation "org.jetbrains.anko:anko-appcompat-v7:$ankoVersion"
implementation "org.jetbrains.anko:anko-design:$ankoVersion"
implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.code.gson:gson:2.8.6'
implementation 'io.reactivex:rxjava:1.3.4' implementation 'io.reactivex:rxjava:1.3.4'
implementation 'io.reactivex:rxandroid:1.2.1' implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar' implementation 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar'
implementation 'com.dinuscxj:recycleritemdecoration:1.0.0'
implementation 'io.reactivex:rxkotlin:0.60.0'
implementation 'me.dm7.barcodescanner:core:1.9.8' implementation 'me.dm7.barcodescanner:core:1.9.8'
implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'com.github.jorgecastilloprz:fabprogresscircle:1.01@aar' implementation 'com.github.jorgecastilloprz:fabprogresscircle:1.01@aar'
implementation 'com.beust:klaxon:3.0.1'
implementation(name: 'libv2ray', ext: 'aar') implementation(name: 'libv2ray', ext: 'aar')
//implementation(name: 'tun2socks', ext: 'aar') //implementation(name: 'tun2socks', ext: 'aar')
@@ -1,10 +1,9 @@
package com.v2ray.ang package com.v2ray.ang
//import com.squareup.leakcanary.LeakCanary
import android.support.multidex.MultiDexApplication import android.support.multidex.MultiDexApplication
import android.support.v7.preference.PreferenceManager
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import me.dozen.dpreference.DPreference import me.dozen.dpreference.DPreference
import org.jetbrains.anko.defaultSharedPreferences
class AngApplication : MultiDexApplication() { class AngApplication : MultiDexApplication() {
companion object { companion object {
@@ -22,6 +21,7 @@ class AngApplication : MultiDexApplication() {
// LeakCanary.install(this) // LeakCanary.install(this)
val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
firstRun = defaultSharedPreferences.getInt(PREF_LAST_VERSION, 0) != BuildConfig.VERSION_CODE firstRun = defaultSharedPreferences.getInt(PREF_LAST_VERSION, 0) != BuildConfig.VERSION_CODE
if (firstRun) if (firstRun)
defaultSharedPreferences.edit().putInt(PREF_LAST_VERSION, BuildConfig.VERSION_CODE).apply() defaultSharedPreferences.edit().putInt(PREF_LAST_VERSION, BuildConfig.VERSION_CODE).apply()
@@ -2,6 +2,7 @@ package com.v2ray.ang.extension
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.widget.Toast
import com.v2ray.ang.AngApplication import com.v2ray.ang.AngApplication
import me.dozen.dpreference.DPreference import me.dozen.dpreference.DPreference
import org.json.JSONObject import org.json.JSONObject
@@ -17,6 +18,17 @@ val Context.v2RayApplication: AngApplication
val Context.defaultDPreference: DPreference val Context.defaultDPreference: DPreference
get() = v2RayApplication.defaultDPreference get() = v2RayApplication.defaultDPreference
inline fun Context.toast(message: Int): Toast = Toast
.makeText(this, message, Toast.LENGTH_SHORT)
.apply {
show()
}
inline fun Context.toast(message: CharSequence): Toast = Toast
.makeText(this, message, Toast.LENGTH_SHORT)
.apply {
show()
}
fun JSONObject.putOpt(pair: Pair<String, Any>) = putOpt(pair.first, pair.second)!! fun JSONObject.putOpt(pair: Pair<String, Any>) = putOpt(pair.first, pair.second)!!
fun JSONObject.putOpt(pairs: Map<String, Any>) = pairs.forEach { putOpt(it.key to it.value) } fun JSONObject.putOpt(pairs: Map<String, Any>) = pairs.forEach { putOpt(it.key to it.value) }
@@ -16,7 +16,9 @@ import com.v2ray.ang.extension.defaultDPreference
import com.v2ray.ang.ui.PerAppProxyActivity import com.v2ray.ang.ui.PerAppProxyActivity
import com.v2ray.ang.ui.SettingsActivity import com.v2ray.ang.ui.SettingsActivity
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import org.jetbrains.anko.doAsync import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.lang.ref.SoftReference import java.lang.ref.SoftReference
@@ -58,8 +60,6 @@ class V2RayVpnService : VpnService(), ServiceControl {
} }
} }
private var listeningForDefaultNetwork = false
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@@ -153,8 +153,11 @@ class V2RayVpnService : VpnService(), ServiceControl {
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
connectivity.requestNetwork(defaultNetworkRequest, defaultNetworkCallback) try {
listeningForDefaultNetwork = true connectivity.requestNetwork(defaultNetworkRequest, defaultNetworkCallback)
} catch (ignored: Exception) {
// ignored
}
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@@ -162,15 +165,20 @@ class V2RayVpnService : VpnService(), ServiceControl {
} }
// Create a new interface using the builder and save the parameters. // Create a new interface using the builder and save the parameters.
mInterface = builder.establish() try {
sendFd() mInterface = builder.establish()!!
} catch (e: Exception) {
// non-nullable lateinit var
e.printStackTrace()
stopV2Ray()
}
} }
private fun sendFd() { private fun sendFd() {
val fd = mInterface.fileDescriptor val fd = mInterface.fileDescriptor
val path = File(Utils.packagePath(applicationContext), "sock_path").absolutePath val path = File(Utils.packagePath(applicationContext), "sock_path").absolutePath
doAsync { GlobalScope.launch(Dispatchers.IO) {
var tries = 0 var tries = 0
while (true) try { while (true) try {
Thread.sleep(50L shl tries) Thread.sleep(50L shl tries)
@@ -200,9 +208,12 @@ class V2RayVpnService : VpnService(), ServiceControl {
// val emptyInfo = VpnNetworkInfo() // val emptyInfo = VpnNetworkInfo()
// val info = loadVpnNetworkInfo(configName, emptyInfo)!! + (lastNetworkInfo ?: emptyInfo) // val info = loadVpnNetworkInfo(configName, emptyInfo)!! + (lastNetworkInfo ?: emptyInfo)
// saveVpnNetworkInfo(configName, info) // saveVpnNetworkInfo(configName, info)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && listeningForDefaultNetwork) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
connectivity.unregisterNetworkCallback(defaultNetworkCallback) try {
listeningForDefaultNetwork = false connectivity.unregisterNetworkCallback(defaultNetworkCallback)
} catch (ignored: Exception) {
// ignored
}
} }
V2RayServiceManager.stopV2rayPoint() V2RayServiceManager.stopV2rayPoint()
@@ -13,11 +13,7 @@ import android.support.v7.widget.Toolbar
import android.util.Log import android.util.Log
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
//import com.v2ray.ang.InappBuyActivity
import com.v2ray.ang.R import com.v2ray.ang.R
import org.jetbrains.anko.startActivity
abstract class BaseDrawerActivity : BaseActivity() { abstract class BaseDrawerActivity : BaseActivity() {
companion object { companion object {
@@ -58,7 +54,7 @@ abstract class BaseDrawerActivity : BaseActivity() {
R.id.sub_setting -> activityClass = SubSettingActivity::class.java R.id.sub_setting -> activityClass = SubSettingActivity::class.java
R.id.settings -> activityClass = SettingsActivity::class.java R.id.settings -> activityClass = SettingsActivity::class.java
R.id.logcat -> { R.id.logcat -> {
startActivity<LogcatActivity>() startActivity(Intent(this@BaseDrawerActivity, LogcatActivity::class.java))
return return
} }
R.id.donate -> { R.id.donate -> {
@@ -8,12 +8,12 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_logcat.* import kotlinx.android.synthetic.main.activity_logcat.*
import org.jetbrains.anko.doAsync import kotlinx.coroutines.Dispatchers
import org.jetbrains.anko.toast import kotlinx.coroutines.GlobalScope
import org.jetbrains.anko.uiThread import kotlinx.coroutines.launch
import java.io.IOException import java.io.IOException
import java.util.LinkedHashSet import java.util.LinkedHashSet
@@ -34,7 +34,7 @@ class LogcatActivity : BaseActivity() {
try { try {
pb_waiting.visibility = View.VISIBLE pb_waiting.visibility = View.VISIBLE
doAsync { GlobalScope.launch(Dispatchers.Default) {
if (shouldFlushLog) { if (shouldFlushLog) {
val lst = LinkedHashSet<String>() val lst = LinkedHashSet<String>()
lst.add("logcat") lst.add("logcat")
@@ -54,7 +54,7 @@ class LogcatActivity : BaseActivity() {
// InputStreamReader(process.inputStream)) // InputStreamReader(process.inputStream))
// val allText = bufferedReader.use(BufferedReader::readText) // val allText = bufferedReader.use(BufferedReader::readText)
val allText = process.inputStream.bufferedReader().use { it.readText() } val allText = process.inputStream.bufferedReader().use { it.readText() }
uiThread { launch(Dispatchers.Main) {
tv_logcat.text = allText tv_logcat.text = allText
tv_logcat.movementMethod = ScrollingMovementMethod() tv_logcat.movementMethod = ScrollingMovementMethod()
pb_waiting.visibility = View.GONE pb_waiting.visibility = View.GONE
@@ -18,7 +18,6 @@ import android.view.KeyEvent
import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig
import com.v2ray.ang.util.MessageUtil import com.v2ray.ang.util.MessageUtil
import com.v2ray.ang.util.V2rayConfigUtil import com.v2ray.ang.util.V2rayConfigUtil
import org.jetbrains.anko.*
import java.lang.ref.SoftReference import java.lang.ref.SoftReference
import java.net.URL import java.net.URL
import android.content.IntentFilter import android.content.IntentFilter
@@ -30,7 +29,7 @@ import android.util.Log
import com.v2ray.ang.BuildConfig import com.v2ray.ang.BuildConfig
import com.v2ray.ang.dto.EConfigType import com.v2ray.ang.dto.EConfigType
import com.v2ray.ang.extension.defaultDPreference import com.v2ray.ang.extension.defaultDPreference
//import com.v2ray.ang.InappBuyActivity import com.v2ray.ang.extension.toast
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -52,10 +51,10 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
field = value field = value
adapter.changeable = !value adapter.changeable = !value
if (value) { if (value) {
fab.imageResource = R.drawable.ic_v fab.setImageResource(R.drawable.ic_v)
tv_test_state.text = getString(R.string.connection_connected) tv_test_state.text = getString(R.string.connection_connected)
} else { } else {
fab.imageResource = R.drawable.ic_v_idle fab.setImageResource(R.drawable.ic_v_idle)
tv_test_state.text = getString(R.string.connection_not_connected) tv_test_state.text = getString(R.string.connection_not_connected)
} }
hideCircle() hideCircle()
@@ -63,7 +62,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
private val adapter by lazy { MainRecyclerAdapter(this) } private val adapter by lazy { MainRecyclerAdapter(this) }
private var mItemTouchHelper: ItemTouchHelper? = null private var mItemTouchHelper: ItemTouchHelper? = null
private val testingJobs = ArrayList<Job>() private val tcpingTestScope by lazy { CoroutineScope(Dispatchers.IO) }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -90,9 +89,9 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
val socksPort = 10808//Utils.parseInt(defaultDPreference.getPrefString(SettingsActivity.PREF_SOCKS_PORT, "10808")) val socksPort = 10808//Utils.parseInt(defaultDPreference.getPrefString(SettingsActivity.PREF_SOCKS_PORT, "10808"))
tv_test_state.text = getString(R.string.connection_test_testing) tv_test_state.text = getString(R.string.connection_test_testing)
doAsync { GlobalScope.launch(Dispatchers.IO) {
val result = Utils.testConnection(this@MainActivity, socksPort) val result = Utils.testConnection(this@MainActivity, socksPort)
uiThread { launch(Dispatchers.Main) {
tv_test_state.text = Utils.getEditable(result) tv_test_state.text = Utils.getEditable(result)
} }
} }
@@ -188,6 +187,9 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
return true return true
} }
private fun getOptionIntent() = Intent().putExtra("position", -1)
.putExtra("isRunning", isRunning)
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.import_qrcode -> { R.id.import_qrcode -> {
importQRcode(REQUEST_SCAN) importQRcode(REQUEST_SCAN)
@@ -198,17 +200,17 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
true true
} }
R.id.import_manually_vmess -> { R.id.import_manually_vmess -> {
startActivity<ServerActivity>("position" to -1, "isRunning" to isRunning) startActivity(getOptionIntent().setClass(this, ServerActivity::class.java))
adapter.updateConfigList() adapter.updateConfigList()
true true
} }
R.id.import_manually_ss -> { R.id.import_manually_ss -> {
startActivity<Server3Activity>("position" to -1, "isRunning" to isRunning) startActivity(getOptionIntent().setClass(this, Server3Activity::class.java))
adapter.updateConfigList() adapter.updateConfigList()
true true
} }
R.id.import_manually_socks -> { R.id.import_manually_socks -> {
startActivity<Server4Activity>("position" to -1, "isRunning" to isRunning) startActivity(getOptionIntent().setClass(this, Server4Activity::class.java))
adapter.updateConfigList() adapter.updateConfigList()
true true
} }
@@ -249,10 +251,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
} }
R.id.ping_all -> { R.id.ping_all -> {
testingJobs.forEach { tcpingTestScope.coroutineContext[Job]?.cancelChildren()
it.cancel()
}
testingJobs.clear()
Utils.closeAllTcpSockets() Utils.closeAllTcpSockets()
for (k in 0 until configs.vmess.count()) { for (k in 0 until configs.vmess.count()) {
configs.vmess[k].testResult = "" configs.vmess[k].testResult = ""
@@ -267,16 +266,14 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
serverAddress = serverOutbound.getServerAddress() ?: continue serverAddress = serverOutbound.getServerAddress() ?: continue
serverPort = serverOutbound.getServerPort() ?: continue serverPort = serverOutbound.getServerPort() ?: continue
} }
testingJobs.add(GlobalScope.launch(Dispatchers.IO) { tcpingTestScope.launch {
configs.vmess.getOrNull(k)?.let { // check null in case array is modified during testing configs.vmess.getOrNull(k)?.let { // check null in case array is modified during testing
it.testResult = Utils.tcping(serverAddress, serverPort) it.testResult = Utils.tcping(serverAddress, serverPort)
val myJob = coroutineContext[Job]
launch(Dispatchers.Main) { launch(Dispatchers.Main) {
testingJobs.remove(myJob)
adapter.updateSelectedItem(k) adapter.updateSelectedItem(k)
} }
} }
}) }
} }
true true
} }
@@ -306,7 +303,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
.request(Manifest.permission.CAMERA) .request(Manifest.permission.CAMERA)
.subscribe { .subscribe {
if (it) if (it)
startActivityForResult<ScannerActivity>(requestCode) startActivityForResult(Intent(this, ScannerActivity::class.java), requestCode)
else else
toast(R.string.toast_permission_denied) toast(R.string.toast_permission_denied)
} }
@@ -392,9 +389,14 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
toast(R.string.toast_invalid_url) toast(R.string.toast_invalid_url)
return false return false
} }
doAsync { GlobalScope.launch(Dispatchers.IO) {
val configText = URL(url).readText() val configText = try {
uiThread { URL(url).readText()
} catch (e: Exception) {
e.printStackTrace()
""
}
launch(Dispatchers.Main) {
importCustomizeConfig(configText) importCustomizeConfig(configText)
} }
} }
@@ -426,9 +428,14 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
continue continue
} }
Log.d("Main", url) Log.d("Main", url)
doAsync { GlobalScope.launch(Dispatchers.IO) {
val configText = URL(url).readText() val configText = try {
uiThread { URL(url).readText()
} catch (e: Exception) {
e.printStackTrace()
""
}
launch(Dispatchers.Main) {
importBatchConfig(Utils.decode(configText), id) importBatchConfig(Utils.decode(configText), id)
} }
} }
@@ -574,10 +581,11 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
when (item.itemId) { when (item.itemId) {
//R.id.server_profile -> activityClass = MainActivity::class.java //R.id.server_profile -> activityClass = MainActivity::class.java
R.id.sub_setting -> { R.id.sub_setting -> {
startActivity<SubSettingActivity>() startActivity(Intent(this, SubSettingActivity::class.java))
} }
R.id.settings -> { R.id.settings -> {
startActivity<SettingsActivity>("isRunning" to isRunning) startActivity(Intent(this, SettingsActivity::class.java)
.putExtra("isRunning", isRunning))
} }
R.id.feedback -> { R.id.feedback -> {
Utils.openUri(this, AppConfig.v2rayNGIssues) Utils.openUri(this, AppConfig.v2rayNGIssues)
@@ -589,7 +597,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
// startActivity<InappBuyActivity>() // startActivity<InappBuyActivity>()
} }
R.id.logcat -> { R.id.logcat -> {
startActivity<LogcatActivity>() startActivity(Intent(this, LogcatActivity::class.java))
} }
} }
drawer_layout.closeDrawer(GravityCompat.START) drawer_layout.closeDrawer(GravityCompat.START)
@@ -1,15 +1,18 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.support.v7.app.AlertDialog
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.text.TextUtils import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.dto.EConfigType import com.v2ray.ang.dto.EConfigType
import com.v2ray.ang.extension.defaultDPreference import com.v2ray.ang.extension.toast
import com.v2ray.ang.helper.ItemTouchHelperAdapter import com.v2ray.ang.helper.ItemTouchHelperAdapter
import com.v2ray.ang.helper.ItemTouchHelperViewHolder import com.v2ray.ang.helper.ItemTouchHelperViewHolder
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
@@ -17,7 +20,6 @@ import com.v2ray.ang.util.Utils
import com.v2ray.ang.util.V2rayConfigUtil import com.v2ray.ang.util.V2rayConfigUtil
import kotlinx.android.synthetic.main.item_qrcode.view.* import kotlinx.android.synthetic.main.item_qrcode.view.*
import kotlinx.android.synthetic.main.item_recycler_main.view.* import kotlinx.android.synthetic.main.item_recycler_main.view.*
import org.jetbrains.anko.*
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -60,7 +62,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
holder.name.text = remarks holder.name.text = remarks
holder.radio.isChecked = (position == configs.index) holder.radio.isChecked = (position == configs.index)
holder.itemView.backgroundColor = Color.TRANSPARENT holder.itemView.setBackgroundColor(Color.TRANSPARENT)
holder.test_result.text = test_result holder.test_result.text = test_result
if (TextUtils.isEmpty(subid)) { if (TextUtils.isEmpty(subid)) {
@@ -85,7 +87,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
} }
holder.layout_share.setOnClickListener { holder.layout_share.setOnClickListener {
mActivity.selector(null, shareOptions) { dialogInterface, i -> AlertDialog.Builder(mActivity).setItems(shareOptions.toTypedArray()) { _, i ->
try { try {
when (i) { when (i) {
0 -> { 0 -> {
@@ -94,14 +96,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
} else { } else {
val iv = mActivity.layoutInflater.inflate(R.layout.item_qrcode, null) val iv = mActivity.layoutInflater.inflate(R.layout.item_qrcode, null)
iv.iv_qcode.setImageBitmap(AngConfigManager.share2QRCode(position)) iv.iv_qcode.setImageBitmap(AngConfigManager.share2QRCode(position))
AlertDialog.Builder(mActivity).setView(iv).show()
mActivity.alert {
customView {
linearLayout {
addView(iv)
}
}
}.show()
} }
} }
1 -> { 1 -> {
@@ -117,18 +112,20 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
} }.show()
} }
holder.layout_edit.setOnClickListener { holder.layout_edit.setOnClickListener {
val intent = Intent().putExtra("position", position)
.putExtra("isRunning", !changeable)
if (configType == EConfigType.VMESS) { if (configType == EConfigType.VMESS) {
mActivity.startActivity<ServerActivity>("position" to position, "isRunning" to !changeable) mActivity.startActivity(intent.setClass(mActivity, ServerActivity::class.java))
} else if (configType == EConfigType.CUSTOM) { } else if (configType == EConfigType.CUSTOM) {
mActivity.startActivity<Server2Activity>("position" to position, "isRunning" to !changeable) mActivity.startActivity(intent.setClass(mActivity, Server2Activity::class.java))
} else if (configType == EConfigType.SHADOWSOCKS) { } else if (configType == EConfigType.SHADOWSOCKS) {
mActivity.startActivity<Server3Activity>("position" to position, "isRunning" to !changeable) mActivity.startActivity(intent.setClass(mActivity, Server3Activity::class.java))
} else if (configType == EConfigType.SOCKS) { } else if (configType == EConfigType.SOCKS) {
mActivity.startActivity<Server4Activity>("position" to position, "isRunning" to !changeable) mActivity.startActivity(intent.setClass(mActivity, Server4Activity::class.java))
} }
} }
holder.layout_remove.setOnClickListener { holder.layout_remove.setOnClickListener {
@@ -183,10 +180,10 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
when (viewType) { when (viewType) {
VIEW_TYPE_ITEM -> VIEW_TYPE_ITEM ->
return MainViewHolder(parent.context.layoutInflater return MainViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_recycler_main, parent, false)) .inflate(R.layout.item_recycler_main, parent, false))
else -> else ->
return FooterViewHolder(parent.context.layoutInflater return FooterViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_recycler_footer, parent, false)) .inflate(R.layout.item_recycler_footer, parent, false))
} }
} }
@@ -4,6 +4,8 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.support.v7.widget.DividerItemDecoration
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
@@ -12,7 +14,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.animation.AccelerateInterpolator import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import com.dinuscxj.itemdecoration.LinearDividerItemDecoration
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.extension.defaultDPreference import com.v2ray.ang.extension.defaultDPreference
import com.v2ray.ang.util.AppManagerUtil import com.v2ray.ang.util.AppManagerUtil
@@ -25,11 +26,12 @@ import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig
import com.v2ray.ang.dto.AppInfo import com.v2ray.ang.dto.AppInfo
import com.v2ray.ang.extension.toast
import com.v2ray.ang.extension.v2RayApplication import com.v2ray.ang.extension.v2RayApplication
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import org.jetbrains.anko.doAsync import kotlinx.coroutines.Dispatchers
import org.jetbrains.anko.toast import kotlinx.coroutines.GlobalScope
import org.jetbrains.anko.uiThread import kotlinx.coroutines.launch
import java.net.URL import java.net.URL
class PerAppProxyActivity : BaseActivity() { class PerAppProxyActivity : BaseActivity() {
@@ -47,8 +49,7 @@ class PerAppProxyActivity : BaseActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
val dividerItemDecoration = LinearDividerItemDecoration( val dividerItemDecoration = DividerItemDecoration(this, LinearLayoutManager.VERTICAL)
this, LinearDividerItemDecoration.LINEAR_DIVIDER_VERTICAL)
recycler_view.addItemDecoration(dividerItemDecoration) recycler_view.addItemDecoration(dividerItemDecoration)
val blacklist = defaultDPreference.getPrefStringSet(PREF_PER_APP_PROXY_SET, null) val blacklist = defaultDPreference.getPrefStringSet(PREF_PER_APP_PROXY_SET, null)
@@ -220,9 +221,14 @@ class PerAppProxyActivity : BaseActivity() {
private fun selectProxyApp() { private fun selectProxyApp() {
toast(R.string.msg_downloading_content) toast(R.string.msg_downloading_content)
val url = AppConfig.androidpackagenamelistUrl val url = AppConfig.androidpackagenamelistUrl
doAsync { GlobalScope.launch(Dispatchers.IO) {
val content = URL(url).readText() val content = try {
uiThread { URL(url).readText()
} catch (e: Exception) {
e.printStackTrace()
""
}
launch(Dispatchers.Main) {
Log.d("selectProxyApp", content) Log.d("selectProxyApp", content)
selectProxyApp(content) selectProxyApp(content)
toast(R.string.toast_success) toast(R.string.toast_success)
@@ -276,4 +282,4 @@ class PerAppProxyActivity : BaseActivity() {
} }
return true return true
} }
} }
@@ -2,14 +2,12 @@ package com.v2ray.ang.ui
import android.graphics.Color import android.graphics.Color
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AppInfo import com.v2ray.ang.dto.AppInfo
import kotlinx.android.synthetic.main.item_recycler_bypass_list.view.* import kotlinx.android.synthetic.main.item_recycler_bypass_list.view.*
import org.jetbrains.anko.image
import org.jetbrains.anko.layoutInflater
import org.jetbrains.anko.textColor
import java.util.* import java.util.*
class PerAppProxyAdapter(val activity: BaseActivity, val apps: List<AppInfo>, blacklist: MutableSet<String>?) : class PerAppProxyAdapter(val activity: BaseActivity, val apps: List<AppInfo>, blacklist: MutableSet<String>?) :
@@ -45,7 +43,7 @@ class PerAppProxyAdapter(val activity: BaseActivity, val apps: List<AppInfo>, bl
// VIEW_TYPE_ITEM -> AppViewHolder(ctx.layoutInflater // VIEW_TYPE_ITEM -> AppViewHolder(ctx.layoutInflater
// .inflate(R.layout.item_recycler_bypass_list, parent, false)) // .inflate(R.layout.item_recycler_bypass_list, parent, false))
else -> AppViewHolder(ctx.layoutInflater else -> AppViewHolder(LayoutInflater.from(ctx)
.inflate(R.layout.item_recycler_bypass_list, parent, false)) .inflate(R.layout.item_recycler_bypass_list, parent, false))
} }
@@ -68,17 +66,17 @@ class PerAppProxyAdapter(val activity: BaseActivity, val apps: List<AppInfo>, bl
fun bind(appInfo: AppInfo) { fun bind(appInfo: AppInfo) {
this.appInfo = appInfo this.appInfo = appInfo
icon.image = appInfo.appIcon icon.setImageDrawable(appInfo.appIcon)
// name.text = appInfo.appName // name.text = appInfo.appName
checkBox.isChecked = inBlacklist checkBox.isChecked = inBlacklist
package_name.text = appInfo.packageName package_name.text = appInfo.packageName
if (appInfo.isSystemApp) { if (appInfo.isSystemApp) {
name.text = String.format("** %1s", appInfo.appName) name.text = String.format("** %1s", appInfo.appName)
name.textColor = Color.RED name.setTextColor(Color.RED)
} else { } else {
name.text = appInfo.appName name.text = appInfo.appName
name.textColor = Color.DKGRAY name.setTextColor(Color.DKGRAY)
} }
itemView.setOnClickListener(this) itemView.setOnClickListener(this)
@@ -94,4 +92,4 @@ class PerAppProxyAdapter(val activity: BaseActivity, val apps: List<AppInfo>, bl
} }
} }
} }
} }
@@ -1,30 +1,24 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.Manifest import android.Manifest
import android.app.Activity.RESULT_OK import android.app.Activity.RESULT_OK
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.text.TextUtils
import android.util.Log
import android.view.* import android.view.*
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.extension.defaultDPreference import com.v2ray.ang.extension.defaultDPreference
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.fragment_routing_settings.* import kotlinx.android.synthetic.main.fragment_routing_settings.*
import org.jetbrains.anko.toast
import android.view.MenuInflater import android.view.MenuInflater
import com.tbruyelle.rxpermissions.RxPermissions import com.tbruyelle.rxpermissions.RxPermissions
import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig
import org.jetbrains.anko.doAsync import com.v2ray.ang.extension.toast
import org.jetbrains.anko.startActivityForResult import kotlinx.coroutines.Dispatchers
import org.jetbrains.anko.support.v4.startActivityForResult import kotlinx.coroutines.GlobalScope
import org.jetbrains.anko.support.v4.toast import kotlinx.coroutines.launch
import org.jetbrains.anko.uiThread
import java.net.URL import java.net.URL
class RoutingSettingsFragment : Fragment() { class RoutingSettingsFragment : Fragment() {
companion object { companion object {
private const val routing_arg = "routing_arg" private const val routing_arg = "routing_arg"
@@ -96,7 +90,7 @@ class RoutingSettingsFragment : Fragment() {
.request(Manifest.permission.CAMERA) .request(Manifest.permission.CAMERA)
.subscribe { .subscribe {
if (it) if (it)
startActivityForResult<ScannerActivity>(requestCode) startActivityForResult(Intent(activity, ScannerActivity::class.java), requestCode)
else else
activity?.toast(R.string.toast_permission_denied) activity?.toast(R.string.toast_permission_denied)
} }
@@ -118,12 +112,17 @@ class RoutingSettingsFragment : Fragment() {
} }
} }
toast(R.string.msg_downloading_content) activity?.toast(R.string.msg_downloading_content)
doAsync { GlobalScope.launch(Dispatchers.IO) {
val content = URL(url).readText() val content = try {
uiThread { URL(url).readText()
et_routing_content.text = Utils.getEditable(content!!) } catch (e: Exception) {
toast(R.string.toast_success) e.printStackTrace()
""
}
launch(Dispatchers.Main) {
et_routing_content.text = Utils.getEditable(content)
activity?.toast(R.string.toast_success)
} }
} }
return true return true
@@ -6,7 +6,7 @@ import com.tbruyelle.rxpermissions.RxPermissions
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import android.os.Bundle import android.os.Bundle
import org.jetbrains.anko.* import com.v2ray.ang.extension.toast
class ScScannerActivity : BaseActivity() { class ScScannerActivity : BaseActivity() {
companion object { companion object {
@@ -24,7 +24,7 @@ class ScScannerActivity : BaseActivity() {
.request(Manifest.permission.CAMERA) .request(Manifest.permission.CAMERA)
.subscribe { .subscribe {
if (it) if (it)
startActivityForResult<ScannerActivity>(requestCode) startActivityForResult(Intent(this, ScannerActivity::class.java), requestCode)
else else
toast(R.string.toast_permission_denied) toast(R.string.toast_permission_denied)
} }
@@ -43,10 +43,10 @@ class ScScannerActivity : BaseActivity() {
} else { } else {
toast(R.string.toast_failure) toast(R.string.toast_failure)
} }
startActivity<MainActivity>() startActivity(Intent(this, MainActivity::class.java))
} }
} }
finish() finish()
} }
} }
@@ -7,23 +7,13 @@ import com.google.zxing.Result
import me.dm7.barcodescanner.zxing.ZXingScannerView import me.dm7.barcodescanner.zxing.ZXingScannerView
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.icu.util.TimeUnit
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.google.zxing.BarcodeFormat import com.google.zxing.BarcodeFormat
import com.tbruyelle.rxpermissions.RxPermissions import com.tbruyelle.rxpermissions.RxPermissions
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.QRCodeDecoder import com.v2ray.ang.util.QRCodeDecoder
import org.jetbrains.anko.toast
import rx.Observable
import android.os.SystemClock
import kotlinx.android.synthetic.main.activity_main.*
import rx.Observer
import rx.android.schedulers.AndroidSchedulers
import javax.xml.datatype.DatatypeConstants.SECONDS
class ScannerActivity : BaseActivity(), ZXingScannerView.ResultHandler { class ScannerActivity : BaseActivity(), ZXingScannerView.ResultHandler {
companion object { companion object {
@@ -1,6 +1,7 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.text.Editable import android.text.Editable
import android.text.TextUtils import android.text.TextUtils
import android.view.Menu import android.view.Menu
@@ -10,13 +11,12 @@ import com.v2ray.ang.AppConfig
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.extension.defaultDPreference import com.v2ray.ang.extension.defaultDPreference
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_server2.* import kotlinx.android.synthetic.main.activity_server2.*
import org.jetbrains.anko.*
import java.lang.Exception import java.lang.Exception
class Server2Activity : BaseActivity() { class Server2Activity : BaseActivity() {
companion object { companion object {
private const val REQUEST_SCAN = 1 private const val REQUEST_SCAN = 1
@@ -112,17 +112,16 @@ class Server2Activity : BaseActivity() {
*/ */
fun deleteServer(): Boolean { fun deleteServer(): Boolean {
if (edit_index >= 0) { if (edit_index >= 0) {
alert(R.string.del_config_comfirm) { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
positiveButton(android.R.string.ok) { .setPositiveButton(android.R.string.ok) { _, _ ->
if (AngConfigManager.removeServer(edit_index) == 0) { if (AngConfigManager.removeServer(edit_index) == 0) {
toast(R.string.toast_success) toast(R.string.toast_success)
finish() finish()
} else { } else {
toast(R.string.toast_failure) toast(R.string.toast_failure)
}
} }
} .show()
show()
}
} else { } else {
} }
return true return true
@@ -158,4 +157,4 @@ class Server2Activity : BaseActivity() {
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
@@ -1,16 +1,16 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.text.TextUtils import android.text.TextUtils
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_server3.* import kotlinx.android.synthetic.main.activity_server3.*
import org.jetbrains.anko.*
class Server3Activity : BaseActivity() { class Server3Activity : BaseActivity() {
companion object { companion object {
@@ -126,17 +126,16 @@ class Server3Activity : BaseActivity() {
*/ */
fun deleteServer(): Boolean { fun deleteServer(): Boolean {
if (edit_index >= 0) { if (edit_index >= 0) {
alert(R.string.del_config_comfirm) { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
positiveButton(android.R.string.ok) { .setPositiveButton(android.R.string.ok) { _, _ ->
if (AngConfigManager.removeServer(edit_index) == 0) { if (AngConfigManager.removeServer(edit_index) == 0) {
toast(R.string.toast_success) toast(R.string.toast_success)
finish() finish()
} else { } else {
toast(R.string.toast_failure) toast(R.string.toast_failure)
}
} }
} .show()
show()
}
} else { } else {
} }
return true return true
@@ -172,4 +171,4 @@ class Server3Activity : BaseActivity() {
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
@@ -1,16 +1,16 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.text.TextUtils import android.text.TextUtils
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_server4.* import kotlinx.android.synthetic.main.activity_server4.*
import org.jetbrains.anko.*
class Server4Activity : BaseActivity() { class Server4Activity : BaseActivity() {
companion object { companion object {
@@ -110,17 +110,16 @@ class Server4Activity : BaseActivity() {
*/ */
fun deleteServer(): Boolean { fun deleteServer(): Boolean {
if (edit_index >= 0) { if (edit_index >= 0) {
alert(R.string.del_config_comfirm) { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
positiveButton(android.R.string.ok) { .setPositiveButton(android.R.string.ok) { _, _ ->
if (AngConfigManager.removeServer(edit_index) == 0) { if (AngConfigManager.removeServer(edit_index) == 0) {
toast(R.string.toast_success) toast(R.string.toast_success)
finish() finish()
} else { } else {
toast(R.string.toast_failure) toast(R.string.toast_failure)
}
} }
} .show()
show()
}
} else { } else {
} }
return true return true
@@ -156,4 +155,4 @@ class Server4Activity : BaseActivity() {
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
@@ -1,16 +1,16 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.text.TextUtils import android.text.TextUtils
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_server.* import kotlinx.android.synthetic.main.activity_server.*
import org.jetbrains.anko.*
class ServerActivity : BaseActivity() { class ServerActivity : BaseActivity() {
companion object { companion object {
@@ -169,17 +169,16 @@ class ServerActivity : BaseActivity() {
*/ */
fun deleteServer(): Boolean { fun deleteServer(): Boolean {
if (edit_index >= 0) { if (edit_index >= 0) {
alert(R.string.del_config_comfirm) { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
positiveButton(android.R.string.ok) { .setPositiveButton(android.R.string.ok) { _, _ ->
if (AngConfigManager.removeServer(edit_index) == 0) { if (AngConfigManager.removeServer(edit_index) == 0) {
toast(R.string.toast_success) toast(R.string.toast_success)
finish() finish()
} else { } else {
toast(R.string.toast_failure) toast(R.string.toast_failure)
}
} }
} .show()
show()
}
} else { } else {
} }
return true return true
@@ -215,4 +214,4 @@ class ServerActivity : BaseActivity() {
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
@@ -1,14 +1,13 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.v7.preference.* import android.support.v7.preference.*
import android.view.View import android.view.View
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import org.jetbrains.anko.defaultSharedPreferences
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
class SettingsActivity : BaseActivity() { class SettingsActivity : BaseActivity() {
companion object { companion object {
@@ -89,7 +88,7 @@ class SettingsActivity : BaseActivity() {
if (isRunning()) { if (isRunning()) {
Utils.stopVService(requireContext()) Utils.stopVService(requireContext())
} }
activity?.startActivity<PerAppProxyActivity>() startActivity(Intent(activity, PerAppProxyActivity::class.java))
perAppProxy.isChecked = true perAppProxy.isChecked = true
true true
} }
@@ -126,7 +125,7 @@ class SettingsActivity : BaseActivity() {
routingCustom.setOnPreferenceClickListener { routingCustom.setOnPreferenceClickListener {
if (isRunning()) if (isRunning())
Utils.stopVService(requireContext()) Utils.stopVService(requireContext())
activity?.startActivity<RoutingSettingsActivity>() startActivity(Intent(activity, RoutingSettingsActivity::class.java))
false false
} }
@@ -206,9 +205,10 @@ class SettingsActivity : BaseActivity() {
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
updatePerAppProxy(activity?.defaultSharedPreferences?.getString(AppConfig.PREF_MODE, "VPN")) val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
remoteDns.summary = activity?.defaultSharedPreferences?.getString(PREF_REMOTE_DNS, "") updatePerAppProxy(defaultSharedPreferences.getString(AppConfig.PREF_MODE, "VPN"))
domesticDns.summary = activity?.defaultSharedPreferences?.getString(PREF_DOMESTIC_DNS, "") remoteDns.summary = defaultSharedPreferences.getString(PREF_REMOTE_DNS, "")
domesticDns.summary = defaultSharedPreferences.getString(PREF_DOMESTIC_DNS, "")
if (remoteDns.summary == "") { if (remoteDns.summary == "") {
remoteDns.summary = AppConfig.DNS_AGENT remoteDns.summary = AppConfig.DNS_AGENT
@@ -223,10 +223,10 @@ class SettingsActivity : BaseActivity() {
} }
private fun updatePerAppProxy(mode: String?) { private fun updatePerAppProxy(mode: String?) {
val preference = activity?.defaultSharedPreferences ?: return
if (mode == "VPN") { if (mode == "VPN") {
perAppProxy.isEnabled = true perAppProxy.isEnabled = true
perAppProxy.isChecked = preference.getBoolean(PREF_PER_APP_PROXY, false) perAppProxy.isChecked = PreferenceManager.getDefaultSharedPreferences(activity)
.getBoolean(PREF_PER_APP_PROXY, false)
} else { } else {
perAppProxy.isEnabled = false perAppProxy.isEnabled = false
perAppProxy.isChecked = false perAppProxy.isChecked = false
@@ -1,16 +1,16 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.text.TextUtils import android.text.TextUtils
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.Utils import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_sub_edit.* import kotlinx.android.synthetic.main.activity_sub_edit.*
import org.jetbrains.anko.*
class SubEditActivity : BaseActivity() { class SubEditActivity : BaseActivity() {
@@ -95,17 +95,16 @@ class SubEditActivity : BaseActivity() {
*/ */
fun deleteServer(): Boolean { fun deleteServer(): Boolean {
if (edit_index >= 0) { if (edit_index >= 0) {
alert(R.string.del_config_comfirm) { AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
positiveButton(android.R.string.ok) { .setPositiveButton(android.R.string.ok) { _, _ ->
if (AngConfigManager.removeSubItem(edit_index) == 0) { if (AngConfigManager.removeSubItem(edit_index) == 0) {
toast(R.string.toast_success) toast(R.string.toast_success)
finish() finish()
} else { } else {
toast(R.string.toast_failure) toast(R.string.toast_failure)
}
} }
} .show()
show()
}
} else { } else {
} }
return true return true
@@ -135,4 +134,4 @@ class SubEditActivity : BaseActivity() {
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
} }
@@ -1,12 +1,12 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.content.Intent
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.v2ray.ang.R import com.v2ray.ang.R
import kotlinx.android.synthetic.main.activity_sub_setting.* import kotlinx.android.synthetic.main.activity_sub_setting.*
import android.os.Bundle import android.os.Bundle
import org.jetbrains.anko.startActivity
class SubSettingActivity : BaseActivity() { class SubSettingActivity : BaseActivity() {
@@ -40,7 +40,9 @@ class SubSettingActivity : BaseActivity() {
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.add_config -> { R.id.add_config -> {
startActivity<SubEditActivity>("position" to -1) startActivity(Intent(this, SubEditActivity::class.java)
.putExtra("position", -1)
)
adapter.updateConfigList() adapter.updateConfigList()
true true
} }
@@ -48,4 +50,4 @@ class SubSettingActivity : BaseActivity() {
} }
} }
@@ -1,14 +1,15 @@
package com.v2ray.ang.ui package com.v2ray.ang.ui
import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.AngConfig import com.v2ray.ang.dto.AngConfig
import com.v2ray.ang.util.AngConfigManager import com.v2ray.ang.util.AngConfigManager
import kotlinx.android.synthetic.main.item_recycler_sub_setting.view.* import kotlinx.android.synthetic.main.item_recycler_sub_setting.view.*
import org.jetbrains.anko.*
class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView.Adapter<SubSettingRecyclerAdapter.BaseViewHolder>() { class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView.Adapter<SubSettingRecyclerAdapter.BaseViewHolder>() {
@@ -28,17 +29,19 @@ class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView
holder.name.text = remarks holder.name.text = remarks
holder.url.text = url holder.url.text = url
holder.itemView.backgroundColor = Color.TRANSPARENT holder.itemView.setBackgroundColor(Color.TRANSPARENT)
holder.layout_edit.setOnClickListener { holder.layout_edit.setOnClickListener {
mActivity.startActivity<SubEditActivity>("position" to position) mActivity.startActivity(Intent(mActivity, SubEditActivity::class.java)
.putExtra("position", position)
)
} }
} else { } else {
} }
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
return MainViewHolder(parent.context.layoutInflater return MainViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_recycler_sub_setting, parent, false)) .inflate(R.layout.item_recycler_sub_setting, parent, false))
} }
@@ -24,18 +24,17 @@ import com.v2ray.ang.AppConfig
import com.v2ray.ang.R import com.v2ray.ang.R
import com.v2ray.ang.dto.EConfigType import com.v2ray.ang.dto.EConfigType
import com.v2ray.ang.extension.responseLength import com.v2ray.ang.extension.responseLength
import com.v2ray.ang.extension.toast
import com.v2ray.ang.extension.v2RayApplication import com.v2ray.ang.extension.v2RayApplication
import com.v2ray.ang.service.V2RayServiceManager import com.v2ray.ang.service.V2RayServiceManager
import com.v2ray.ang.ui.SettingsActivity import com.v2ray.ang.ui.SettingsActivity
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import me.dozen.dpreference.DPreference import me.dozen.dpreference.DPreference
import org.jetbrains.anko.toast
import java.io.IOException import java.io.IOException
import java.net.* import java.net.*
import libv2ray.Libv2ray import libv2ray.Libv2ray
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
object Utils { object Utils {
val tcpTestingSockets = ArrayList<Socket?>() val tcpTestingSockets = ArrayList<Socket?>()
+1 -36
View File
@@ -17,17 +17,6 @@
<copyright>Copyright(C) 2008-2011 The Android Open Source Project</copyright> <copyright>Copyright(C) 2008-2011 The Android Open Source Project</copyright>
<license>Apache Software License 2.0</license> <license>Apache Software License 2.0</license>
</notice> </notice>
<notice>
<name>Apache Commons Validator</name>
<url>http://commons.apache.org/proper/commons-collections/</url>
<copyright>Copyright(C) 2001-2014 The Apache Software Foundation</copyright>
<license>Apache Software License 2.0</license>
</notice>
<notice>
<name>anko</name>
<url>https://github.com/Kotlin/anko</url>
<license>Apache Software License 2.0</license>
</notice>
<notice> <notice>
<name>Google Gson</name> <name>Google Gson</name>
<url>https://github.com/google/gson</url> <url>https://github.com/google/gson</url>
@@ -52,33 +41,9 @@
<copyright>Copyright 2015 Square, Inc.</copyright> <copyright>Copyright 2015 Square, Inc.</copyright>
<license>Apache Software License 2.0</license> <license>Apache Software License 2.0</license>
</notice> </notice>
<notice>
<name>ReactiveNetwork</name>
<url>https://github.com/pwittchen/ReactiveNetwork</url>
<copyright>Copyright 2016 Piotr Wittchen</copyright>
<license>Apache Software License 2.0</license>
</notice>
<notice>
<name>RecyclerItemDecoration</name>
<url>https://github.com/dinuscxj/RecyclerItemDecoration</url>
<copyright>Copyright 2015-2019 dinus</copyright>
<license>Apache Software License 2.0</license>
</notice>
<notice>
<name>RxKotlin</name>
<url>https://github.com/ReactiveX/RxKotlin</url>
<copyright>Copyright 2012 Netflix, Inc.</copyright>
<license>Apache Software License 2.0</license>
</notice>
<notice> <notice>
<name>RxPermissions</name> <name>RxPermissions</name>
<url>https://github.com/tbruyelle/RxPermissions</url> <url>https://github.com/tbruyelle/RxPermissions</url>
<license>Apache Software License 2.0</license> <license>Apache Software License 2.0</license>
</notice> </notice>
<notice> </notices>
<name>RecyclerItemDecoration</name>
<url>https://github.com/dinuscxj/RecyclerItemDecoration</url>
<copyright>Copyright 2015-2019 dinus</copyright>
<license>Apache Software License 2.0</license>
</notice>
</notices>
-1
View File
@@ -13,7 +13,6 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Fri Jun 02 14:08:42 CST 2017 #Fri Jun 02 14:08:42 CST 2017
ankoVersion=0.10.8
kotlinVersion=1.4.0 kotlinVersion=1.4.0
supportLibVersion=28.0.0 supportLibVersion=28.0.0
buildToolsVer=29.0.3 buildToolsVer=29.0.3