diff --git a/README.md b/README.md
index e56eded8..3bcf2be2 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
## Shadowsocks for Android
[](https://travis-ci.org/shadowsocks/shadowsocks-android)
-[](https://android-arsenal.com/api?level=19)
+[](https://android-arsenal.com/api?level=21)
[](https://github.com/shadowsocks/shadowsocks-android/releases)
[](https://www.gnu.org/licenses/gpl-3.0)
diff --git a/build.gradle b/build.gradle
index 92e6c03e..039d7e95 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,8 +2,8 @@
buildscript {
ext {
- kotlinVersion = '1.2.10'
- minSdkVersion = 19
+ kotlinVersion = '1.2.20'
+ minSdkVersion = 21
sdkVersion = 27
buildToolsVersion = '27.0.3'
supportLibraryVersion = '27.0.2'
diff --git a/core/src/main/java/com/github/shadowsocks/JniHelper.java b/core/src/main/java/com/github/shadowsocks/JniHelper.java
index ff111a65..d4167a67 100755
--- a/core/src/main/java/com/github/shadowsocks/JniHelper.java
+++ b/core/src/main/java/com/github/shadowsocks/JniHelper.java
@@ -43,8 +43,6 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.system.ErrnoException;
-import java.net.InetAddress;
-
public class JniHelper {
static {
System.loadLibrary("jni-helper");
@@ -54,8 +52,7 @@ public class JniHelper {
public static void sigtermCompat(@NonNull Process process) throws Exception {
if (Build.VERSION.SDK_INT >= 24) throw new UnsupportedOperationException("Never call this method in OpenJDK!");
int errno = sigterm(process);
- if (errno != 0) throw Build.VERSION.SDK_INT >= 21
- ? new ErrnoException("kill", errno) : new Exception("kill failed: " + errno);
+ if (errno != 0) throw new ErrnoException("kill", errno);
}
@Deprecated // only implemented for before API 24
diff --git a/core/src/overture/make.bash b/core/src/overture/make.bash
index a857f2c5..0aadf24e 100755
--- a/core/src/overture/make.bash
+++ b/core/src/overture/make.bash
@@ -12,7 +12,7 @@ TARGET=$DIR/bin
DEPS=$DIR/.deps
ANDROID_ARM_TOOLCHAIN=$DEPS/android-toolchain-${MIN_API}-arm
-ANDROID_ARM64_TOOLCHAIN=$DEPS/android-toolchain-21-arm64
+ANDROID_ARM64_TOOLCHAIN=$DEPS/android-toolchain-${MIN_API}-arm64
ANDROID_X86_TOOLCHAIN=$DEPS/android-toolchain-${MIN_API}-x86
ANDROID_ARM_CC=$ANDROID_ARM_TOOLCHAIN/bin/arm-linux-androideabi-clang
@@ -35,7 +35,7 @@ fi
if [ ! -f "$ANDROID_ARM64_CC" ]; then
echo "Make standalone toolchain for ARM64 arch"
$ANDROID_NDK_HOME/build/tools/make_standalone_toolchain.py --arch arm64 \
- --api 21 --install-dir $ANDROID_ARM64_TOOLCHAIN
+ --api $MIN_API --install-dir $ANDROID_ARM64_TOOLCHAIN
fi
if [ ! -f "$ANDROID_X86_CC" ]; then
diff --git a/core/src/overture/make.bat b/core/src/overture/make.bat
index 1dae4616..065de4f8 100644
--- a/core/src/overture/make.bat
+++ b/core/src/overture/make.bat
@@ -11,7 +11,7 @@ SET TARGET=%DIR%\bin
SET DEPS=%DIR%\.deps
SET ANDROID_ARM_TOOLCHAIN=%DEPS%\android-toolchain-%MIN_API%-arm
-SET ANDROID_ARM64_TOOLCHAIN=%DEPS%\android-toolchain-21-arm64
+SET ANDROID_ARM64_TOOLCHAIN=%DEPS%\android-toolchain-%MIN_API%-arm64
SET ANDROID_X86_TOOLCHAIN=%DEPS%\android-toolchain-%MIN_API%-x86
SET ANDROID_ARM_CC=%ANDROID_ARM_TOOLCHAIN%\bin\arm-linux-androideabi-clang
@@ -37,7 +37,7 @@ IF NOT EXIST %ANDROID_ARM_CC% (
IF NOT EXIST %ANDROID_ARM64_CC% (
ECHO "Make standalone toolchain for ARM64 arch"
%ANDROID_NDK_HOME%\build\tools\make_standalone_toolchain.py --arch arm64 ^
- --api 21 --install-dir %ANDROID_ARM64_TOOLCHAIN%
+ --api %MIN_API% --install-dir %ANDROID_ARM64_TOOLCHAIN%
)
IF NOT EXIST %ANDROID_X86_CC% (
diff --git a/mobile/build.gradle b/mobile/build.gradle
index 51f22d6d..41add3a3 100644
--- a/mobile/build.gradle
+++ b/mobile/build.gradle
@@ -24,7 +24,6 @@ android {
versionName "4.4.5"
testApplicationId "com.github.shadowsocks.test"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- vectorDrawables.useSupportLibrary true
resConfigs "fa", "fr", "ja", "ko", "ru", "zh-rCN", "zh-rTW"
}
buildTypes {
@@ -48,17 +47,13 @@ dependencies {
implementation "com.android.support:design:$supportLibraryVersion"
implementation "com.android.support:gridlayout-v7:$supportLibraryVersion"
implementation 'com.futuremind.recyclerfastscroll:fastscroll:0.2.5'
- implementation 'com.evernote:android-job:1.2.1'
+ implementation 'com.evernote:android-job:1.2.2'
implementation "com.google.android.gms:play-services-ads:$playServicesVersion"
implementation "com.google.android.gms:play-services-analytics:$playServicesVersion"
- implementation "com.google.android.gms:play-services-gcm:$playServicesVersion"
implementation "com.google.firebase:firebase-config:$playServicesVersion"
implementation 'com.j256.ormlite:ormlite-android:5.0'
implementation 'com.mikepenz:crossfader:1.5.1'
- implementation 'com.mikepenz:fastadapter:3.0.4'
- implementation 'com.mikepenz:iconics-core:3.0.0'
implementation 'com.mikepenz:materialdrawer:6.0.2'
- implementation 'com.mikepenz:materialize:1.1.2'
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
implementation "com.takisoft.fix:preference-v7-simplemenu:$takisoftFixVersion"
implementation 'com.twofortyfouram:android-plugin-api-for-locale:1.0.2'
diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml
index a552d5b1..fc8517ce 100644
--- a/mobile/src/main/AndroidManifest.xml
+++ b/mobile/src/main/AndroidManifest.xml
@@ -171,9 +171,11 @@
-
+
diff --git a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
index ea511abe..98817951 100644
--- a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
@@ -80,13 +80,11 @@ class ProfileConfigFragment : PreferenceFragmentCompatDividers(), Toolbar.OnMenu
val serviceMode = DataStore.serviceMode
findPreference(Key.remoteDns).isEnabled = serviceMode != Key.modeProxy
isProxyApps = findPreference(Key.proxyApps) as SwitchPreference
- if (Build.VERSION.SDK_INT < 21) isProxyApps.parent!!.removePreference(isProxyApps) else {
- isProxyApps.isEnabled = serviceMode == Key.modeVpn
- isProxyApps.setOnPreferenceClickListener {
- startActivity(Intent(activity, AppManager::class.java))
- isProxyApps.isChecked = true
- false
- }
+ isProxyApps.isEnabled = serviceMode == Key.modeVpn
+ isProxyApps.setOnPreferenceClickListener {
+ startActivity(Intent(activity, AppManager::class.java))
+ isProxyApps.isChecked = true
+ false
}
findPreference(Key.udpdns).isEnabled = serviceMode != Key.modeProxy
plugin = findPreference(Key.plugin) as IconListPreference
diff --git a/mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt b/mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt
index 05ab6bc9..56d6840d 100644
--- a/mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt
@@ -20,49 +20,19 @@
package com.github.shadowsocks.bg
-import android.content.Context
-import android.net.ConnectivityManager
-import android.net.LinkProperties
-import android.os.Build
import android.util.Log
import com.github.shadowsocks.App.Companion.app
import com.github.shadowsocks.BuildConfig
-import okhttp3.Dns as Okdns
import org.xbill.DNS.*
import java.net.Inet6Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.UnknownHostException
-import java.util.*
+import okhttp3.Dns as Okdns
object Dns {
private const val TAG = "Dns"
- @Throws(Exception::class)
- fun getDnsResolver(context: Context): String {
- val dnsResolvers = getDnsResolvers(context)
- if (dnsResolvers.isEmpty()) throw Exception("Couldn't find an active DNS resolver")
- val dnsResolver = dnsResolvers.iterator().next().toString()
- if (dnsResolver.startsWith("/")) return dnsResolver.substring(1)
- return dnsResolver
- }
-
- @Throws(Exception::class)
- private fun getDnsResolvers(context: Context): Collection {
- val addresses = ArrayList()
- val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
- val classLinkProperties = Class.forName("android.net.LinkProperties")
- val getActiveLinkPropertiesMethod = ConnectivityManager::class.java.getMethod("getActiveLinkProperties")
- val linkProperties = getActiveLinkPropertiesMethod.invoke(connectivityManager)
- if (linkProperties != null) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- val dnses = classLinkProperties.getMethod("getDnses").invoke(linkProperties) as Collection<*>
- dnses.mapTo(addresses) { it as InetAddress }
- } else addresses.addAll((linkProperties as LinkProperties).dnsServers)
- }
- return addresses
- }
-
private val hasIPv6Support get() = try {
val result = NetworkInterface.getNetworkInterfaces().asSequence().flatMap { it.inetAddresses.asSequence() }
.count { it is Inet6Address && !it.isLoopbackAddress && !it.isLinkLocalAddress } > 0
diff --git a/mobile/src/main/java/com/github/shadowsocks/bg/ServiceNotification.kt b/mobile/src/main/java/com/github/shadowsocks/bg/ServiceNotification.kt
index e4974a21..cd16d74a 100644
--- a/mobile/src/main/java/com/github/shadowsocks/bg/ServiceNotification.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/bg/ServiceNotification.kt
@@ -40,8 +40,7 @@ import java.util.*
/**
* Android < 8 VPN: always invisible because of VPN notification/icon
- * Android 4.x other: always visible
- * Android 5-7 other: only invisible in (possibly unsecure) lockscreen
+ * Android < 8 other: only invisible in (possibly unsecure) lockscreen
* Android 8+: always visible due to system limitations
* (user can choose to hide the notification in secure lockscreen or anywhere)
*/
@@ -85,24 +84,22 @@ class ServiceNotification(private val service: BaseService.Interface, profileNam
if (Build.VERSION.SDK_INT < 24) builder.addAction(R.drawable.ic_navigation_close,
service.getString(R.string.stop), PendingIntent.getBroadcast(service, 0, Intent(Action.CLOSE), 0))
val power = service.getSystemService(Context.POWER_SERVICE) as PowerManager
- update(if (if (Build.VERSION.SDK_INT >= 20) power.isInteractive else @Suppress("DEPRECATION") power.isScreenOn)
- Intent.ACTION_SCREEN_ON else Intent.ACTION_SCREEN_OFF, true)
+ update(if (power.isInteractive) Intent.ACTION_SCREEN_ON else Intent.ACTION_SCREEN_OFF, true)
val screenFilter = IntentFilter()
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
- if (visible && Build.VERSION.SDK_INT in 21 until 26) screenFilter.addAction(Intent.ACTION_USER_PRESENT)
+ if (visible && Build.VERSION.SDK_INT < 26) screenFilter.addAction(Intent.ACTION_USER_PRESENT)
service.registerReceiver(lockReceiver, screenFilter)
}
private fun update(action: String, forceShow: Boolean = false) {
if (forceShow || service.data.state == BaseService.CONNECTED) when (action) {
Intent.ACTION_SCREEN_OFF -> {
- setVisible(visible && Build.VERSION.SDK_INT < 21, forceShow)
+ setVisible(false, forceShow)
unregisterCallback() // unregister callback to save battery
}
Intent.ACTION_SCREEN_ON -> {
- setVisible(visible && (Build.VERSION.SDK_INT < 21 || !keyGuard.inKeyguardRestrictedInputMode()),
- forceShow)
+ setVisible(visible && !keyGuard.inKeyguardRestrictedInputMode(), forceShow)
service.data.binder.registerCallback(callback)
service.data.binder.startListeningForBandwidth(callback)
callbackRegistered = true
diff --git a/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt b/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt
index 4a456d5a..ca3055f3 100644
--- a/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt
@@ -24,7 +24,6 @@ import android.app.Service
import android.content.Intent
import android.content.pm.PackageManager
import android.net.LocalSocket
-import android.os.Build
import android.os.IBinder
import android.os.ParcelFileDescriptor
import android.util.Log
@@ -140,7 +139,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
builder.addRoute("::", 0)
}
- if (Build.VERSION.SDK_INT >= 21 && profile.proxyApps) {
+ if (profile.proxyApps) {
val me = packageName
profile.individual.split('\n')
.filter { it != me }
diff --git a/mobile/src/main/java/com/github/shadowsocks/tasker/ConfigActivity.kt b/mobile/src/main/java/com/github/shadowsocks/tasker/ConfigActivity.kt
index 68afd7c4..602f75d7 100644
--- a/mobile/src/main/java/com/github/shadowsocks/tasker/ConfigActivity.kt
+++ b/mobile/src/main/java/com/github/shadowsocks/tasker/ConfigActivity.kt
@@ -22,7 +22,6 @@ package com.github.shadowsocks.tasker
import android.app.Activity
import android.content.res.Resources
-import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.DefaultItemAnimator
@@ -71,13 +70,12 @@ class ConfigActivity : AppCompatActivity() {
inner class ProfilesAdapter : RecyclerView.Adapter() {
internal val profiles = ProfileManager.getAllProfiles()?.toMutableList() ?: mutableListOf()
- private val name = "select_dialog_singlechoice_" + (if (Build.VERSION.SDK_INT >= 21) "material" else "holo")
override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) =
if (position == 0) holder.bindDefault() else holder.bind(profiles[position - 1])
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileViewHolder = ProfileViewHolder(
LayoutInflater.from(parent.context).inflate(Resources.getSystem()
- .getIdentifier(name, "layout", "android"), parent, false))
+ .getIdentifier("select_dialog_singlechoice_material", "layout", "android"), parent, false))
override fun getItemCount(): Int = 1 + profiles.size
}
diff --git a/mobile/src/main/res/drawable-hdpi/ic_navigation_close.webp b/mobile/src/main/res/drawable-hdpi/ic_navigation_close.webp
deleted file mode 100644
index 541301f0..00000000
Binary files a/mobile/src/main/res/drawable-hdpi/ic_navigation_close.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-hdpi/ic_service_active.webp b/mobile/src/main/res/drawable-hdpi/ic_service_active.webp
deleted file mode 100644
index 65182a59..00000000
Binary files a/mobile/src/main/res/drawable-hdpi/ic_service_active.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_navigation_close.webp b/mobile/src/main/res/drawable-mdpi/ic_navigation_close.webp
deleted file mode 100644
index 2c66e486..00000000
Binary files a/mobile/src/main/res/drawable-mdpi/ic_navigation_close.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_service_active.webp b/mobile/src/main/res/drawable-mdpi/ic_service_active.webp
deleted file mode 100644
index 0182a994..00000000
Binary files a/mobile/src/main/res/drawable-mdpi/ic_service_active.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-v21/background_profile.xml b/mobile/src/main/res/drawable-v21/background_profile.xml
deleted file mode 100644
index 3509fa32..00000000
--- a/mobile/src/main/res/drawable-v21/background_profile.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
diff --git a/mobile/src/main/res/drawable-v21/background_selectable.xml b/mobile/src/main/res/drawable-v21/background_selectable.xml
deleted file mode 100644
index b8810034..00000000
--- a/mobile/src/main/res/drawable-v21/background_selectable.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- -
-
-
-
-
-
-
-
-
-
diff --git a/mobile/src/main/res/drawable-v21/background_stat.xml b/mobile/src/main/res/drawable-v21/background_stat.xml
deleted file mode 100644
index 48bdd29f..00000000
--- a/mobile/src/main/res/drawable-v21/background_stat.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- -
-
-
-
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_navigation_close.webp b/mobile/src/main/res/drawable-xhdpi/ic_navigation_close.webp
deleted file mode 100644
index c1d0fd16..00000000
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_navigation_close.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_service_active.webp b/mobile/src/main/res/drawable-xhdpi/ic_service_active.webp
deleted file mode 100644
index 0e0bbf50..00000000
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_service_active.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_navigation_close.webp b/mobile/src/main/res/drawable-xxhdpi/ic_navigation_close.webp
deleted file mode 100644
index 1ae09899..00000000
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_navigation_close.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_service_active.webp b/mobile/src/main/res/drawable-xxhdpi/ic_service_active.webp
deleted file mode 100644
index bb2c5bc2..00000000
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_service_active.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_navigation_close.webp b/mobile/src/main/res/drawable-xxxhdpi/ic_navigation_close.webp
deleted file mode 100644
index 439b8fe8..00000000
Binary files a/mobile/src/main/res/drawable-xxxhdpi/ic_navigation_close.webp and /dev/null differ
diff --git a/mobile/src/main/res/drawable/background_profile.xml b/mobile/src/main/res/drawable/background_profile.xml
index 28592514..3509fa32 100644
--- a/mobile/src/main/res/drawable/background_profile.xml
+++ b/mobile/src/main/res/drawable/background_profile.xml
@@ -15,18 +15,11 @@
- -
+
+
-
- -
-
-
-
-
-
-
-
-
-
+
diff --git a/mobile/src/main/res/drawable/background_selectable.xml b/mobile/src/main/res/drawable/background_selectable.xml
index c969f4ac..b8810034 100644
--- a/mobile/src/main/res/drawable/background_selectable.xml
+++ b/mobile/src/main/res/drawable/background_selectable.xml
@@ -1,11 +1,12 @@
-
- -
-
+
+
-
+
+
-
+
+
+
- -
-
-
-
+
+
diff --git a/mobile/src/main/res/drawable/background_stat.xml b/mobile/src/main/res/drawable/background_stat.xml
index fe7ba6d4..7c56f04c 100644
--- a/mobile/src/main/res/drawable/background_stat.xml
+++ b/mobile/src/main/res/drawable/background_stat.xml
@@ -1,17 +1,7 @@
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
+
+
diff --git a/mobile/src/main/res/drawable-anydpi-v21/ic_navigation_close.xml b/mobile/src/main/res/drawable/ic_navigation_close.xml
similarity index 100%
rename from mobile/src/main/res/drawable-anydpi-v21/ic_navigation_close.xml
rename to mobile/src/main/res/drawable/ic_navigation_close.xml
diff --git a/mobile/src/main/res/drawable-anydpi-v21/ic_service_active.xml b/mobile/src/main/res/drawable/ic_service_active.xml
similarity index 100%
rename from mobile/src/main/res/drawable-anydpi-v21/ic_service_active.xml
rename to mobile/src/main/res/drawable/ic_service_active.xml
diff --git a/mobile/src/main/res/layout/layout_main.xml b/mobile/src/main/res/layout/layout_main.xml
index 480022ba..85a0de78 100644
--- a/mobile/src/main/res/layout/layout_main.xml
+++ b/mobile/src/main/res/layout/layout_main.xml
@@ -148,7 +148,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
- android:layout_marginTop="@dimen/fab_margin_top"
+ android:layout_marginTop="-28dp"
android:elevation="6dp"
app:layout_anchor="@id/stat"
app:layout_anchorGravity="top|end">
diff --git a/mobile/src/main/res/values-v21/dimen.xml b/mobile/src/main/res/values-v21/dimen.xml
deleted file mode 100644
index 605379c3..00000000
--- a/mobile/src/main/res/values-v21/dimen.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- -28dp
-
diff --git a/mobile/src/main/res/values/dimen.xml b/mobile/src/main/res/values/dimen.xml
index ce2156f8..522ab6ce 100644
--- a/mobile/src/main/res/values/dimen.xml
+++ b/mobile/src/main/res/values/dimen.xml
@@ -4,5 +4,4 @@
250dp
8dp
8dp
- -44dp
diff --git a/plugin/build.gradle b/plugin/build.gradle
index 6c9c6336..19ec80ad 100644
--- a/plugin/build.gradle
+++ b/plugin/build.gradle
@@ -24,7 +24,6 @@ android {
}
dependencies {
- api "com.android.support:preference-v7:$supportLibraryVersion"
api "com.android.support:preference-v14:$supportLibraryVersion"
api "com.takisoft.fix:preference-v7:$takisoftFixVersion"
api "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlinVersion"