Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
b00ae42a
Commit
b00ae42a
authored
Jun 11, 2020
by
Mygod
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into r
parents
1160f135
f2c83f97
Changes
44
Hide whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
270 additions
and
209 deletions
+270
-209
.circleci/config.yml
.circleci/config.yml
+1
-1
.github/ISSUE_TEMPLATE/bug_report.md
.github/ISSUE_TEMPLATE/bug_report.md
+3
-0
.github/ISSUE_TEMPLATE/feature_request.md
.github/ISSUE_TEMPLATE/feature_request.md
+3
-0
.github/ISSUE_TEMPLATE/questions-support-requests-other.md
.github/ISSUE_TEMPLATE/questions-support-requests-other.md
+3
-0
.gitmodules
.gitmodules
+1
-1
README.md
README.md
+5
-5
build.gradle.kts
build.gradle.kts
+9
-2
buildSrc/src/main/kotlin/Helpers.kt
buildSrc/src/main/kotlin/Helpers.kt
+5
-3
core/build.gradle.kts
core/build.gradle.kts
+31
-28
core/lint.xml
core/lint.xml
+1
-0
core/src/main/AndroidManifest.xml
core/src/main/AndroidManifest.xml
+12
-33
core/src/main/java/com/github/shadowsocks/BootReceiver.kt
core/src/main/java/com/github/shadowsocks/BootReceiver.kt
+1
-4
core/src/main/java/com/github/shadowsocks/Core.kt
core/src/main/java/com/github/shadowsocks/Core.kt
+12
-9
core/src/main/java/com/github/shadowsocks/UrlImportActivity.kt
...src/main/java/com/github/shadowsocks/UrlImportActivity.kt
+1
-1
core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt
core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt
+15
-10
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
+10
-8
core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt
...src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt
+9
-3
core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
.../src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
+3
-3
core/src/main/java/com/github/shadowsocks/bg/TrafficMonitor.kt
...src/main/java/com/github/shadowsocks/bg/TrafficMonitor.kt
+1
-1
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
+30
-22
core/src/main/java/com/github/shadowsocks/database/ProfileManager.kt
...in/java/com/github/shadowsocks/database/ProfileManager.kt
+6
-2
core/src/main/java/com/github/shadowsocks/net/DnsResolverCompat.kt
...main/java/com/github/shadowsocks/net/DnsResolverCompat.kt
+16
-13
core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt
core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt
+1
-4
core/src/main/java/com/github/shadowsocks/plugin/PluginList.kt
...src/main/java/com/github/shadowsocks/plugin/PluginList.kt
+9
-1
core/src/main/java/com/github/shadowsocks/plugin/PluginManager.kt
.../main/java/com/github/shadowsocks/plugin/PluginManager.kt
+6
-0
core/src/main/java/com/github/shadowsocks/utils/DirectBoot.kt
.../src/main/java/com/github/shadowsocks/utils/DirectBoot.kt
+2
-2
core/src/main/java/com/github/shadowsocks/utils/Utils.kt
core/src/main/java/com/github/shadowsocks/utils/Utils.kt
+0
-5
core/src/main/res/values/arrays.xml
core/src/main/res/values/arrays.xml
+2
-2
core/src/main/rust/linker-wrapper.py
core/src/main/rust/linker-wrapper.py
+18
-0
core/src/main/rust/shadowsocks-rust
core/src/main/rust/shadowsocks-rust
+1
-1
detekt.yml
detekt.yml
+37
-27
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.jar
+0
-0
gradle/wrapper/gradle-wrapper.properties
gradle/wrapper/gradle-wrapper.properties
+1
-1
gradlew
gradlew
+2
-0
gradlew.bat
gradlew.bat
+1
-0
mobile/build.gradle.kts
mobile/build.gradle.kts
+3
-4
mobile/src/main/java/com/github/shadowsocks/App.kt
mobile/src/main/java/com/github/shadowsocks/App.kt
+1
-1
mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
...main/java/com/github/shadowsocks/ProfileConfigFragment.kt
+0
-2
mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt
.../src/main/java/com/github/shadowsocks/ProfilesFragment.kt
+2
-2
mobile/src/main/java/com/github/shadowsocks/ScannerActivity.kt
...e/src/main/java/com/github/shadowsocks/ScannerActivity.kt
+2
-2
mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
...in/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
+1
-1
plugin/build.gradle.kts
plugin/build.gradle.kts
+1
-3
repositories.gradle.kts
repositories.gradle.kts
+1
-1
tv/src/main/java/com/github/shadowsocks/tv/App.kt
tv/src/main/java/com/github/shadowsocks/tv/App.kt
+1
-1
No files found.
.circleci/config.yml
View file @
b00ae42a
...
...
@@ -3,7 +3,7 @@ jobs:
build
:
working_directory
:
~/code
docker
:
-
image
:
shadowsocks/android-ndk-go
:v1.0
-
image
:
shadowsocks/android-ndk-go
environment
:
GRADLE_OPTS
:
-Dorg.gradle.workers.max=1 -Dorg.gradle.daemon=false -Dkotlin.compiler.execution.strategy="in-process"
steps
:
...
...
.github/ISSUE_TEMPLATE/bug_report.md
View file @
b00ae42a
---
name
:
Bug report
about
:
Create a report to help us improve
title
:
'
'
labels
:
bug
assignees
:
'
'
---
...
...
.github/ISSUE_TEMPLATE/feature_request.md
View file @
b00ae42a
---
name
:
Feature request
about
:
Suggest an idea for this project
title
:
'
'
labels
:
enhancement
assignees
:
'
'
---
...
...
.github/ISSUE_TEMPLATE/questions-support-requests-other.md
View file @
b00ae42a
---
name
:
Questions/Support requests/Other
about
:
You should probably use the forum
title
:
'
'
labels
:
question
assignees
:
'
'
---
...
...
.gitmodules
View file @
b00ae42a
...
...
@@ -16,4 +16,4 @@
branch = shadowsocks-android
[submodule "core/src/main/rust/shadowsocks-rust"]
path = core/src/main/rust/shadowsocks-rust
url = https://github.com/
madeye/shadowsocks-rus
t
url = https://github.com/
shadowsocks/shadowsocks-rust.gi
t
README.md
View file @
b00ae42a
...
...
@@ -18,21 +18,21 @@ for Android TV ([beta](https://play.google.com/apps/testing/com.github.shadowsoc
*
JDK 1.8
*
Android SDK
-
Android NDK
*
Rust with Android targets installed
`$ rustup target install armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android`
### BUILD
You can check whether the latest commit builds under UNIX environment by checking Travis status.
*
Install prerequisites
*
Clone the repo using
`git clone --recurse-submodules <repo>`
or update submodules using
`git submodule update --init --recursive`
*
Build it using Android Studio or gradle script
### BUILD WITH DOCKER
```
bash
mkdir
build
sudo chown
3434:3434 build
docker run
--rm
-v
${
PWD
}
/build:/build circleci/android:api-28-ndk bash
-c
"cd /build; git clone https://github.com/shadowsocks/shadowsocks-android; cd shadowsocks-android; git submodule update --init --recursive; ./gradlew assembleDebug"
```
*
Clone the repo using
`git clone --recurse-submodules <repo>`
or update submodules using
`git submodule update --init --recursive`
*
Run
`docker run --rm -v ${PWD}:/build -w /build shadowsocks/android-ndk-go ./gradlew assembleDebug`
### CONTRIBUTING
...
...
build.gradle.kts
View file @
b00ae42a
...
...
@@ -17,7 +17,7 @@ buildscript {
classpath
(
rootProject
.
extra
.
get
(
"androidPlugin"
).
toString
())
classpath
(
kotlin
(
"gradle-plugin"
,
rootProject
.
extra
.
get
(
"kotlinVersion"
).
toString
()))
classpath
(
"com.google.android.gms:oss-licenses-plugin:0.10.2"
)
classpath
(
"com.google.firebase:firebase-crashlytics-gradle:2.
0.0-beta04
"
)
classpath
(
"com.google.firebase:firebase-crashlytics-gradle:2.
1.1
"
)
classpath
(
"com.google.gms:google-services:4.3.3"
)
classpath
(
"com.vanniktech:gradle-maven-publish-plugin:0.11.1"
)
classpath
(
"gradle.plugin.org.mozilla.rust-android-gradle:plugin:0.8.3"
)
...
...
@@ -28,6 +28,13 @@ allprojects {
apply
(
from
=
"${rootProject.projectDir}/repositories.gradle.kts"
)
}
tasks
.
register
(
"clean"
,
Delete
::
class
)
{
tasks
.
register
<
Delete
>(
"clean"
)
{
delete
(
rootProject
.
buildDir
)
}
// skip uploading the mapping to Crashlytics
subprojects
{
tasks
.
whenTaskAdded
{
if
(
name
.
contains
(
"uploadCrashlyticsMappingFile"
))
enabled
=
false
}
}
buildSrc/src/main/kotlin/Helpers.kt
View file @
b00ae42a
...
...
@@ -17,7 +17,7 @@ private val Project.android get() = extensions.getByName<BaseExtension>("android
private
val
flavorRegex
=
"(assemble|generate)\\w*(Release|Debug)"
.
toRegex
()
val
Project
.
currentFlavor
get
()
=
gradle
.
startParameter
.
taskRequests
.
toString
().
let
{
task
->
flavorRegex
.
matchEntire
(
task
)
?.
groupValues
?.
get
(
2
)
?.
toLowerCase
(
Locale
.
ROOT
)
?:
"debug"
.
also
{
flavorRegex
.
find
(
task
)
?.
groupValues
?.
get
(
2
)
?.
toLowerCase
(
Locale
.
ROOT
)
?:
"debug"
.
also
{
println
(
"Warning: No match found for $task"
)
}
}
...
...
@@ -50,10 +50,11 @@ fun Project.setupCore() {
setupCommon
()
android
.
apply
{
defaultConfig
{
versionCode
=
50
006
50
versionName
=
"5.
0.6
-nightly"
versionCode
=
50
101
50
versionName
=
"5.
1.1
-nightly"
}
compileOptions
.
isCoreLibraryDesugaringEnabled
=
true
ndkVersion
=
"21.3.6528147"
}
dependencies
.
add
(
"coreLibraryDesugaring"
,
"com.android.tools:desugar_jdk_libs:1.0.5"
)
}
...
...
@@ -74,6 +75,7 @@ fun Project.setupApp() {
proguardFile
(
getDefaultProguardFile
(
"proguard-android.txt"
))
}
}
lintOptions
.
disable
(
"RemoveWorkManagerInitializer"
)
packagingOptions
{
exclude
(
"**/*.kotlin_*"
)
}
...
...
core/build.gradle.kts
View file @
b00ae42a
import
com.android.build.gradle.internal.tasks.factory.dependsOn
plugins
{
id
(
"com.android.library"
)
id
(
"org.mozilla.rust-android-gradle.rust-android"
)
...
...
@@ -17,10 +19,9 @@ android {
arguments
(
"-j${Runtime.getRuntime().availableProcessors()}"
)
}
javaCompileOptions
.
annotationProcessorOptions
.
arguments
=
mapOf
(
javaCompileOptions
.
annotationProcessorOptions
.
arguments
(
mapOf
(
"room.incremental"
to
"true"
,
"room.schemaLocation"
to
"$projectDir/schemas"
)
"room.schemaLocation"
to
"$projectDir/schemas"
))
}
externalNativeBuild
.
ndkBuild
.
path
(
"src/main/jni/Android.mk"
)
...
...
@@ -30,42 +31,44 @@ android {
}
}
androidExtensions
.
isExperimental
=
true
cargo
{
module
=
"src/main/rust/shadowsocks-rust"
libname
=
"sslocal"
targets
=
listOf
(
"arm"
,
"arm64"
,
"x86"
,
"x86_64"
)
profile
=
findProperty
(
"CARGO_PROFILE"
)
?.
toString
()
?:
"release"
targetIncludes
=
arrayOf
(
"lib$libname.so"
)
extraCargoBuildArguments
=
listOf
(
"--bin"
,
"sslocal"
)
features
{
noDefaultBut
(
arrayOf
(
"sodium"
,
"rc4"
,
"aes-cfb"
,
"aes-ctr"
,
"camellia-cfb"
,
"openssl-vendored"
,
"local-flow-stat"
,
"local-dns-relay"
))
}
profile
=
findProperty
(
"CARGO_PROFILE"
)
?.
toString
()
?:
currentFlavor
extraCargoBuildArguments
=
listOf
(
"--bin"
,
libname
!!
)
featureSpec
.
noDefaultBut
(
arrayOf
(
"sodium"
,
"rc4"
,
"aes-cfb"
,
"aes-ctr"
,
"camellia-cfb"
,
"openssl-vendored"
,
"local-flow-stat"
,
"local-dns-relay"
))
exec
=
{
spec
,
toolchain
->
spec
.
environment
(
"RUST
FLAGS"
,
"-C lto=no -C link-arg=-o -C link-arg=
target/${toolchain.target}/$profile/lib$libname.so"
)
spec
.
environment
(
"RUST
_ANDROID_GRADLE_LINKER_WRAPPER_PY"
,
"$projectDir/$module/../linker-wrapper.py"
)
spec
.
environment
(
"RUST_ANDROID_GRADLE_TARGET"
,
"
target/${toolchain.target}/$profile/lib$libname.so"
)
}
}
tasks
.
whenTaskAdded
{
when
(
name
)
{
"
javaPreCompileDebug"
,
"javaPreCompileRelease
"
->
dependsOn
(
"cargoBuild"
)
"
mergeDebugJniLibFolders"
,
"mergeReleaseJniLibFolders
"
->
dependsOn
(
"cargoBuild"
)
}
}
tasks
.
register
<
Exec
>(
"cargoClean"
)
{
executable
(
"cargo"
)
// cargo.cargoCommand
args
(
"clean"
)
workingDir
(
"$projectDir/${cargo.module}"
)
}
tasks
.
clean
.
dependsOn
(
"cargoClean"
)
dependencies
{
val
coroutinesVersion
=
"1.3.
5
"
val
coroutinesVersion
=
"1.3.
6
"
val
roomVersion
=
"2.2.5"
val
workVersion
=
"2.
3.4
"
val
workVersion
=
"2.
4.0-beta01
"
api
(
project
(
":plugin"
))
api
(
"androidx.fragment:fragment-ktx:1.2.4"
)
...
...
@@ -77,11 +80,11 @@ dependencies {
api
(
"androidx.work:work-gcm:$workVersion"
)
api
(
"com.google.android.gms:play-services-oss-licenses:17.0.0"
)
api
(
"com.google.code.gson:gson:2.8.6"
)
api
(
"com.google.firebase:firebase-analytics-ktx:17.
3.0
"
)
api
(
"com.google.firebase:firebase-config-ktx:19.1.
3
"
)
api
(
"com.google.firebase:firebase-crashlytics:17.0.
0-beta04
"
)
api
(
"com.google.firebase:firebase-analytics-ktx:17.
4.3
"
)
api
(
"com.google.firebase:firebase-config-ktx:19.1.
4
"
)
api
(
"com.google.firebase:firebase-crashlytics:17.0.
1
"
)
api
(
"com.jakewharton.timber:timber:4.7.1"
)
api
(
"dnsjava:dnsjava:3.
0.2
"
)
api
(
"dnsjava:dnsjava:3.
1.0
"
)
api
(
"org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
)
api
(
"org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion"
)
kapt
(
"androidx.room:room-compiler:$roomVersion"
)
...
...
core/lint.xml
View file @
b00ae42a
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue
id=
"BadConfigurationProvider"
severity=
"informational"
/>
<issue
id=
"ImpliedQuantity"
severity=
"warning"
/>
<issue
id=
"ExtraTranslation"
severity=
"warning"
/>
<issue
id=
"MissingDefaultResource"
severity=
"warning"
/>
...
...
core/src/main/AndroidManifest.xml
View file @
b00ae42a
...
...
@@ -32,6 +32,7 @@
android:extractNativeLibs=
"true"
android:fullBackupContent=
"@xml/backup_descriptor"
android:fullBackupOnly=
"true"
android:hasFragileUserData=
"true"
android:label=
"@string/app_name"
android:supportsRtl=
"true"
android:networkSecurityConfig=
"@xml/network_security_config"
...
...
@@ -113,52 +114,30 @@
tools:node=
"remove"
/>
<service
android:name=
"androidx.work.impl.background.systemalarm.SystemAlarmService"
android:process=
":bg"
android:directBootAware=
"true"
tools:ignore=
"Instantiatable"
tools:replace=
"android:directBootAware"
/>
tools:ignore=
"Instantiatable"
/>
<service
android:name=
"androidx.work.impl.background.systemjob.SystemJobService"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<service
android:name=
"androidx.work.impl.foreground.SystemForegroundService"
android:process=
":bg"
android:directBootAware=
"true"
tools:ignore=
"Instantiatable"
tools:replace=
"android:directBootAware"
/>
tools:ignore=
"Instantiatable"
/>
<receiver
android:name=
"androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<receiver
android:name=
"androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<receiver
android:name=
"androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<receiver
android:name=
"androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<receiver
android:name=
"androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<receiver
android:name=
"androidx.work.impl.background.systemalarm.RescheduleReceiver"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<receiver
android:name=
"androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
android:process=
":bg"
android:directBootAware=
"true"
tools:replace=
"android:directBootAware"
/>
android:process=
":bg"
/>
<!-- Used for API < 23. https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/work/workmanager-gcm/src/main/AndroidManifest.xml -->
<service
android:name=
"androidx.work.impl.background.gcm.WorkManagerGcmService"
android:process=
":bg"
android:directBootAware=
"true"
tools:ignore=
"Instantiatable"
tools:replace=
"android:directBootAware"
/>
tools:ignore=
"Instantiatable"
/>
</application>
</manifest>
core/src/main/java/com/github/shadowsocks/BootReceiver.kt
View file @
b00ae42a
...
...
@@ -26,8 +26,6 @@ import android.content.Context
import
android.content.Intent
import
android.content.pm.PackageManager
import
android.os.Build
import
android.os.UserManager
import
androidx.core.content.getSystemService
import
com.github.shadowsocks.Core.app
import
com.github.shadowsocks.preference.DataStore
...
...
@@ -50,8 +48,7 @@ class BootReceiver : BroadcastReceiver() {
val
doStart
=
when
(
intent
.
action
)
{
Intent
.
ACTION_BOOT_COMPLETED
->
!
DataStore
.
directBootAware
Intent
.
ACTION_LOCKED_BOOT_COMPLETED
->
DataStore
.
directBootAware
else
->
DataStore
.
directBootAware
||
Build
.
VERSION
.
SDK_INT
>=
24
&&
app
.
getSystemService
<
UserManager
>()
?.
isUserUnlocked
!=
false
else
->
DataStore
.
directBootAware
||
Build
.
VERSION
.
SDK_INT
>=
24
&&
Core
.
user
.
isUserUnlocked
}
if
(
doStart
)
Core
.
startService
()
}
...
...
core/src/main/java/com/github/shadowsocks/Core.kt
View file @
b00ae42a
...
...
@@ -37,7 +37,6 @@ import androidx.annotation.VisibleForTesting
import
androidx.core.content.ContextCompat
import
androidx.core.content.getSystemService
import
androidx.work.Configuration
import
androidx.work.WorkManager
import
com.github.shadowsocks.acl.Acl
import
com.github.shadowsocks.aidl.ShadowsocksConnection
import
com.github.shadowsocks.core.BuildConfig
...
...
@@ -62,7 +61,7 @@ import java.io.File
import
java.io.IOException
import
kotlin.reflect.KClass
object
Core
{
object
Core
:
Configuration
.
Provider
{
lateinit
var
app
:
Application
@VisibleForTesting
set
lateinit
var
configureIntent
:
(
Context
)
->
PendingIntent
...
...
@@ -70,6 +69,7 @@ object Core {
val
clipboard
by
lazy
{
app
.
getSystemService
<
ClipboardManager
>()
!!
}
val
connectivity
by
lazy
{
app
.
getSystemService
<
ConnectivityManager
>()
!!
}
val
notification
by
lazy
{
app
.
getSystemService
<
NotificationManager
>()
!!
}
val
user
by
lazy
{
app
.
getSystemService
<
UserManager
>()
!!
}
val
packageInfo
:
PackageInfo
by
lazy
{
getPackageInfo
(
app
.
packageName
)
}
val
deviceStorage
by
lazy
{
if
(
Build
.
VERSION
.
SDK_INT
<
24
)
app
else
DeviceStorageApp
(
app
)
}
val
directBootSupported
by
lazy
{
...
...
@@ -80,7 +80,7 @@ object Core {
val
activeProfileIds
get
()
=
ProfileManager
.
getProfile
(
DataStore
.
profileId
).
let
{
if
(
it
==
null
)
emptyList
()
else
listOfNotNull
(
it
.
id
,
it
.
udpFallback
)
}
val
currentProfile
:
P
air
<
Profile
,
Profile
?
>
?
get
()
{
val
currentProfile
:
P
rofileManager
.
ExpandedProfile
?
get
()
{
if
(
DataStore
.
directBootAware
)
DirectBoot
.
getDeviceProfile
()
?.
apply
{
return
this
}
return
ProfileManager
.
expand
(
ProfileManager
.
getProfile
(
DataStore
.
profileId
)
?:
return
null
)
}
...
...
@@ -121,14 +121,11 @@ object Core {
}
}
})
WorkManager
.
initialize
(
deviceStorage
,
Configuration
.
Builder
().
apply
{
setExecutor
{
GlobalScope
.
launch
{
it
.
run
()
}
}
setTaskExecutor
{
GlobalScope
.
launch
{
it
.
run
()
}
}
}.
build
())
// handle data restored/crash
if
(
Build
.
VERSION
.
SDK_INT
>=
24
&&
DataStore
.
directBootAware
&&
app
.
getSystemService
<
UserManager
>()
?.
isUserUnlocked
==
true
)
DirectBoot
.
flushTrafficStats
()
if
(
Build
.
VERSION
.
SDK_INT
>=
24
&&
DataStore
.
directBootAware
&&
user
.
isUserUnlocked
)
{
DirectBoot
.
flushTrafficStats
()
}
if
(
DataStore
.
publicStore
.
getLong
(
Key
.
assetUpdateTime
,
-
1
)
!=
packageInfo
.
lastUpdateTime
)
{
val
assetManager
=
app
.
assets
try
{
...
...
@@ -143,6 +140,12 @@ object Core {
updateNotificationChannels
()
}
override
fun
getWorkManagerConfiguration
()
=
Configuration
.
Builder
().
apply
{
setMinimumLoggingLevel
(
if
(
BuildConfig
.
DEBUG
)
Log
.
VERBOSE
else
Log
.
INFO
)
setExecutor
{
GlobalScope
.
launch
{
it
.
run
()
}
}
setTaskExecutor
{
GlobalScope
.
launch
{
it
.
run
()
}
}
}.
build
()
fun
updateNotificationChannels
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
26
)
@RequiresApi
(
26
)
{
notification
.
createNotificationChannels
(
listOf
(
...
...
core/src/main/java/com/github/shadowsocks/UrlImportActivity.kt
View file @
b00ae42a
...
...
@@ -67,7 +67,7 @@ class UrlImportActivity : AppCompatActivity() {
}
private
fun
handleShareIntent
()
=
intent
.
data
?.
toString
()
?.
let
{
sharedStr
->
val
profiles
=
Profile
.
findAllUrls
(
sharedStr
,
Core
.
currentProfile
?.
first
).
toList
()
val
profiles
=
Profile
.
findAllUrls
(
sharedStr
,
Core
.
currentProfile
?.
main
).
toList
()
if
(
profiles
.
isEmpty
())
null
else
ImportProfilesDialogFragment
().
withArg
(
ProfilesArg
(
profiles
))
}
}
core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt
View file @
b00ae42a
...
...
@@ -21,8 +21,10 @@
package
com.github.shadowsocks.acl
import
android.content.Context
import
android.os.Build
import
androidx.work.*
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.Core.app
import
com.github.shadowsocks.utils.useCancellable
import
timber.log.Timber
import
java.io.IOException
...
...
@@ -34,16 +36,19 @@ class AclSyncer(context: Context, workerParams: WorkerParameters) : CoroutineWor
companion
object
{
private
const
val
KEY_ROUTE
=
"route"
fun
schedule
(
route
:
String
)
=
WorkManager
.
getInstance
(
Core
.
deviceStorage
).
enqueueUniqueWork
(
route
,
ExistingWorkPolicy
.
REPLACE
,
OneTimeWorkRequestBuilder
<
AclSyncer
>().
run
{
setInputData
(
Data
.
Builder
().
putString
(
KEY_ROUTE
,
route
).
build
())
setConstraints
(
Constraints
.
Builder
()
.
setRequiredNetworkType
(
NetworkType
.
UNMETERED
)
.
setRequiresCharging
(
true
)
.
build
())
setInitialDelay
(
10
,
TimeUnit
.
SECONDS
)
build
()
})
fun
schedule
(
route
:
String
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
24
&&
!
Core
.
user
.
isUserUnlocked
)
return
// work does not support this
WorkManager
.
getInstance
(
app
).
enqueueUniqueWork
(
route
,
ExistingWorkPolicy
.
REPLACE
,
OneTimeWorkRequestBuilder
<
AclSyncer
>().
run
{
setInputData
(
Data
.
Builder
().
putString
(
KEY_ROUTE
,
route
).
build
())
setConstraints
(
Constraints
.
Builder
()
.
setRequiredNetworkType
(
NetworkType
.
UNMETERED
)
.
setRequiresCharging
(
true
)
.
build
())
setInitialDelay
(
10
,
TimeUnit
.
SECONDS
)
build
()
})
}
}
override
suspend
fun
doWork
():
Result
=
try
{
...
...
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
View file @
b00ae42a
...
...
@@ -24,8 +24,10 @@ import android.app.Service
import
android.content.Context
import
android.content.Intent
import
android.content.IntentFilter
import
android.os.*
import
androidx.core.content.getSystemService
import
android.os.Build
import
android.os.IBinder
import
android.os.RemoteCallbackList
import
android.os.RemoteException
import
com.github.shadowsocks.BootReceiver
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.Core.app
...
...
@@ -238,13 +240,13 @@ object BaseService {
val
isVpnService
get
()
=
false
suspend
fun
startProcesses
()
{
val
con
figRoot
=
(
if
(
Build
.
VERSION
.
SDK_INT
<
24
||
app
.
getSystemService
<
UserManager
>()
?.
isUserUnlocked
!=
false
)
app
else
Core
.
deviceStorage
)
.
noBackupFilesDir
val
con
text
=
if
(
Build
.
VERSION
.
SDK_INT
<
24
||
Core
.
user
.
isUserUnlocked
)
app
else
Core
.
deviceStorage
val
configRoot
=
context
.
noBackupFilesDir
val
udpFallback
=
data
.
udpFallback
data
.
proxy
!!
.
start
(
this
,
File
(
Core
.
deviceStorage
.
noBackupFilesDir
,
"stat_main"
),
File
(
configRoot
,
CONFIG_FILE
),
if
(
udpFallback
==
null
)
"-U"
else
null
)
if
(
udpFallback
==
null
&&
data
.
proxy
?.
plugin
==
null
)
"-U"
else
null
)
if
(
udpFallback
?.
plugin
!=
null
)
throw
ExpectedExceptionWrapper
(
IllegalStateException
(
"UDP fallback cannot have plugins"
))
udpFallback
?.
start
(
this
,
...
...
@@ -321,15 +323,15 @@ object BaseService {
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
val
data
=
data
if
(
data
.
state
!=
State
.
Stopped
)
return
Service
.
START_NOT_STICKY
val
profilePair
=
Core
.
currentProfile
val
expanded
=
Core
.
currentProfile
this
as
Context
if
(
profilePair
==
null
)
{
if
(
expanded
==
null
)
{
// gracefully shutdown: https://stackoverflow.com/q/47337857/2245107
data
.
notification
=
createNotification
(
""
)
stopRunner
(
false
,
getString
(
R
.
string
.
profile_empty
))
return
Service
.
START_NOT_STICKY
}
val
(
profile
,
fallback
)
=
profilePair
val
(
profile
,
fallback
)
=
expanded
profile
.
name
=
profile
.
formattedName
// save name for later queries
val
proxy
=
ProxyInstance
(
profile
)
data
.
proxy
=
proxy
...
...
core/src/main/java/com/github/shadowsocks/bg/LocalDnsWorker.kt
View file @
b00ae42a
...
...
@@ -4,6 +4,7 @@ import android.net.LocalSocket
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.net.ConcurrentLocalSocketListener
import
com.github.shadowsocks.net.DnsResolverCompat
import
com.github.shadowsocks.utils.readableMessage
import
kotlinx.coroutines.CancellationException
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.TimeoutCancellationException
...
...
@@ -23,8 +24,11 @@ class LocalDnsWorker(private val resolver: suspend (ByteArray) -> ByteArray) : C
launch
{
socket
.
use
{
val
input
=
DataInputStream
(
socket
.
inputStream
)
val
query
=
ByteArray
(
input
.
readUnsignedShort
())
input
.
read
(
query
)
val
query
=
try
{
ByteArray
(
input
.
readUnsignedShort
()).
also
{
input
.
read
(
it
)
}
}
catch
(
e
:
IOException
)
{
// connection early close possibly due to resolving timeout
return
@use
Timber
.
d
(
e
)
}
try
{
resolver
(
query
)
}
catch
(
e
:
Exception
)
{
...
...
@@ -46,7 +50,9 @@ class LocalDnsWorker(private val resolver: suspend (ByteArray) -> ByteArray) : C
val
output
=
DataOutputStream
(
socket
.
outputStream
)
output
.
writeShort
(
response
.
size
)
output
.
write
(
response
)
}
catch
(
_
:
IOException
)
{
}
// connection early close possibly due to resolving timeout
}
catch
(
e
:
IOException
)
{
Timber
.
d
(
e
.
readableMessage
)
}
}
}
}
...
...
core/src/main/java/com/github/shadowsocks/bg/ProxyInstance.kt
View file @
b00ae42a
...
...
@@ -86,8 +86,8 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
if
(
profile
.
host
.
parseNumericAddress
()
==
null
)
{
profile
.
host
=
try
{
service
.
resolver
(
profile
.
host
).
firstOrNull
()
}
catch
(
_
:
IOException
)
{
null
}
catch
(
e
:
IOException
)
{
throw
UnknownHostException
().
initCause
(
e
)
}
?.
hostAddress
?:
throw
UnknownHostException
()
}
}
...
...
@@ -121,7 +121,7 @@ class ProxyInstance(val profile: Profile, private val route: String = profile.ro
}.
let
{
dns
->
cmd
+=
arrayListOf
(
"--dns-relay"
,
"${DataStore.listenAddress}:${DataStore.portLocalDns}"
,
"--remote-dns"
,
"${dns.host
!!
}:${if (dns.port < 0) 53 else dns.port}"
)
"--remote-dns"
,
"${dns.host
?: "
0.0.0.0
"
}:${if (dns.port < 0) 53 else dns.port}"
)
}
if
(
route
!=
Acl
.
ALL
)
{
...
...
core/src/main/java/com/github/shadowsocks/bg/TrafficMonitor.kt
View file @
b00ae42a
...
...
@@ -96,7 +96,7 @@ class TrafficMonitor(statFile: File) {
ProfileManager
.
updateProfile
(
profile
)
}
catch
(
e
:
IOException
)
{
if
(!
DataStore
.
directBootAware
)
throw
e
// we should only reach here because we're in direct boot
val
profile
=
DirectBoot
.
getDeviceProfile
()
!!
.
toList
().
filterNotNull
().
single
{
it
.
id
==
id
}
val
profile
=
DirectBoot
.
getDeviceProfile
()
!!
.
toList
().
single
{
it
.
id
==
id
}
profile
.
tx
+=
current
.
txTotal
profile
.
rx
+=
current
.
rxTotal
profile
.
dirty
=
true
...
...
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
View file @
b00ae42a
...
...
@@ -29,6 +29,7 @@ import android.net.Network
import
android.os.Build
import
android.os.ParcelFileDescriptor
import
android.system.ErrnoException
import
android.system.Os
import
android.system.OsConstants
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.VpnRequestActivity
...
...
@@ -40,7 +41,6 @@ import com.github.shadowsocks.net.DnsResolverCompat
import
com.github.shadowsocks.net.Subnet
import
com.github.shadowsocks.preference.DataStore
import
com.github.shadowsocks.utils.Key
import
com.github.shadowsocks.utils.closeQuietly
import
com.github.shadowsocks.utils.int
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.delay
...
...
@@ -59,34 +59,42 @@ class VpnService : BaseVpnService(), BaseService.Interface {
private
const
val
PRIVATE_VLAN4_ROUTER
=
"172.19.0.2"
private
const
val
PRIVATE_VLAN6_CLIENT
=
"fdfe:dcba:9876::1"
private
const
val
PRIVATE_VLAN6_ROUTER
=
"fdfe:dcba:9876::2"
private
fun
<
T
>
FileDescriptor
.
use
(
block
:
(
FileDescriptor
)
->
T
)
=
try
{
block
(
this
)
}
finally
{
try
{
Os
.
close
(
this
)
}
catch
(
_
:
ErrnoException
)
{
}
}
}
private
inner
class
ProtectWorker
:
ConcurrentLocalSocketListener
(
"ShadowsocksVpnThread"
,
File
(
Core
.
deviceStorage
.
noBackupFilesDir
,
"protect_path"
))
{
override
fun
acceptInternal
(
socket
:
LocalSocket
)
{
socket
.
inputStream
.
read
()
val
fd
=
socket
.
ancillaryFileDescriptors
!!
.
single
()
!!
try
{
socket
.
outputStream
.
write
(
if
(
underlyingNetwork
.
let
{
network
->
if
(
network
!=
null
)
try
{
DnsResolverCompat
.
bindSocket
(
network
,
fd
)
return
@let
true
}
catch
(
e
:
IOException
)
{
when
((
e
.
cause
as
?
ErrnoException
)
?.
errno
)
{
// also suppress ENONET (Machine is not on the network)
OsConstants
.
EPERM
,
64
->
Timber
.
d
(
e
)
else
->
Timber
.
w
(
e
)
}
return
@let
false
}
catch
(
e
:
ReflectiveOperationException
)
{
check
(
Build
.
VERSION
.
SDK_INT
<
23
)
Timber
.
w
(
e
)
}
protect
(
fd
.
int
)
})
0
else
1
)
}
finally
{
fd
.
closeQuietly
()
val
success
=
socket
.
ancillaryFileDescriptors
!!
.
single
()
!!
.
use
{
fd
->
underlyingNetwork
.
let
{
network
->
if
(
network
!=
null
)
try
{
DnsResolverCompat
.
bindSocket
(
network
,
fd
)
return
@let
true
}
catch
(
e
:
IOException
)
{
when
((
e
.
cause
as
?
ErrnoException
)
?.
errno
)
{
// also suppress ENONET (Machine is not on the network)
OsConstants
.
EPERM
,
OsConstants
.
EACCES
,
64
->
Timber
.
d
(
e
)
else
->
Timber
.
w
(
e
)
}
return
@let
false
}
catch
(
e
:
ReflectiveOperationException
)
{
check
(
Build
.
VERSION
.
SDK_INT
<
23
)
Timber
.
w
(
e
)
}
protect
(
fd
.
int
)
}
}
try
{
socket
.
outputStream
.
write
(
if
(
success
)
0
else
1
)
}
catch
(
_
:
IOException
)
{
}
// ignore connection early close
}
}
...
...
core/src/main/java/com/github/shadowsocks/database/ProfileManager.kt
View file @
b00ae42a
...
...
@@ -46,6 +46,10 @@ object ProfileManager {
}
var
listener
:
Listener
?
=
null
data class
ExpandedProfile
(
val
main
:
Profile
,
val
udpFallback
:
Profile
?)
{
fun
toList
()
=
listOfNotNull
(
main
,
udpFallback
)
}
@Throws
(
SQLException
::
class
)
fun
createProfile
(
profile
:
Profile
=
Profile
()):
Profile
{
profile
.
id
=
0
...
...
@@ -59,7 +63,7 @@ object ProfileManager {
val
profiles
=
if
(
replace
)
getAllProfiles
()
?.
associateBy
{
it
.
formattedAddress
}
else
null
val
feature
=
if
(
replace
)
{
profiles
?.
values
?.
singleOrNull
{
it
.
id
==
DataStore
.
profileId
}
}
else
Core
.
currentProfile
?.
first
}
else
Core
.
currentProfile
?.
main
val
lazyClear
=
lazy
{
clear
()
}
jsons
.
asIterable
().
forEachTry
{
json
->
Profile
.
parseJson
(
JsonStreamParser
(
json
.
bufferedReader
()).
asSequence
().
single
(),
feature
)
{
...
...
@@ -99,7 +103,7 @@ object ProfileManager {
}
@Throws
(
IOException
::
class
)
fun
expand
(
profile
:
Profile
)
:
Pair
<
Profile
,
Profile
?
>
=
Pair
(
profile
,
profile
.
udpFallback
?.
let
{
getProfile
(
it
)
})
fun
expand
(
profile
:
Profile
)
=
ExpandedProfile
(
profile
,
profile
.
udpFallback
?.
let
{
getProfile
(
it
)
})
@Throws
(
SQLException
::
class
)
fun
delProfile
(
id
:
Long
)
{
...
...
core/src/main/java/com/github/shadowsocks/net/DnsResolverCompat.kt
View file @
b00ae42a
...
...
@@ -26,9 +26,7 @@ import android.net.DnsResolver
import
android.net.Network
import
android.os.Build
import
android.os.CancellationSignal
import
android.os.Looper
import
android.system.ErrnoException
import
android.system.Os
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.utils.int
import
kotlinx.coroutines.*
...
...
@@ -70,6 +68,7 @@ sealed class DnsResolverCompat {
fun
prepareDnsResponse
(
request
:
Message
)
=
Message
(
request
.
header
.
id
).
apply
{
header
.
setFlag
(
Flags
.
QR
.
toInt
())
// this is a response
header
.
setFlag
(
Flags
.
RA
.
toInt
())
// recursion available
if
(
request
.
header
.
getFlag
(
Flags
.
RD
.
toInt
()))
header
.
setFlag
(
Flags
.
RD
.
toInt
())
request
.
question
?.
also
{
addRecord
(
it
,
Section
.
QUESTION
)
}
}
...
...
@@ -77,8 +76,6 @@ sealed class DnsResolverCompat {
@Throws
(
IOException
::
class
)
abstract
fun
bindSocket
(
network
:
Network
,
socket
:
FileDescriptor
)
internal
open
suspend
fun
connectUdp
(
fd
:
FileDescriptor
,
address
:
InetAddress
,
port
:
Int
=
0
)
=
Os
.
connect
(
fd
,
address
,
port
)
abstract
suspend
fun
resolve
(
network
:
Network
,
host
:
String
):
Array
<
InetAddress
>
abstract
suspend
fun
resolveOnActiveNetwork
(
host
:
String
):
Array
<
InetAddress
>
abstract
suspend
fun
resolveRaw
(
network
:
Network
,
query
:
ByteArray
):
ByteArray
...
...
@@ -99,12 +96,6 @@ sealed class DnsResolverCompat {
throw
ErrnoException
(
message
,
-
err
).
rethrowAsSocketException
()
}
override
suspend
fun
connectUdp
(
fd
:
FileDescriptor
,
address
:
InetAddress
,
port
:
Int
)
{
if
(
Looper
.
getMainLooper
().
thread
==
Thread
.
currentThread
())
withContext
(
Dispatchers
.
IO
)
{
// #2405
super
.
connectUdp
(
fd
,
address
,
port
)
}
else
super
.
connectUdp
(
fd
,
address
,
port
)
}
/**
* This dispatcher is used for noncancellable possibly-forever-blocking operations in network IO.
*
...
...
@@ -120,7 +111,7 @@ sealed class DnsResolverCompat {
override
suspend
fun
resolveOnActiveNetwork
(
host
:
String
)
=
GlobalScope
.
async
(
unboundedIO
)
{
InetAddress
.
getAllByName
(
host
)
}.
await
()
private
suspend
fun
resolveRaw
(
query
:
ByteArray
,
private
suspend
fun
resolveRaw
(
query
:
ByteArray
,
networkSpecified
:
Boolean
=
true
,
hostResolver
:
suspend
(
String
)
->
Array
<
InetAddress
>):
ByteArray
{
val
request
=
try
{
Message
(
query
)
...
...
@@ -135,11 +126,23 @@ sealed class DnsResolverCompat {
val
isIpv6
=
when
(
val
type
=
question
?.
type
)
{
Type
.
A
->
false
Type
.
AAAA
->
true
Type
.
PTR
->
{
// Android does not provide a PTR lookup API for Network prior to Android 10
if
(
networkSpecified
)
throw
IOException
(
UnsupportedOperationException
(
"Network unspecified"
))
val
ip
=
try
{
ReverseMap
.
fromName
(
question
.
name
)
}
catch
(
e
:
IOException
)
{
throw
UnsupportedOperationException
(
e
)
// unrecognized PTR name
}
val
hostname
=
Name
.
fromString
(
GlobalScope
.
async
(
unboundedIO
)
{
ip
.
hostName
}.
await
())
return
prepareDnsResponse
(
request
).
apply
{
addRecord
(
PTRRecord
(
question
.
name
,
DClass
.
IN
,
TTL
,
hostname
),
Section
.
ANSWER
)
}.
toWire
()
}
else
->
throw
UnsupportedOperationException
(
"Unsupported query type $type"
)
}
val
host
=
question
.
name
.
canonicalize
().
toString
(
true
)
return
prepareDnsResponse
(
request
).
apply
{
header
.
setFlag
(
Flags
.
RA
.
toInt
())
// recursion available
for
(
address
in
hostResolver
(
host
).
asIterable
().
run
{
if
(
isIpv6
)
filterIsInstance
<
Inet6Address
>()
else
filterIsInstance
<
Inet4Address
>()
})
addRecord
(
when
(
address
)
{
...
...
@@ -152,7 +155,7 @@ sealed class DnsResolverCompat {
override
suspend
fun
resolveRaw
(
network
:
Network
,
query
:
ByteArray
)
=
resolveRaw
(
query
)
{
resolve
(
network
,
it
)
}
override
suspend
fun
resolveRawOnActiveNetwork
(
query
:
ByteArray
)
=
resolveRaw
(
query
,
this
::
resolveOnActiveNetwork
)
resolveRaw
(
query
,
false
,
this
::
resolveOnActiveNetwork
)
}
@TargetApi
(
23
)
...
...
core/src/main/java/com/github/shadowsocks/net/HttpsTest.kt
View file @
b00ae42a
...
...
@@ -84,10 +84,7 @@ class HttpsTest : ViewModel() {
fun
testConnection
()
{
cancelTest
()
status
.
value
=
Status
.
Testing
val
url
=
URL
(
"https"
,
when
((
Core
.
currentProfile
?:
return
).
first
.
route
)
{
Acl
.
CHINALIST
->
"www.qualcomm.cn"
else
->
"www.google.com"
},
"/generate_204"
)
val
url
=
URL
(
"https://cp.cloudflare.com"
)
val
conn
=
(
if
(
DataStore
.
serviceMode
!=
Key
.
modeVpn
)
{
url
.
openConnection
(
Proxy
(
Proxy
.
Type
.
SOCKS
,
DataStore
.
proxyAddress
))
}
else
url
.
openConnection
())
as
HttpURLConnection
...
...
core/src/main/java/com/github/shadowsocks/plugin/PluginList.kt
View file @
b00ae42a
...
...
@@ -22,6 +22,7 @@ package com.github.shadowsocks.plugin
import
android.content.Intent
import
android.content.pm.PackageManager
import
android.widget.Toast
import
com.github.shadowsocks.Core.app
class
PluginList
:
ArrayList
<
Plugin
>()
{
...
...
@@ -33,7 +34,14 @@ class PluginList : ArrayList<Plugin>() {
val
lookup
=
mutableMapOf
<
String
,
Plugin
>().
apply
{
for
(
plugin
in
this
@PluginList
)
{
fun
check
(
old
:
Plugin
?)
=
check
(
old
==
null
||
old
===
plugin
)
fun
check
(
old
:
Plugin
?)
{
if
(
old
!=
null
&&
old
!==
plugin
)
{
val
packages
=
this
@PluginList
.
filter
{
it
.
id
==
plugin
.
id
}.
joinToString
{
it
.
packageName
}
val
message
=
"Conflicting plugins found from: $packages"
Toast
.
makeText
(
app
,
message
,
Toast
.
LENGTH_LONG
).
show
()
throw
IllegalStateException
(
message
)
}
}
check
(
put
(
plugin
.
id
,
plugin
))
for
(
alias
in
plugin
.
idAliases
)
check
(
put
(
alias
,
plugin
))
}
...
...
core/src/main/java/com/github/shadowsocks/plugin/PluginManager.kt
View file @
b00ae42a
...
...
@@ -33,6 +33,7 @@ import android.net.Uri
import
android.os.Build
import
android.system.Os
import
android.util.Base64
import
android.widget.Toast
import
androidx.core.os.bundleOf
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.Core.app
...
...
@@ -143,6 +144,11 @@ object PluginManager {
val
providers
=
app
.
packageManager
.
queryIntentContentProviders
(
Intent
(
PluginContract
.
ACTION_NATIVE_PLUGIN
,
buildUri
(
configuration
.
selected
)),
flags
)
if
(
providers
.
isEmpty
())
return
null
if
(
providers
.
size
>
1
)
{
val
message
=
"Conflicting plugins found from: ${providers.joinToString { it.providerInfo.packageName }}"
Toast
.
makeText
(
app
,
message
,
Toast
.
LENGTH_LONG
).
show
()
throw
IllegalStateException
(
message
)
}
val
provider
=
providers
.
single
().
providerInfo
val
options
=
configuration
.
getOptions
{
provider
.
loadString
(
PluginContract
.
METADATA_KEY_DEFAULT_CONFIG
)
}
var
failure
:
Throwable
?
=
null
...
...
core/src/main/java/com/github/shadowsocks/utils/DirectBoot.kt
View file @
b00ae42a
...
...
@@ -21,8 +21,8 @@ object DirectBoot : BroadcastReceiver() {
private
val
file
=
File
(
Core
.
deviceStorage
.
noBackupFilesDir
,
"directBootProfile"
)
private
var
registered
=
false
fun
getDeviceProfile
():
P
air
<
Profile
,
Profile
?
>
?
=
try
{
ObjectInputStream
(
file
.
inputStream
()).
use
{
it
.
readObject
()
as
?
P
air
<
Profile
,
Profile
?
>
}
fun
getDeviceProfile
():
P
rofileManager
.
ExpandedProfile
?
=
try
{
ObjectInputStream
(
file
.
inputStream
()).
use
{
it
.
readObject
()
as
?
P
rofileManager
.
ExpandedProfile
}
}
catch
(
_
:
IOException
)
{
null
}
fun
clean
()
{
...
...
core/src/main/java/com/github/shadowsocks/utils/Utils.kt
View file @
b00ae42a
...
...
@@ -28,7 +28,6 @@ import android.graphics.BitmapFactory
import
android.graphics.ImageDecoder
import
android.net.Uri
import
android.os.Build
import
android.system.ErrnoException
import
android.system.Os
import
android.system.OsConstants
import
android.util.TypedValue
...
...
@@ -66,10 +65,6 @@ val Throwable.readableMessage get() = localizedMessage ?: javaClass.name
private
val
getInt
=
FileDescriptor
::
class
.
java
.
getDeclaredMethod
(
"getInt$"
)
val
FileDescriptor
.
int
get
()
=
getInt
.
invoke
(
this
)
as
Int
fun
FileDescriptor
.
closeQuietly
()
=
try
{
Os
.
close
(
this
)
}
catch
(
_
:
ErrnoException
)
{
}
private
val
parseNumericAddress
by
lazy
@SuppressLint
(
"SoonBlockedPrivateApi"
)
{
InetAddress
::
class
.
java
.
getDeclaredMethod
(
"parseNumericAddress"
,
String
::
class
.
java
).
apply
{
isAccessible
=
true
...
...
core/src/main/res/values/arrays.xml
View file @
b00ae42a
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name=
"enc_method_entry"
translatable=
"false"
>
<item>
PLAIN
</item>
<item>
NONE
</item>
<item>
RC4-MD5
</item>
<item>
AES-128-CFB
</item>
<item>
AES-192-CFB
</item>
...
...
@@ -24,7 +24,7 @@
</string-array>
<string-array
name=
"enc_method_value"
translatable=
"false"
>
<item>
plain
</item>
<item>
none
</item>
<item>
rc4-md5
</item>
<item>
aes-128-cfb
</item>
<item>
aes-192-cfb
</item>
...
...
core/src/main/rust/linker-wrapper.py
0 → 100755
View file @
b00ae42a
from
__future__
import
absolute_import
,
print_function
,
unicode_literals
import
os
import
pipes
import
shutil
import
subprocess
import
sys
args
=
[
os
.
environ
[
'RUST_ANDROID_GRADLE_CC'
],
os
.
environ
[
'RUST_ANDROID_GRADLE_CC_LINK_ARG'
]]
+
sys
.
argv
[
1
:]
# This only appears when the subprocess call fails, but it's helpful then.
printable_cmd
=
' '
.
join
(
pipes
.
quote
(
arg
)
for
arg
in
args
)
print
(
printable_cmd
)
code
=
subprocess
.
call
(
args
)
if
code
==
0
:
shutil
.
copyfile
(
sys
.
argv
[
sys
.
argv
.
index
(
'-o'
)
+
1
],
os
.
environ
[
'RUST_ANDROID_GRADLE_TARGET'
])
sys
.
exit
(
code
)
shadowsocks-rust
@
ce1e5864
Subproject commit
246b6c48bce6d4a83af046bd3feb4843f772b9d
2
Subproject commit
ce1e58641d502ec128806efa898ebf271646113
2
detekt.yml
View file @
b00ae42a
...
...
@@ -19,10 +19,8 @@ complexity:
ignoreSingleWhenExpression
:
false
ignoreSimpleWhenEntries
:
false
ignoreNestingFunctions
:
false
nestingFunctions
:
run,let,apply,with,also,use,forEach,isNotNull,ifNull
LabeledExpression
:
active
:
false
ignoredLabels
:
'
'
LargeClass
:
active
:
true
threshold
:
600
...
...
@@ -35,6 +33,7 @@ complexity:
constructorThreshold
:
7
ignoreDefaultParameters
:
true
ignoreDataClasses
:
true
ignoreAnnotated
:
[]
MethodOverloading
:
active
:
false
NestedBlockDepth
:
...
...
@@ -42,14 +41,14 @@ complexity:
threshold
:
4
StringLiteralDuplication
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
threshold
:
3
ignoreAnnotation
:
true
excludeStringsWithLessThan5Characters
:
true
ignoreStringsRegex
:
'
$^'
TooManyFunctions
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
thresholdInFiles
:
11
thresholdInClasses
:
11
thresholdInInterfaces
:
11
...
...
@@ -105,7 +104,7 @@ exceptions:
active
:
true
ExceptionRaisedInUnexpectedLocation
:
active
:
true
methodNames
:
'
toString,hashCode,equals,finalize'
methodNames
:
[
toString
,
hashCode
,
equals
,
finalize
]
InstanceOfCheckForException
:
active
:
false
NotImplementedDeclaration
:
...
...
@@ -119,7 +118,11 @@ exceptions:
ignoreLabeled
:
true
SwallowedException
:
active
:
true
ignoredExceptionTypes
:
'
InterruptedException,NumberFormatException,ParseException,MalformedURLException'
ignoredExceptionTypes
:
-
InterruptedException
-
NumberFormatException
-
ParseException
-
MalformedURLException
allowedExceptionNameRegex
:
'
^(_|(ignore|expected).*)'
ThrowingExceptionFromFinally
:
active
:
false
...
...
@@ -127,12 +130,15 @@ exceptions:
active
:
true
ThrowingExceptionsWithoutMessageOrCause
:
active
:
true
exceptions
:
'
IllegalArgumentException,IllegalStateException,IOException'
exceptions
:
-
IllegalArgumentException
-
IllegalStateException
-
IOException
ThrowingNewInstanceOfSameException
:
active
:
true
TooGenericExceptionCaught
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
exceptionNames
:
-
ArrayIndexOutOfBoundsException
-
Error
...
...
@@ -259,37 +265,37 @@ naming:
ClassNaming
:
active
:
true
classPattern
:
'
[A-Z$][a-zA-Z0-9$]*'
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
ConstructorParameterNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
parameterPattern
:
'
[a-z][A-Za-z0-9]*'
privateParameterPattern
:
'
[a-z][A-Za-z0-9]*'
excludeClassPattern
:
'
$^'
ignoreOverridden
:
true
EnumNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
enumEntryPattern
:
'
^[A-Z][_a-zA-Z0-9]*'
ForbiddenClassName
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
forbiddenName
:
'
'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
forbiddenName
:
[]
FunctionMaxLength
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
maximumFunctionNameLength
:
30
FunctionMinLength
:
active
:
false
FunctionNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
functionPattern
:
'
^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
excludeClassPattern
:
'
$^'
ignoreOverridden
:
true
FunctionParameterNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
parameterPattern
:
'
[a-z][A-Za-z0-9]*'
excludeClassPattern
:
'
$^'
ignoreOverridden
:
true
...
...
@@ -303,29 +309,29 @@ naming:
active
:
false
ObjectPropertyNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
constantPattern
:
'
[A-Za-z][_A-Za-z0-9]*'
propertyPattern
:
'
[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern
:
'
(_)?[A-Za-z][_A-Za-z0-9]*'
PackageNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
packagePattern
:
'
^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
TopLevelPropertyNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
constantPattern
:
'
[A-Z][_A-Z0-9]*'
propertyPattern
:
'
[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern
:
'
_?[A-Za-z][_A-Za-z0-9]*'
VariableMaxLength
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
maximumVariableNameLength
:
64
VariableMinLength
:
active
:
false
VariableNaming
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
variablePattern
:
'
[a-z][A-Za-z0-9]*'
privateVariablePattern
:
'
(_)?[a-z][A-Za-z0-9]*'
excludeClassPattern
:
'
$^'
...
...
@@ -337,10 +343,10 @@ performance:
active
:
true
ForEachOnRange
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
SpreadOperator
:
active
:
true
excludes
:
'
**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt'
excludes
:
[
'
**/test/**'
,
'
**/androidTest/**'
,
'
**/*.Test.kt'
,
'
**/*.Spec.kt'
,
'
**/*.Spek.kt'
]
UnnecessaryTemporaryInstantiation
:
active
:
true
...
...
@@ -376,6 +382,10 @@ potential-bugs:
active
:
true
UnconditionalJumpStatementInLoop
:
active
:
true
UnnecessaryNotNullOperator
:
active
:
false
UnnecessarySafeCall
:
active
:
false
UnreachableCode
:
active
:
true
UnsafeCallOnNullableType
:
...
...
@@ -408,7 +418,7 @@ style:
includeLineWrapping
:
false
ForbiddenComment
:
active
:
true
values
:
'
TODO:,FIXME:,STOPSHIP:'
values
:
[
'
TODO:'
,
'
FIXME:'
,
'
STOPSHIP:'
]
allowedPatterns
:
'
'
ForbiddenImport
:
active
:
true
...
...
@@ -416,10 +426,10 @@ style:
forbiddenPatterns
:
'
'
ForbiddenMethodCall
:
active
:
true
methods
:
'
'
methods
:
[]
ForbiddenPublicDataClass
:
active
:
true
ignorePackages
:
'
*.internal,*.internal.*'
ignorePackages
:
[
'
*.internal'
,
'
*.internal.*'
]
ForbiddenVoid
:
active
:
true
ignoreOverridden
:
true
...
...
@@ -428,7 +438,7 @@ style:
active
:
true
ignoreOverridableFunction
:
true
excludedFunctions
:
'
describeContents'
excludeAnnotatedFunction
:
'
dagger.Provides'
excludeAnnotatedFunction
:
[
'
dagger.Provides'
]
LibraryCodeMustSpecifyReturnType
:
active
:
true
LoopWithTooManyJumpStatements
:
...
...
gradle/wrapper/gradle-wrapper.jar
View file @
b00ae42a
No preview for this file type
gradle/wrapper/gradle-wrapper.properties
View file @
b00ae42a
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-6.
3-all
.zip
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-6.
5-bin
.zip
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
gradlew
View file @
b00ae42a
...
...
@@ -82,6 +82,7 @@ esac
CLASSPATH
=
$APP_HOME
/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if
[
-n
"
$JAVA_HOME
"
]
;
then
if
[
-x
"
$JAVA_HOME
/jre/sh/java"
]
;
then
...
...
@@ -129,6 +130,7 @@ fi
if
[
"
$cygwin
"
=
"true"
-o
"
$msys
"
=
"true"
]
;
then
APP_HOME
=
`
cygpath
--path
--mixed
"
$APP_HOME
"
`
CLASSPATH
=
`
cygpath
--path
--mixed
"
$CLASSPATH
"
`
JAVACMD
=
`
cygpath
--unix
"
$JAVACMD
"
`
# We build the pattern for arguments to be converted via cygpath
...
...
gradlew.bat
View file @
b00ae42a
...
...
@@ -84,6 +84,7 @@ set CMD_LINE_ARGS=%*
set CLASSPATH=
%APP_HOME%
\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"
%JAVA_EXE%
"
%DEFAULT_JVM_OPTS%
%JAVA_OPTS%
%GRADLE_OPTS%
"
-Dorg
.gradle.appname
=
%APP_BASE_NAME%
" -classpath "
%CLASSPATH%
" org.gradle.wrapper.GradleWrapperMain
%CMD_LINE_ARGS%
...
...
mobile/build.gradle.kts
View file @
b00ae42a
...
...
@@ -10,17 +10,16 @@ plugins {
setupApp
()
android
.
defaultConfig
.
applicationId
=
"com.github.shadowsocks"
androidExtensions
.
isExperimental
=
true
dependencies
{
implementation
(
"androidx.browser:browser:1.2.0"
)
implementation
(
"androidx.constraintlayout:constraintlayout:2.0.0-beta
4
"
)
implementation
(
"androidx.constraintlayout:constraintlayout:2.0.0-beta
6
"
)
implementation
(
"androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
)
implementation
(
"com.google.android.gms:play-services-vision:20.
0
.0"
)
implementation
(
"com.google.android.gms:play-services-vision:20.
1
.0"
)
implementation
(
"com.google.firebase:firebase-ads:19.1.0"
)
implementation
(
"com.google.zxing:core:3.4.0"
)
implementation
(
"com.takisoft.preferencex:preferencex-simplemenu:1.1.0"
)
implementation
(
"com.twofortyfouram:android-plugin-api-for-locale:1.0.4"
)
implementation
(
"me.zhanghai.android.fastscroll:library:1.1.
2
"
)
implementation
(
"me.zhanghai.android.fastscroll:library:1.1.
4
"
)
implementation
(
"xyz.belvi.mobilevision:barcodescanner:2.0.3"
)
}
mobile/src/main/java/com/github/shadowsocks/App.kt
View file @
b00ae42a
...
...
@@ -24,7 +24,7 @@ import android.app.Application
import
android.content.res.Configuration
import
androidx.appcompat.app.AppCompatDelegate
class
App
:
Application
()
{
class
App
:
Application
()
,
androidx
.
work
.
Configuration
.
Provider
by
Core
{
override
fun
onCreate
()
{
super
.
onCreate
()
Core
.
init
(
this
,
MainActivity
::
class
)
...
...
mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
View file @
b00ae42a
...
...
@@ -88,7 +88,6 @@ class ProfileConfigFragment : PreferenceFragmentCompat(),
findPreference
<
EditTextPreference
>(
Key
.
remotePort
)
!!
.
setOnBindEditTextListener
(
EditTextPreferenceModifiers
.
Port
)
findPreference
<
EditTextPreference
>(
Key
.
password
)
!!
.
summaryProvider
=
PasswordSummaryProvider
val
serviceMode
=
DataStore
.
serviceMode
findPreference
<
Preference
>(
Key
.
remoteDns
)
!!
.
isEnabled
=
serviceMode
!=
Key
.
modeProxy
findPreference
<
Preference
>(
Key
.
ipv6
)
!!
.
isEnabled
=
serviceMode
==
Key
.
modeVpn
isProxyApps
=
findPreference
(
Key
.
proxyApps
)
!!
isProxyApps
.
isEnabled
=
serviceMode
==
Key
.
modeVpn
...
...
@@ -100,7 +99,6 @@ class ProfileConfigFragment : PreferenceFragmentCompat(),
findPreference
<
Preference
>(
Key
.
metered
)
!!
.
apply
{
if
(
Build
.
VERSION
.
SDK_INT
>=
28
)
isEnabled
=
serviceMode
==
Key
.
modeVpn
else
remove
()
}
findPreference
<
Preference
>(
Key
.
udpdns
)
!!
.
isEnabled
=
serviceMode
!=
Key
.
modeProxy
plugin
=
findPreference
(
Key
.
plugin
)
!!
pluginConfigure
=
findPreference
(
Key
.
pluginConfigure
)
!!
pluginConfigure
.
setOnBindEditTextListener
(
EditTextPreferenceModifiers
.
Monospace
)
...
...
mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt
View file @
b00ae42a
...
...
@@ -502,7 +502,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
try
{
val
profiles
=
Profile
.
findAllUrls
(
Core
.
clipboard
.
primaryClip
!!
.
getItemAt
(
0
).
text
,
Core
.
currentProfile
?.
first
Core
.
currentProfile
?.
main
).
toList
()
if
(
profiles
.
isNotEmpty
())
{
profiles
.
forEach
{
ProfileManager
.
createProfile
(
it
)
}
...
...
@@ -533,7 +533,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
}
R
.
id
.
action_manual_settings
->
{
startConfig
(
ProfileManager
.
createProfile
(
Profile
().
also
{
Core
.
currentProfile
?.
first
?.
copyFeatureSettingsTo
(
it
)
}))
Profile
().
also
{
Core
.
currentProfile
?.
main
?.
copyFeatureSettingsTo
(
it
)
}))
true
}
R
.
id
.
action_export_clipboard
->
{
...
...
mobile/src/main/java/com/github/shadowsocks/ScannerActivity.kt
View file @
b00ae42a
...
...
@@ -105,7 +105,7 @@ class ScannerActivity : AppCompatActivity(), BarcodeRetriever {
}
override
fun
onRetrieved
(
barcode
:
Barcode
)
=
runOnUiThread
{
Profile
.
findAllUrls
(
barcode
.
rawValue
,
Core
.
currentProfile
?.
first
).
forEach
{
ProfileManager
.
createProfile
(
it
)
}
Profile
.
findAllUrls
(
barcode
.
rawValue
,
Core
.
currentProfile
?.
main
).
forEach
{
ProfileManager
.
createProfile
(
it
)
}
onSupportNavigateUp
()
}
override
fun
onRetrievedMultiple
(
closetToClick
:
Barcode
?,
barcode
:
MutableList
<
BarcodeGraphic
>?)
=
check
(
false
)
...
...
@@ -141,7 +141,7 @@ class ScannerActivity : AppCompatActivity(), BarcodeRetriever {
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
?)
{
when
(
requestCode
)
{
REQUEST_IMPORT
,
REQUEST_IMPORT_OR_FINISH
->
if
(
resultCode
==
Activity
.
RESULT_OK
)
{
val
feature
=
Core
.
currentProfile
?.
first
val
feature
=
Core
.
currentProfile
?.
main
try
{
var
success
=
false
data
!!
.
datas
.
forEachTry
{
uri
->
...
...
mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
View file @
b00ae42a
...
...
@@ -362,7 +362,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
}
private
val
isEnabled
get
()
=
(
activity
as
?
MainActivity
)
?.
state
==
BaseService
.
State
.
Stopped
||
Core
.
currentProfile
?.
first
?.
route
!=
Acl
.
CUSTOM_RULES
Core
.
currentProfile
?.
main
?.
route
!=
Acl
.
CUSTOM_RULES
private
val
selectedItems
=
HashSet
<
Any
>()
private
val
adapter
by
lazy
{
AclRulesAdapter
()
}
...
...
plugin/build.gradle.kts
View file @
b00ae42a
...
...
@@ -14,8 +14,6 @@ android {
}
}
androidExtensions
.
isExperimental
=
true
mavenPublish
.
targets
.
getByName
(
"uploadArchives"
)
{
releaseRepositoryUrl
=
"https://oss.sonatype.org/service/local/staging/deploy/maven2/"
snapshotRepositoryUrl
=
"https://oss.sonatype.org/content/repositories/snapshots/"
...
...
@@ -27,6 +25,6 @@ dependencies {
api
(
kotlin
(
"stdlib-jdk8"
,
rootProject
.
extra
.
get
(
"kotlinVersion"
).
toString
()))
api
(
"androidx.core:core-ktx:1.2.0"
)
// https://android-developers.googleblog.com/2019/07/android-q-beta-5-update.html
api
(
"androidx.drawerlayout:drawerlayout:1.1.0-
beta
01"
)
api
(
"androidx.drawerlayout:drawerlayout:1.1.0-
rc
01"
)
api
(
"com.google.android.material:material:1.1.0"
)
}
repositories.gradle.kts
View file @
b00ae42a
rootProject
.
extra
.
apply
{
set
(
"androidPlugin"
,
"com.android.tools.build:gradle:4.1.0-
alpha06
"
)
set
(
"androidPlugin"
,
"com.android.tools.build:gradle:4.1.0-
beta01
"
)
set
(
"kotlinVersion"
,
"1.3.72"
)
}
...
...
tv/src/main/java/com/github/shadowsocks/tv/App.kt
View file @
b00ae42a
...
...
@@ -24,7 +24,7 @@ import android.app.Application
import
android.content.res.Configuration
import
com.github.shadowsocks.Core
class
App
:
Application
()
{
class
App
:
Application
()
,
androidx
.
work
.
Configuration
.
Provider
by
Core
{
override
fun
onCreate
()
{
super
.
onCreate
()
Core
.
init
(
this
,
MainActivity
::
class
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment