Compare commits

..
5 Commits
Author SHA1 Message Date
Max Lv dec098fbc5 refine the lock screen receiver 2014-12-18 09:17:57 +08:00
Max Lv 000d03ad4c update shadowsocks-libev 2014-12-17 08:49:43 +08:00
Max Lv 667619f701 tune timeout for long tcp connection 2014-12-17 08:42:43 +08:00
Max Lv afd91b7155 fix #186 2014-12-15 17:19:40 +08:00
Max Lv e10272c8e5 disable uptest in pdnsd 2014-12-14 14:46:16 +08:00
12 changed files with 160 additions and 35 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks"
android:versionCode="93"
android:versionName="2.5.4">
android:versionCode="95"
android:versionName="2.5.5">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+8
View File
@@ -0,0 +1,8 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/action_export"
android:title="@string/action_export"
android:showAsAction="never" />
<item android:id="@+id/action_import"
android:title="@string/action_import"
android:showAsAction="never" />
</menu>
+7
View File
@@ -88,4 +88,11 @@
<item>绕过局域网及中国大陆地址</item>
</string-array>
<string name="action_export">导出至剪贴板</string>
<string name="action_import">从剪贴板导入</string>
<string name="action_export_msg">导出成功</string>
<string name="action_export_err">导出失败</string>
<string name="action_import_msg">导入成功</string>
<string name="action_import_err">导入失败</string>
</resources>
+2 -1
View File
@@ -4,6 +4,7 @@
<color name="title_background">#ff5e5e5e</color>
<color name="dialog_title_background">#17170443</color>
<color name="white">#FFFFFF</color>
<color name="black">#000000</color>
<color name="grey1">#646464</color>
<color name="grey2">#c8c8c8</color>
@@ -11,4 +12,4 @@
<color name="md__transparent">#00000000</color>
<color name="md__defaultBackground">#FF555555</color>
</resources>
</resources>
+6
View File
@@ -86,6 +86,12 @@
<string name="flush_dnscache">Flush DNS Cache</string>
<string name="flushing">Flushing</string>
<string name="add_profile">Add Profile</string>
<string name="action_export">Export to Clipboard</string>
<string name="action_import">Import from Clipboard</string>
<string name="action_export_msg">Successfully export!</string>
<string name="action_export_err">Failed to export.</string>
<string name="action_import_msg">Successfully import!</string>
<string name="action_import_err">Failed to import.</string>
<!-- profile -->
<string name="add_profile_dialog">Add this Shadowsocks Profile?</string>
+15 -4
View File
@@ -29,10 +29,10 @@
<item name="android:actionModeBackground">@drawable/cab_background_top_shadow</item>
<item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_shadow</item>
<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
<!-- Light.DarkActionBar specific -->
<!-- Light.DarkActionBar specific -->
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
</style>
<style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
@@ -51,6 +51,14 @@
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
</style>
<style name="m_textAppearanceSmallPopupMenu" parent="@android:style/TextAppearance.Holo.Widget.PopupMenu.Small">
<item name="android:textColor">@android:color/white</item>
</style>
<style name="m_textAppearanceLargePopupMenu" parent="@android:style/TextAppearance.Holo.Widget.PopupMenu.Large">
<item name="android:textColor">@android:color/white</item>
</style>
<style name="DropDownListView.Shadow" parent="@android:style/Widget.Holo.ListView.DropDown">
<item name="android:listSelector">@drawable/selectable_background_shadow</item>
</style>
@@ -77,6 +85,9 @@
<style name="Theme.Shadow.Widget" parent="@android:style/Theme.Holo">
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
</style>
</resources>
</resources>
@@ -40,6 +40,8 @@
package com.github.shadowsocks
import android.app.{Activity, ProgressDialog}
import android.content.ClipboardManager
import android.content.ClipData
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
@@ -47,6 +49,8 @@ import android.graphics.{Bitmap, PixelFormat}
import android.os.Bundle
import android.os.Handler
import android.preference.PreferenceManager
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
@@ -115,7 +119,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
var appsLoaded: Boolean = false
def loadApps(context: Context): Array[ProxiedApp] = {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val proxiedAppString = prefs.getString(Key.proxied, "")
val proxiedApps = proxiedAppString.split('|').sortWith(_ < _)
@@ -218,6 +222,48 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
}
}
protected override def onOptionsItemSelected(item: MenuItem): Boolean = {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE).asInstanceOf[ClipboardManager]
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
item.getItemId match {
case R.id.action_export =>
val proxiedAppString = prefs.getString(Key.proxied, "")
val clip = ClipData.newPlainText(Key.proxied, proxiedAppString)
clipboard.setPrimaryClip(clip)
Toast.makeText(this, R.string.action_export_msg, Toast.LENGTH_SHORT).show()
return true
case R.id.action_import =>
if (clipboard.hasPrimaryClip) {
val clipdata = clipboard.getPrimaryClip
val label = clipdata.getDescription.getLabel
if (label == Key.proxied) {
val proxiedAppSequence = clipdata.getItemAt(0).getText
if (proxiedAppSequence != null) {
val proxiedAppString = proxiedAppSequence.toString
if (!proxiedAppString.isEmpty) {
Toast.makeText(this, R.string.action_import_msg, Toast.LENGTH_SHORT).show()
prefs.edit.putString(Key.proxied, proxiedAppString).commit()
// Restart activity
val intent = getIntent
finish()
startActivity(intent)
return true
}
}
}
}
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show()
return false
}
super.onOptionsItemSelected(item)
}
protected override def onCreateOptionsMenu(menu: Menu): Boolean = {
val inflater = getMenuInflater()
inflater.inflate(R.menu.app_manager_menu, menu)
return super.onCreateOptionsMenu(menu)
}
protected override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
@@ -239,7 +285,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
ImageLoader.getInstance().init(config)
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener {
def onCheckedChanged(button: CompoundButton, checked: Boolean) {
prefs.edit().putBoolean(Key.isBypassApps, checked).commit()
@@ -261,7 +307,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
def saveAppSettings(context: Context) {
if (apps == null) return
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val proxiedApps = new StringBuilder
apps.foreach(app =>
if (app.proxied) {
@@ -49,8 +49,8 @@ import android.content.Context
trait BaseService {
@volatile var state = State.INIT
@volatile var callbackCount = 0
@volatile private var state = State.INIT
@volatile private var callbackCount = 0
final val callbacks = new RemoteCallbackList[IShadowsocksServiceCallback]
@@ -100,6 +100,12 @@ trait BaseService {
def getTag: String
def getContext: Context
def getCallbackCount(): Int = {
callbackCount
}
def getState(): Int = {
state
}
def changeState(s: Int) {
changeState(s, null)
}
@@ -43,7 +43,7 @@ import java.io.File
import java.lang.reflect.{InvocationTargetException, Method}
import java.util.Locale
import android.app.{Notification, NotificationManager, PendingIntent, Service}
import android.app._
import android.content._
import android.content.pm.{PackageInfo, PackageManager}
import android.net.{Network, ConnectivityManager}
@@ -75,6 +75,7 @@ class ShadowsocksNatService extends Service with BaseService {
private val mStartForegroundArgs = new Array[AnyRef](2)
private val mStopForegroundArgs = new Array[AnyRef](1)
var lockReceiver: BroadcastReceiver = null
var closeReceiver: BroadcastReceiver = null
var connReceiver: BroadcastReceiver = null
var notificationManager: NotificationManager = null
@@ -200,6 +201,7 @@ class ShadowsocksNatService extends Service with BaseService {
val cmd = new ArrayBuffer[String]
cmd += (Path.BASE + "ss-local"
, "-b" , "127.0.0.1"
, "-t" , "600"
, "-c" , Path.BASE + "ss-local-nat.conf"
, "-f" , Path.BASE + "ss-local-nat.pid")
@@ -223,6 +225,7 @@ class ShadowsocksNatService extends Service with BaseService {
val cmd = new ArrayBuffer[String]
cmd += (Path.BASE + "ss-tunnel"
, "-u"
, "-t" , "10"
, "-b" , "127.0.0.1"
, "-L" , "8.8.8.8:53"
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
@@ -244,6 +247,7 @@ class ShadowsocksNatService extends Service with BaseService {
val cmdBuf = new ArrayBuffer[String]
cmdBuf += (Path.BASE + "ss-tunnel"
, "-u"
, "-t" , "10"
, "-b" , "127.0.0.1"
, "-l" , "8163"
, "-L" , "8.8.8.8:53"
@@ -324,7 +328,7 @@ class ShadowsocksNatService extends Service with BaseService {
}
}
def notifyForegroundAlert(title: String, info: String) {
def notifyForegroundAlert(title: String, info: String, visible: Boolean) {
val openIntent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
val contentIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
@@ -341,7 +345,11 @@ class ShadowsocksNatService extends Service with BaseService {
.setSmallIcon(R.drawable.ic_stat_shadowsocks)
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.stop),
actionIntent)
.setPriority(NotificationCompat.PRIORITY_MIN)
if (visible)
builder.setPriority(NotificationCompat.PRIORITY_MAX)
else
builder.setPriority(NotificationCompat.PRIORITY_MIN)
startForegroundCompat(1, builder.build)
}
@@ -497,13 +505,39 @@ class ShadowsocksNatService extends Service with BaseService {
filter.addAction(Intent.ACTION_SHUTDOWN)
filter.addAction(Action.CLOSE)
closeReceiver = new BroadcastReceiver() {
def onReceive(p1: Context, p2: Intent) {
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT).show()
def onReceive(context: Context, intent: Intent) {
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
stopRunner()
}
}
registerReceiver(closeReceiver, filter)
val screenFilter = new IntentFilter()
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
screenFilter.addAction(Intent.ACTION_USER_PRESENT)
lockReceiver = new BroadcastReceiver() {
def onReceive(context: Context, intent: Intent) {
if (getState == State.CONNECTED) {
val action = intent.getAction
if (action == Intent.ACTION_SCREEN_OFF) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false)
} else if (action == Intent.ACTION_SCREEN_ON) {
val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
if (!keyGuard.inKeyguardRestrictedInputMode) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
}
} else if (action == Intent.ACTION_USER_PRESENT) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
}
}
}
}
registerReceiver(lockReceiver, screenFilter)
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(TAG)
@@ -551,7 +585,7 @@ class ShadowsocksNatService extends Service with BaseService {
flushDns()
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName))
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
changeState(State.CONNECTED)
} else {
changeState(State.STOPPED, getString(R.string.service_failed))
@@ -571,6 +605,10 @@ class ShadowsocksNatService extends Service with BaseService {
unregisterReceiver(closeReceiver)
closeReceiver = null
}
if (lockReceiver != null) {
unregisterReceiver(lockReceiver)
lockReceiver = null
}
// send event
application.tracker.send(new HitBuilders.EventBuilder()
@@ -583,7 +621,7 @@ class ShadowsocksNatService extends Service with BaseService {
killProcesses()
// stop the service if no callback registered
if (callbackCount == 0) {
if (getCallbackCount == 0) {
stopSelf()
}
@@ -116,9 +116,10 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val cmd = new ArrayBuffer[String]
cmd +=(Path.BASE + "ss-local", "-u"
, "-b", "127.0.0.1"
, "-c", Path.BASE + "ss-local-vpn.conf"
, "-f", Path.BASE + "ss-local-vpn.pid")
, "-b" , "127.0.0.1"
, "-t" , "600"
, "-c" , Path.BASE + "ss-local-vpn.conf"
, "-f" , Path.BASE + "ss-local-vpn.pid")
if (Utils.isLollipopOrAbove && config.route != Route.ALL) {
cmd += "--acl"
@@ -139,11 +140,12 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val cmd = new ArrayBuffer[String]
cmd +=(Path.BASE + "ss-tunnel"
, "-u"
, "-b", "127.0.0.1"
, "-l", "8163"
, "-L", "8.8.8.8:53"
, "-c", Path.BASE + "ss-tunnel-vpn.conf"
, "-f", Path.BASE + "ss-tunnel-vpn.pid")
, "-t" , "10"
, "-b" , "127.0.0.1"
, "-l" , "8163"
, "-L" , "8.8.8.8:53"
, "-c" , Path.BASE + "ss-tunnel-vpn.conf"
, "-f" , Path.BASE + "ss-tunnel-vpn.pid")
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
Console.runCommand(cmd.mkString(" "))
@@ -477,7 +479,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
// stop the service if no callback registered
if (callbackCount == 0) {
if (getCallbackCount == 0) {
stopSelf()
}
@@ -123,6 +123,8 @@ object ConfigUtils {
|server {
| label = "local-server";
| ip = 127.0.0.1;
| uptest = none;
| preset = on;
| port = %d;
| timeout = 5;
|}
@@ -159,9 +161,8 @@ object ConfigUtils {
| reject = %s;
| reject_policy = fail;
| reject_recursively = on;
| uptest = query;
| query_test_name = ".";
| interval = ontimeout;
| uptest = none;
| preset = on;
|}
|
|server {
@@ -172,9 +173,8 @@ object ConfigUtils {
| reject = %s;
| reject_policy = fail;
| reject_recursively = on;
| uptest = query;
| query_test_name = ".";
| interval = ontimeout;
| uptest = none;
| preset = on;
|}
|
|server {