diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f14f04c3..1294e97e 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2,12 +2,13 @@
+ android:versionCode="4"
+ android:versionName="1.1">
+
+
+
+
+
+
+
diff --git a/assets/local.js b/assets/local.js
index cdb3937a..bad00dda 100644
--- a/assets/local.js
+++ b/assets/local.js
@@ -164,6 +164,11 @@
console.log = function() {};
+ var pid = ""+process.pid; // need to turn into a string
+ fs.writeFile('/data/data/com.github.shadowsocks/shadowsocks.pid', pid, function (err) {
+ // Ignore
+ });
+
console.log("calculating ciphers");
tables = getTable(KEY);
@@ -332,11 +337,6 @@
});
});
- var pid = ""+process.pid; // need to turn into a string
- fs.writeFile('/data/data/com.github.shadowsocks/shadowsocks.pid', pid, function (err) {
- // Ignore
- });
-
server.listen(PORT, function() {
return console.log("server listening at port " + PORT);
});
diff --git a/pom.xml b/pom.xml
index a200a095..2fd1e3fa 100755
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.github.shadowsocks
shadowsocks
- 1.0.2
+ 1.1
apk
Shadowsocks
diff --git a/res/xml/shadowsocks_preference.xml b/res/xml/shadowsocks_preference.xml
index 9016fa4a..53c31d18 100755
--- a/res/xml/shadowsocks_preference.xml
+++ b/res/xml/shadowsocks_preference.xml
@@ -4,6 +4,7 @@
@@ -11,24 +12,28 @@
-
+
+
diff --git a/src/com/github/shadowsocks/Shadowsocks.java b/src/com/github/shadowsocks/Shadowsocks.java
index e697586a..9ed19629 100644
--- a/src/com/github/shadowsocks/Shadowsocks.java
+++ b/src/com/github/shadowsocks/Shadowsocks.java
@@ -103,13 +103,10 @@ public class Shadowsocks extends PreferenceActivity implements
private static ProgressDialog mProgressDialog = null;
- private CheckBoxPreference isGlobalProxyCheck;
private EditTextPreference proxyText;
private EditTextPreference portText;
private EditTextPreference remotePortText;
private EditTextPreference sitekeyText;
- private CheckBoxPreference isGFWListCheck;
- private CheckBoxPreference isRunningCheck;
private Preference proxyedApps;
private CheckBoxPreference isBypassAppsCheck;
@@ -159,32 +156,6 @@ public class Shadowsocks extends PreferenceActivity implements
}
- private void disableAll() {
- proxyText.setEnabled(false);
- portText.setEnabled(false);
- remotePortText.setEnabled(false);
- sitekeyText.setEnabled(false);
- proxyedApps.setEnabled(false);
- isGFWListCheck.setEnabled(false);
- isBypassAppsCheck.setEnabled(false);
-
- isGlobalProxyCheck.setEnabled(false);
- }
-
- private void enableAll() {
- proxyText.setEnabled(true);
- portText.setEnabled(true);
- remotePortText.setEnabled(true);
- sitekeyText.setEnabled(true);
- isGlobalProxyCheck.setEnabled(true);
- isGFWListCheck.setEnabled(true);
- if (!isGlobalProxyCheck.isChecked()) {
- proxyedApps.setEnabled(true);
- isBypassAppsCheck.setEnabled(true);
- }
-
- }
-
private boolean isTextEmpty(String s, String msg) {
if (s == null || s.length() <= 0) {
showAToast(msg);
@@ -208,9 +179,6 @@ public class Shadowsocks extends PreferenceActivity implements
sitekeyText = (EditTextPreference) findPreference("sitekey");
proxyedApps = findPreference("proxyedApps");
- isRunningCheck = (CheckBoxPreference) findPreference("isRunning");
- isGlobalProxyCheck = (CheckBoxPreference) findPreference("isGlobalProxy");
- isGFWListCheck = (CheckBoxPreference) findPreference("isGFWList");
isBypassAppsCheck = (CheckBoxPreference) findPreference("isBypassApps");
if (mProgressDialog == null)
@@ -350,23 +318,14 @@ public class Shadowsocks extends PreferenceActivity implements
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(this);
- if (settings.getBoolean("isSystemProxy", false)) {
- isGlobalProxyCheck.setEnabled(false);
- isGFWListCheck.setEnabled(false);
+ if (settings.getBoolean("isGlobalProxy", false)) {
proxyedApps.setEnabled(false);
isBypassAppsCheck.setEnabled(false);
} else {
- if (settings.getBoolean("isGlobalProxy", false)) {
- proxyedApps.setEnabled(false);
- isBypassAppsCheck.setEnabled(false);
- } else {
- proxyedApps.setEnabled(true);
- isBypassAppsCheck.setEnabled(true);
- }
+ proxyedApps.setEnabled(true);
+ isBypassAppsCheck.setEnabled(true);
}
- sitekeyText.setEnabled(true);
-
Editor edit = settings.edit();
if (ShadowsocksService.isServiceStarted()) {
@@ -386,14 +345,6 @@ public class Shadowsocks extends PreferenceActivity implements
edit.commit();
- if (settings.getBoolean("isRunning", false)) {
- isRunningCheck.setChecked(true);
- disableAll();
- } else {
- isRunningCheck.setChecked(false);
- enableAll();
- }
-
// Setup the initial values
if (!settings.getString("sitekey", "").equals(""))
@@ -448,15 +399,6 @@ public class Shadowsocks extends PreferenceActivity implements
}
}
- if (key.equals("isRunning")) {
- if (settings.getBoolean("isRunning", false)) {
- disableAll();
- isRunningCheck.setChecked(true);
- } else {
- isRunningCheck.setChecked(false);
- enableAll();
- }
- }
if (key.equals("remotePort"))
if (settings.getString("remotePort", "").equals(""))
diff --git a/src/com/github/shadowsocks/ShadowsocksReceiver.java b/src/com/github/shadowsocks/ShadowsocksReceiver.java
new file mode 100644
index 00000000..2f67afe2
--- /dev/null
+++ b/src/com/github/shadowsocks/ShadowsocksReceiver.java
@@ -0,0 +1,47 @@
+package com.github.shadowsocks;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.preference.PreferenceManager;
+
+public class ShadowsocksReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "Shadowsocks";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
+ String versionName;
+ try {
+ versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ versionName = "NONE";
+ }
+
+ final boolean isAutoConnect = settings.getBoolean("isAutoConnect", false);
+ final boolean isInstalled = settings.getBoolean(versionName, false);
+
+ if (isAutoConnect && isInstalled) {
+ final String portText = settings.getString("port", "");
+ if (portText == null || portText.length() <= 0) {
+ return;
+ }
+ try {
+ int port = Integer.valueOf(portText);
+ if (port <= 1024) {
+ return;
+ }
+ } catch (Exception e) {
+ return;
+ }
+
+ Intent it = new Intent(context, ShadowsocksService.class);
+ context.startService(it);
+ }
+ }
+
+}
diff --git a/src/com/github/shadowsocks/ShadowsocksService.java b/src/com/github/shadowsocks/ShadowsocksService.java
index 144f0f59..3c999777 100755
--- a/src/com/github/shadowsocks/ShadowsocksService.java
+++ b/src/com/github/shadowsocks/ShadowsocksService.java
@@ -56,8 +56,7 @@ import android.preference.PreferenceManager;
import android.util.Log;
import com.google.analytics.tracking.android.EasyTracker;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import java.io.*;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -183,7 +182,22 @@ public class ShadowsocksService extends Service {
return isServiceStarted;
}
- public void startShadowsocksDaemon() {
+ private int getPid(String name) {
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(BASE + name + ".pid"));
+ final String line = reader.readLine();
+ return Integer.valueOf(line);
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Cannot open pid file: " + name);
+ } catch (IOException e) {
+ Log.e(TAG, "Cannot read pid file: " + name);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Invalid pid", e);
+ }
+ return -1;
+ }
+
+ private void startShadowsocksDaemon() {
new Thread() {
@Override
public void run() {
@@ -195,9 +209,9 @@ public class ShadowsocksService extends Service {
}.start();
}
- public void startDnsDaemon() {
+ private void startDnsDaemon() {
final String cmd = BASE + "pdnsd -c " + BASE + "pdnsd.conf";
- Utils.runRootCommand(cmd);
+ Utils.runCommand(cmd);
}
private String getVersionName() {
@@ -277,7 +291,26 @@ public class ShadowsocksService extends Service {
BASE, BASE, BASE);
Utils.runRootCommand("echo \"" + conf + "\" > " + BASE + "redsocks.conf\n"
+ cmd);
+ }
+ private boolean waitForProcess(final String name) {
+ final int pid = getPid(name);
+ if (pid == -1) return false;
+
+ Exec.hangupProcessGroup(-pid);
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ Exec.waitFor(-pid);
+ Log.d(TAG, "Successfully exit pid: " + pid);
+ }
+ };
+ t.start();
+ try {
+ t.join(300);
+ } catch (InterruptedException ignored) {
+ }
+ return !t.isAlive();
}
/**
@@ -436,9 +469,13 @@ public class ShadowsocksService extends Service {
private void onDisconnect() {
Utils.runRootCommand(Utils.getIptables() + " -t nat -F OUTPUT");
StringBuilder sb = new StringBuilder();
- sb.append("kill -9 `cat /data/data/com.github.shadowsocks/pdnsd.pid`").append("\n");
sb.append("kill -9 `cat /data/data/com.github.shadowsocks/redsocks.pid`").append("\n");
- sb.append("kill -9 `cat /data/data/com.github.shadowsocks/shadowsocks.pid`").append("\n");
+ if (!waitForProcess("pdnsd")) {
+ sb.append("kill -9 `cat /data/data/com.github.shadowsocks/pdnsd.pid`").append("\n");
+ }
+ if (!waitForProcess("shadowsocks")) {
+ sb.append("kill -9 `cat /data/data/com.github.shadowsocks/shadowsocks.pid`").append("\n");
+ }
Utils.runRootCommand(sb.toString());
}