Commit 3d664377 authored by Max Lv's avatar Max Lv

clean up

parent a74c3fde
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" <item android:state_pressed="true"
android:drawable="@drawable/btn_cab_done_pressed_shadow" /> android:drawable="@drawable/btn_cab_done_pressed_shadow"/>
<item android:state_focused="true" android:state_enabled="true" <item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_cab_done_focused_shadow" /> android:drawable="@drawable/btn_cab_done_focused_shadow"/>
<item android:state_enabled="true" <item android:state_enabled="true"
android:drawable="@drawable/btn_cab_done_default_shadow" /> android:drawable="@drawable/btn_cab_done_default_shadow"/>
</selector> </selector>
...@@ -18,5 +18,5 @@ ...@@ -18,5 +18,5 @@
--> -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/pressed_shadow" /> <solid android:color="@color/pressed_shadow"/>
</shape> </shape>
...@@ -20,16 +20,16 @@ ...@@ -20,16 +20,16 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background" <item android:id="@android:id/background"
android:drawable="@drawable/progress_bg_shadow" /> android:drawable="@drawable/progress_bg_shadow"/>
<item android:id="@android:id/secondaryProgress"> <item android:id="@android:id/secondaryProgress">
<scale android:scaleWidth="100%" <scale android:scaleWidth="100%"
android:drawable="@drawable/progress_secondary_shadow" /> android:drawable="@drawable/progress_secondary_shadow"/>
</item> </item>
<item android:id="@android:id/progress"> <item android:id="@android:id/progress">
<scale android:scaleWidth="100%" <scale android:scaleWidth="100%"
android:drawable="@drawable/progress_primary_shadow" /> android:drawable="@drawable/progress_primary_shadow"/>
</item> </item>
</layer-list> </layer-list>
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
--> -->
<selector xmlns:android="http://schemas.android.com/apk/res/android" <selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="@android:integer/config_mediumAnimTime" > android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_pressed="false" android:state_focused="true" android:drawable="@drawable/list_focused_shadow" /> <item android:state_pressed="false" android:state_focused="true"
<item android:state_pressed="true" android:drawable="@drawable/pressed_background_shadow" /> android:drawable="@drawable/list_focused_shadow"/>
<item android:drawable="@android:color/transparent" /> <item android:state_pressed="true" android:drawable="@drawable/pressed_background_shadow"/>
<item android:drawable="@android:color/transparent"/>
</selector> </selector>
\ No newline at end of file
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" <item android:state_enabled="false"
android:drawable="@drawable/spinner_ab_disabled_shadow" /> android:drawable="@drawable/spinner_ab_disabled_shadow"/>
<item android:state_pressed="true" <item android:state_pressed="true"
android:drawable="@drawable/spinner_ab_pressed_shadow" /> android:drawable="@drawable/spinner_ab_pressed_shadow"/>
<item android:state_pressed="false" android:state_focused="true" <item android:state_pressed="false" android:state_focused="true"
android:drawable="@drawable/spinner_ab_focused_shadow" /> android:drawable="@drawable/spinner_ab_focused_shadow"/>
<item android:drawable="@drawable/spinner_ab_default_shadow" /> <item android:drawable="@drawable/spinner_ab_default_shadow"/>
</selector> </selector>
...@@ -19,19 +19,27 @@ ...@@ -19,19 +19,27 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states --> <!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@android:color/transparent" /> <item android:state_focused="false" android:state_selected="false" android:state_pressed="false"
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_shadow" /> android:drawable="@android:color/transparent"/>
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false"
android:drawable="@drawable/tab_selected_shadow"/>
<!-- Focused states --> <!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused_shadow" /> <item android:state_focused="true" android:state_selected="false" android:state_pressed="false"
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_shadow" /> android:drawable="@drawable/tab_unselected_focused_shadow"/>
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false"
android:drawable="@drawable/tab_selected_focused_shadow"/>
<!-- Pressed --> <!-- Pressed -->
<!-- Non focused states --> <!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_shadow" /> <item android:state_focused="false" android:state_selected="false" android:state_pressed="true"
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_shadow" /> android:drawable="@drawable/tab_unselected_pressed_shadow"/>
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true"
android:drawable="@drawable/tab_selected_pressed_shadow"/>
<!-- Focused states --> <!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_shadow" /> <item android:state_focused="true" android:state_selected="false" android:state_pressed="true"
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_shadow" /> android:drawable="@drawable/tab_unselected_pressed_shadow"/>
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true"
android:drawable="@drawable/tab_selected_pressed_shadow"/>
</selector> </selector>
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
android:minWidth="80dp" android:maxWidth="80dp" android:gravity="center" android:minWidth="80dp" android:maxWidth="80dp" android:gravity="center"
android:textSize="70sp" android:textColor="#ffffffff" android:textSize="70sp" android:textColor="#ffffffff"
android:background="#99000088" android:padding="10dp" android:background="#99000088" android:padding="10dp"
android:visibility="invisible" /> android:visibility="invisible"/>
\ No newline at end of file \ No newline at end of file
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
</style> </style>
<style name="ActionBar.Solid.Shadow" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse"> <style name="ActionBar.Solid.Shadow"
parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="android:background">@drawable/ab_solid_shadow</item> <item name="android:background">@drawable/ab_solid_shadow</item>
<item name="android:backgroundStacked">@drawable/ab_stacked_solid_shadow</item> <item name="android:backgroundStacked">@drawable/ab_stacked_solid_shadow</item>
<item name="android:backgroundSplit">@drawable/ab_bottom_solid_shadow</item> <item name="android:backgroundSplit">@drawable/ab_bottom_solid_shadow</item>
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
</style> </style>
<style name="ActionBar.Solid.Shadow" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse"> <style name="ActionBar.Solid.Shadow"
parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="background">@drawable/ab_solid_shadow</item> <item name="background">@drawable/ab_solid_shadow</item>
<item name="backgroundStacked">@drawable/ab_stacked_solid_shadow</item> <item name="backgroundStacked">@drawable/ab_stacked_solid_shadow</item>
<item name="backgroundSplit">@drawable/ab_bottom_solid_shadow</item> <item name="backgroundSplit">@drawable/ab_bottom_solid_shadow</item>
...@@ -69,7 +70,8 @@ ...@@ -69,7 +70,8 @@
<item name="android:progressDrawable">@drawable/progress_horizontal_shadow</item> <item name="android:progressDrawable">@drawable/progress_horizontal_shadow</item>
</style> </style>
<style name="ActionButton.CloseMode.Shadow" parent="@style/Widget.Sherlock.ActionButton.CloseMode"> <style name="ActionButton.CloseMode.Shadow"
parent="@style/Widget.Sherlock.ActionButton.CloseMode">
<item name="android:background">@drawable/btn_cab_done_shadow</item> <item name="android:background">@drawable/btn_cab_done_shadow</item>
</style> </style>
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" <preference-headers
xmlns:unified="http://schemas.android.com/apk/res-auto"> xmlns:unified="http://schemas.android.com/apk/res-auto">
<header <header
......
...@@ -21,15 +21,26 @@ import android.view.View.OnClickListener; ...@@ -21,15 +21,26 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.*; import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener; import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.app.SherlockActivity;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.*; public class AppManager extends SherlockActivity
implements OnCheckedChangeListener, OnClickListener {
public class AppManager extends SherlockActivity implements OnCheckedChangeListener,
OnClickListener {
public final static String PREFS_KEY_PROXYED = "Proxyed"; public final static String PREFS_KEY_PROXYED = "Proxyed";
private static final int MSG_LOAD_START = 1; private static final int MSG_LOAD_START = 1;
...@@ -39,8 +50,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -39,8 +50,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case MSG_LOAD_START: case MSG_LOAD_START:
pd = ProgressDialog.show(AppManager.this, "", pd = ProgressDialog.show(AppManager.this, "", getString(R.string.loading), true, true);
getString(R.string.loading), true, true);
break; break;
case MSG_LOAD_FINISH: case MSG_LOAD_FINISH:
...@@ -51,23 +61,21 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -51,23 +61,21 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
boolean visible; boolean visible;
@Override @Override
public void onScroll(AbsListView view, public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int firstVisibleItem, int visibleItemCount,
int totalItemCount) { int totalItemCount) {
if (visible) { if (visible) {
String name = apps[firstVisibleItem].getName(); String name = apps[firstVisibleItem].getName();
if (name != null && name.length() > 1) if (name != null && name.length() > 1) {
overlay.setText(apps[firstVisibleItem] overlay.setText(apps[firstVisibleItem].getName().substring(0, 1));
.getName().substring(0, 1)); } else {
else
overlay.setText("*"); overlay.setText("*");
}
overlay.setVisibility(View.VISIBLE); overlay.setVisibility(View.VISIBLE);
} }
} }
@Override @Override
public void onScrollStateChanged(AbsListView view, public void onScrollStateChanged(AbsListView view, int scrollState) {
int scrollState) {
visible = true; visible = true;
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) { if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
overlay.setVisibility(View.INVISIBLE); overlay.setVisibility(View.INVISIBLE);
...@@ -95,8 +103,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -95,8 +103,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
public static ProxyedApp[] getProxyedApps(Context context) { public static ProxyedApp[] getProxyedApps(Context context) {
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
.getDefaultSharedPreferences(context);
String tordAppString = prefs.getString(PREFS_KEY_PROXYED, ""); String tordAppString = prefs.getString(PREFS_KEY_PROXYED, "");
String[] tordApps; String[] tordApps;
...@@ -125,8 +132,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -125,8 +132,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
aInfo = itAppInfo.next(); aInfo = itAppInfo.next();
// ignore system apps // ignore system apps
if (aInfo.uid < 10000) if (aInfo.uid < 10000) continue;
continue;
ProxyedApp app = new ProxyedApp(); ProxyedApp app = new ProxyedApp();
...@@ -135,8 +141,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -135,8 +141,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
app.setUsername(pMgr.getNameForUid(app.getUid())); app.setUsername(pMgr.getNameForUid(app.getUid()));
// check if this application is allowed // check if this application is allowed
if (aInfo.packageName != null if (aInfo.packageName != null && aInfo.packageName.equals("com.github.shadowsocks")) {
&& aInfo.packageName.equals("com.github.shadowsocks")) {
app.setProxyed(true); app.setProxyed(true);
} else if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) { } else if (Arrays.binarySearch(tordApps, app.getUsername()) >= 0) {
app.setProxyed(true); app.setProxyed(true);
...@@ -145,7 +150,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -145,7 +150,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
} }
vectorApps.add(app); vectorApps.add(app);
} }
ProxyedApp[] apps = new ProxyedApp[vectorApps.size()]; ProxyedApp[] apps = new ProxyedApp[vectorApps.size()];
...@@ -155,8 +159,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -155,8 +159,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
public void getApps(Context context) { public void getApps(Context context) {
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
.getDefaultSharedPreferences(context);
String tordAppString = prefs.getString(PREFS_KEY_PROXYED, ""); String tordAppString = prefs.getString(PREFS_KEY_PROXYED, "");
String[] tordApps; String[] tordApps;
...@@ -185,16 +188,15 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -185,16 +188,15 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
aInfo = itAppInfo.next(); aInfo = itAppInfo.next();
// ignore system apps // ignore system apps
if (aInfo.uid < 10000) if (aInfo.uid < 10000) continue;
continue;
if (aInfo.processName == null) if (aInfo.processName == null) continue;
continue; if (pMgr.getApplicationLabel(aInfo) == null || pMgr.getApplicationLabel(aInfo)
if (pMgr.getApplicationLabel(aInfo) == null .toString()
|| pMgr.getApplicationLabel(aInfo).toString().equals("")) .equals("")) {
continue;
if (pMgr.getApplicationIcon(aInfo) == null)
continue; continue;
}
if (pMgr.getApplicationIcon(aInfo) == null) continue;
ProxyedApp tApp = new ProxyedApp(); ProxyedApp tApp = new ProxyedApp();
...@@ -216,7 +218,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -216,7 +218,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
apps = new ProxyedApp[vectorApps.size()]; apps = new ProxyedApp[vectorApps.size()];
vectorApps.toArray(apps); vectorApps.toArray(apps);
} }
private void loadApps() { private void loadApps() {
...@@ -225,35 +226,26 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -225,35 +226,26 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
Arrays.sort(apps, new Comparator<ProxyedApp>() { Arrays.sort(apps, new Comparator<ProxyedApp>() {
@Override @Override
public int compare(ProxyedApp o1, ProxyedApp o2) { public int compare(ProxyedApp o1, ProxyedApp o2) {
if (o1 == null || o2 == null || o1.getName() == null if (o1 == null || o2 == null || o1.getName() == null || o2.getName() == null) return 1;
|| o2.getName() == null) if (o1.isProxyed() == o2.isProxyed()) return o1.getName().compareTo(o2.getName());
return 1; if (o1.isProxyed()) return -1;
if (o1.isProxyed() == o2.isProxyed())
return o1.getName().compareTo(o2.getName());
if (o1.isProxyed())
return -1;
return 1; return 1;
} }
}); });
final LayoutInflater inflater = getLayoutInflater(); final LayoutInflater inflater = getLayoutInflater();
adapter = new ArrayAdapter<ProxyedApp>(this, R.layout.layout_apps_item, adapter = new ArrayAdapter<ProxyedApp>(this, R.layout.layout_apps_item, R.id.itemtext, apps) {
R.id.itemtext, apps) {
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
ListEntry entry; ListEntry entry;
if (convertView == null) { if (convertView == null) {
// Inflate a new view // Inflate a new view
convertView = inflater.inflate(R.layout.layout_apps_item, convertView = inflater.inflate(R.layout.layout_apps_item, parent, false);
parent, false);
entry = new ListEntry(); entry = new ListEntry();
entry.icon = (ImageView) convertView entry.icon = (ImageView) convertView.findViewById(R.id.itemicon);
.findViewById(R.id.itemicon); entry.box = (CheckBox) convertView.findViewById(R.id.itemcheck);
entry.box = (CheckBox) convertView entry.text = (TextView) convertView.findViewById(R.id.itemtext);
.findViewById(R.id.itemcheck);
entry.text = (TextView) convertView
.findViewById(R.id.itemtext);
entry.text.setOnClickListener(mAppManager); entry.text.setOnClickListener(mAppManager);
entry.text.setOnClickListener(mAppManager); entry.text.setOnClickListener(mAppManager);
...@@ -270,8 +262,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -270,8 +262,7 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
entry.icon.setTag(app.getUid()); entry.icon.setTag(app.getUid());
dm.DisplayImage(app.getUid(), dm.DisplayImage(app.getUid(), (Activity) convertView.getContext(), entry.icon);
(Activity) convertView.getContext(), entry.icon);
entry.text.setText(app.getName()); entry.text.setText(app.getName());
...@@ -286,12 +277,9 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -286,12 +277,9 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
}; };
appsLoaded = true; appsLoaded = true;
} }
/** /** Called an application is check/unchecked */
* Called an application is check/unchecked
*/
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final ProxyedApp app = (ProxyedApp) buttonView.getTag(); final ProxyedApp app = (ProxyedApp) buttonView.getTag();
...@@ -300,7 +288,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -300,7 +288,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
} }
saveAppSettings(this); saveAppSettings(this);
} }
@Override @Override
...@@ -315,7 +302,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -315,7 +302,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
} }
saveAppSettings(this); saveAppSettings(this);
} }
@Override @Override
...@@ -327,19 +313,13 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -327,19 +313,13 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
this.dm = ImageLoaderFactory.getImageLoader(this); this.dm = ImageLoaderFactory.getImageLoader(this);
this.overlay = (TextView) View.inflate(this, R.layout.overlay, null); this.overlay = (TextView) View.inflate(this, R.layout.overlay, null);
getWindowManager() getWindowManager().addView(overlay,
.addView( new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
overlay,
new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT));
PixelFormat.TRANSLUCENT));
mAppManager = this; mAppManager = this;
} }
@Override @Override
...@@ -354,12 +334,10 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -354,12 +334,10 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
listApps = (ListView) findViewById(R.id.applistview); listApps = (ListView) findViewById(R.id.applistview);
if (!appsLoaded) if (!appsLoaded) loadApps();
loadApps();
handler.sendEmptyMessage(MSG_LOAD_FINISH); handler.sendEmptyMessage(MSG_LOAD_FINISH);
} }
}.start(); }.start();
} }
/* /*
...@@ -375,11 +353,9 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -375,11 +353,9 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
} }
public void saveAppSettings(Context context) { public void saveAppSettings(Context context) {
if (apps == null) if (apps == null) return;
return;
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
.getDefaultSharedPreferences(this);
// final SharedPreferences prefs = // final SharedPreferences prefs =
// context.getSharedPreferences(PREFS_KEY, 0); // context.getSharedPreferences(PREFS_KEY, 0);
...@@ -396,7 +372,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -396,7 +372,6 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
Editor edit = prefs.edit(); Editor edit = prefs.edit();
edit.putString(PREFS_KEY_PROXYED, tordApps.toString()); edit.putString(PREFS_KEY_PROXYED, tordApps.toString());
edit.commit(); edit.commit();
} }
private static class ListEntry { private static class ListEntry {
...@@ -404,5 +379,4 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe ...@@ -404,5 +379,4 @@ public class AppManager extends SherlockActivity implements OnCheckedChangeListe
private TextView text; private TextView text;
private ImageView icon; private ImageView icon;
} }
} }
...@@ -31,9 +31,7 @@ public class Exec { ...@@ -31,9 +31,7 @@ public class Exec {
java.lang.System.loadLibrary("exec"); java.lang.System.loadLibrary("exec");
} }
/** /** Close a given file descriptor. */
* Close a given file descriptor.
*/
public static native void close(FileDescriptor fd); public static native void close(FileDescriptor fd);
/** /**
...@@ -53,13 +51,10 @@ public class Exec { ...@@ -53,13 +51,10 @@ public class Exec {
* process will be written. * process will be written.
* @return File descriptor * @return File descriptor
*/ */
public static native FileDescriptor createSubprocess(int rdt, String cmd, public static native FileDescriptor createSubprocess(int rdt, String cmd, String[] args,
String[] args, String[] envVars, String[] envVars, String scripts, int[] processId);
String scripts, int[] processId);
/** /** Send SIGHUP to a process group. */
* Send SIGHUP to a process group.
*/
public static native void hangupProcessGroup(int processId); public static native void hangupProcessGroup(int processId);
/** /**
......
...@@ -45,7 +45,6 @@ import android.graphics.Bitmap; ...@@ -45,7 +45,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.widget.ImageView; import android.widget.ImageView;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
...@@ -72,7 +71,6 @@ public class ImageLoader { ...@@ -72,7 +71,6 @@ public class ImageLoader {
// Find the dir to save cached images // Find the dir to save cached images
cacheDir = context.getCacheDir(); cacheDir = context.getCacheDir();
} }
public void clearCache() { public void clearCache() {
...@@ -98,9 +96,7 @@ public class ImageLoader { ...@@ -98,9 +96,7 @@ public class ImageLoader {
int width_tmp = o.outWidth, height_tmp = o.outHeight; int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1; int scale = 1;
while (true) { while (true) {
if (width_tmp / 2 < REQUIRED_SIZE if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) break;
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2; width_tmp /= 2;
height_tmp /= 2; height_tmp /= 2;
scale *= 2; scale *= 2;
...@@ -116,9 +112,9 @@ public class ImageLoader { ...@@ -116,9 +112,9 @@ public class ImageLoader {
} }
public void DisplayImage(int uid, Activity activity, ImageView imageView) { public void DisplayImage(int uid, Activity activity, ImageView imageView) {
if (cache.containsKey(uid)) if (cache.containsKey(uid)) {
imageView.setImageBitmap(cache.get(uid)); imageView.setImageBitmap(cache.get(uid));
else { } else {
queuePhoto(uid, activity, imageView); queuePhoto(uid, activity, imageView);
imageView.setImageResource(stub_id); imageView.setImageResource(stub_id);
} }
...@@ -132,13 +128,11 @@ public class ImageLoader { ...@@ -132,13 +128,11 @@ public class ImageLoader {
// from SD cache // from SD cache
Bitmap b = decodeFile(f); Bitmap b = decodeFile(f);
if (b != null) if (b != null) return b;
return b;
// from web // from web
try { try {
BitmapDrawable icon = (BitmapDrawable) Utils.getAppIcon(context, BitmapDrawable icon = (BitmapDrawable) Utils.getAppIcon(context, uid);
uid);
return icon.getBitmap(); return icon.getBitmap();
} catch (Exception ex) { } catch (Exception ex) {
return null; return null;
...@@ -156,8 +150,7 @@ public class ImageLoader { ...@@ -156,8 +150,7 @@ public class ImageLoader {
} }
// start thread if it's not started yet // start thread if it's not started yet
if (photoLoaderThread.getState() == Thread.State.NEW) if (photoLoaderThread.getState() == Thread.State.NEW) photoLoaderThread.start();
photoLoaderThread.start();
} }
public void stopThread() { public void stopThread() {
...@@ -176,12 +169,13 @@ public class ImageLoader { ...@@ -176,12 +169,13 @@ public class ImageLoader {
@Override @Override
public void run() { public void run() {
if (bitmap != null) if (bitmap != null) {
imageView.setImageBitmap(bitmap); imageView.setImageBitmap(bitmap);
else } else {
imageView.setImageResource(stub_id); imageView.setImageResource(stub_id);
} }
} }
}
class PhotosLoader extends Thread { class PhotosLoader extends Thread {
@Override @Override
...@@ -190,10 +184,11 @@ public class ImageLoader { ...@@ -190,10 +184,11 @@ public class ImageLoader {
while (true) { while (true) {
// thread waits until there are any images to load in the // thread waits until there are any images to load in the
// queue // queue
if (photosQueue.photosToLoad.size() == 0) if (photosQueue.photosToLoad.size() == 0) {
synchronized (photosQueue.photosToLoad) { synchronized (photosQueue.photosToLoad) {
photosQueue.photosToLoad.wait(); photosQueue.photosToLoad.wait();
} }
}
if (photosQueue.photosToLoad.size() != 0) { if (photosQueue.photosToLoad.size() != 0) {
PhotoToLoad photoToLoad; PhotoToLoad photoToLoad;
synchronized (photosQueue.photosToLoad) { synchronized (photosQueue.photosToLoad) {
...@@ -203,15 +198,12 @@ public class ImageLoader { ...@@ -203,15 +198,12 @@ public class ImageLoader {
cache.put(photoToLoad.uid, bmp); cache.put(photoToLoad.uid, bmp);
Object tag = photoToLoad.imageView.getTag(); Object tag = photoToLoad.imageView.getTag();
if (tag != null && ((Integer) tag) == photoToLoad.uid) { if (tag != null && ((Integer) tag) == photoToLoad.uid) {
BitmapDisplayer bd = new BitmapDisplayer(bmp, BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad.imageView);
photoToLoad.imageView); Activity a = (Activity) photoToLoad.imageView.getContext();
Activity a = (Activity) photoToLoad.imageView
.getContext();
a.runOnUiThread(bd); a.runOnUiThread(bd);
} }
} }
if (Thread.interrupted()) if (Thread.interrupted()) break;
break;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
// allow thread to exit // allow thread to exit
...@@ -227,8 +219,11 @@ public class ImageLoader { ...@@ -227,8 +219,11 @@ public class ImageLoader {
public void Clean(ImageView image) { public void Clean(ImageView image) {
synchronized (photosToLoad) { synchronized (photosToLoad) {
for (int j = 0; j < photosToLoad.size(); ) { for (int j = 0; j < photosToLoad.size(); ) {
if (photosToLoad.get(j).imageView == image) photosToLoad.remove(j); if (photosToLoad.get(j).imageView == image) {
else ++j; photosToLoad.remove(j);
} else {
++j;
}
} }
} }
} }
...@@ -244,5 +239,4 @@ public class ImageLoader { ...@@ -244,5 +239,4 @@ public class ImageLoader {
imageView = i; imageView = i;
} }
} }
} }
...@@ -47,86 +47,62 @@ public class ProxyedApp { ...@@ -47,86 +47,62 @@ public class ProxyedApp {
private String name; private String name;
private boolean proxyed = false; private boolean proxyed = false;
/** /** @return the name */
* @return the name
*/
public String getName() { public String getName() {
return name; return name;
} }
/** /** @param name the name to set */
* @param name the name to set
*/
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
/** /** @return the procname */
* @return the procname
*/
public String getProcname() { public String getProcname() {
return procname; return procname;
} }
/** /** @param procname the procname to set */
* @param procname the procname to set
*/
public void setProcname(String procname) { public void setProcname(String procname) {
this.procname = procname; this.procname = procname;
} }
/** /** @return the uid */
* @return the uid
*/
public int getUid() { public int getUid() {
return uid; return uid;
} }
/** /** @param uid the uid to set */
* @param uid the uid to set
*/
public void setUid(int uid) { public void setUid(int uid) {
this.uid = uid; this.uid = uid;
} }
/** /** @return the username */
* @return the username
*/
public String getUsername() { public String getUsername() {
return username; return username;
} }
/** /** @param username the username to set */
* @param username the username to set
*/
public void setUsername(String username) { public void setUsername(String username) {
this.username = username; this.username = username;
} }
/** /** @return the enabled */
* @return the enabled
*/
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
} }
/** /** @param enabled the enabled to set */
* @param enabled the enabled to set
*/
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
this.enabled = enabled; this.enabled = enabled;
} }
/** /** @return the proxyed */
* @return the proxyed
*/
public boolean isProxyed() { public boolean isProxyed() {
return proxyed; return proxyed;
} }
/** /** @param proxyed the proxyed to set */
* @param proxyed the proxyed to set
*/
public void setProxyed(boolean proxyed) { public void setProxyed(boolean proxyed) {
this.proxyed = proxyed; this.proxyed = proxyed;
} }
......
...@@ -52,7 +52,8 @@ import android.graphics.Typeface; ...@@ -52,7 +52,8 @@ import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.preference.*; import android.preference.Preference;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.widget.CompoundButton; import android.widget.CompoundButton;
...@@ -61,26 +62,28 @@ import android.widget.TextView; ...@@ -61,26 +62,28 @@ import android.widget.TextView;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import com.google.analytics.tracking.android.EasyTracker; import com.google.analytics.tracking.android.EasyTracker;
import net.saik0.android.unifiedpreference.UnifiedPreferenceFragment;
import net.saik0.android.unifiedpreference.UnifiedSherlockPreferenceActivity;
import org.jraf.android.backport.switchwidget.Switch;
import de.keyboardsurfer.android.widget.crouton.Crouton; import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style; import de.keyboardsurfer.android.widget.crouton.Style;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Hashtable; import java.util.Hashtable;
import net.saik0.android.unifiedpreference.UnifiedPreferenceFragment;
import net.saik0.android.unifiedpreference.UnifiedSherlockPreferenceActivity;
import org.jraf.android.backport.switchwidget.Switch;
public class Shadowsocks extends UnifiedSherlockPreferenceActivity public class Shadowsocks extends UnifiedSherlockPreferenceActivity
implements CompoundButton.OnCheckedChangeListener, OnSharedPreferenceChangeListener { implements CompoundButton.OnCheckedChangeListener, OnSharedPreferenceChangeListener {
public static final String PREFS_NAME = "Shadowsocks"; public static final String PREFS_NAME = "Shadowsocks";
public static final String[] PROXY_PREFS = {"proxy", "remotePort", "port" public static final String[] PROXY_PREFS = {
, "sitekey", "encMethod"}; "proxy", "remotePort", "port", "sitekey", "encMethod"
public static final String[] FEATRUE_PREFS = {"isHTTPProxy", "isDNSProxy", "isGFWList", "isGlobalProxy", "isBypassApps" };
, "proxyedApps", "isAutoConnect"}; public static final String[] FEATRUE_PREFS = {
"isHTTPProxy", "isDNSProxy", "isGFWList", "isGlobalProxy", "isBypassApps", "proxyedApps",
"isAutoConnect"
};
private static final String TAG = "Shadowsocks"; private static final String TAG = "Shadowsocks";
private static final int MSG_CRASH_RECOVER = 1; private static final int MSG_CRASH_RECOVER = 1;
private static final int MSG_INITIAL_FINISH = 2; private static final int MSG_INITIAL_FINISH = 2;
...@@ -88,8 +91,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -88,8 +91,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
final Handler handler = new Handler() { final Handler handler = new Handler() {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(Shadowsocks.this);
.getDefaultSharedPreferences(Shadowsocks.this);
Editor ed = settings.edit(); Editor ed = settings.edit();
switch (msg.what) { switch (msg.what) {
case MSG_CRASH_RECOVER: case MSG_CRASH_RECOVER:
...@@ -128,8 +130,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -128,8 +130,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
} else { } else {
in = assetManager.open(file); in = assetManager.open(file);
} }
out = new FileOutputStream("/data/data/com.github.shadowsocks/" out = new FileOutputStream("/data/data/com.github.shadowsocks/" + file);
+ file);
copyFile(in, out); copyFile(in, out);
in.close(); in.close();
in = null; in = null;
...@@ -164,7 +165,6 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -164,7 +165,6 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
sb.append("killall -9 shadowsocks").append("\n"); sb.append("killall -9 shadowsocks").append("\n");
sb.append("killall -9 polipo").append("\n"); sb.append("killall -9 polipo").append("\n");
Utils.runRootCommand(sb.toString()); Utils.runRootCommand(sb.toString());
} }
private boolean isTextEmpty(String s, String msg) { private boolean isTextEmpty(String s, String msg) {
...@@ -184,23 +184,20 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -184,23 +184,20 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
} }
} }
/** /** Called when the activity is first created. */
* Called when the activity is first created.
*/
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
setHeaderRes(R.xml.shadowsocks_headers); setHeaderRes(R.xml.shadowsocks_headers);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
RelativeLayout switchLayout = (RelativeLayout) RelativeLayout switchLayout =
getLayoutInflater().inflate(R.layout.layout_switch, null); (RelativeLayout) getLayoutInflater().inflate(R.layout.layout_switch, null);
getSupportActionBar().setCustomView(switchLayout); getSupportActionBar().setCustomView(switchLayout);
getSupportActionBar().setDisplayShowTitleEnabled(false); getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowCustomEnabled(true); getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(false); getSupportActionBar().setDisplayShowHomeEnabled(false);
switchButton = (Switch) switchLayout.findViewById(R.id.switchButton); switchButton = (Switch) switchLayout.findViewById(R.id.switchButton);
TextView title = (TextView) switchLayout.findViewById(R.id.title); TextView title = (TextView) switchLayout.findViewById(R.id.title);
...@@ -208,6 +205,42 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -208,6 +205,42 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
if (tf != null) title.setTypeface(tf); if (tf != null) title.setTypeface(tf);
title.setText(R.string.app_name); title.setText(R.string.app_name);
final SharedPreferences settings =
PreferenceManager.getDefaultSharedPreferences(Shadowsocks.this);
boolean init =
!settings.getBoolean("isRunning", false) && !settings.getBoolean("isConnecting", false);
if (init) {
if (mProgressDialog == null) {
mProgressDialog =
ProgressDialog.show(this, "", getString(R.string.initializing), true, true);
}
new Thread() {
@Override
public void run() {
Utils.isRoot();
String versionName;
try {
versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
versionName = "NONE";
}
if (!settings.getBoolean(versionName, false)) {
Editor edit = settings.edit();
edit.putBoolean(versionName, true);
edit.commit();
reset();
}
handler.sendEmptyMessage(MSG_INITIAL_FINISH);
}
}.start();
}
} }
@Override @Override
...@@ -221,9 +254,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -221,9 +254,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
return true; return true;
} }
/** /** Called when the activity is closed. */
* Called when the activity is closed.
*/
@Override @Override
public void onDestroy() { public void onDestroy() {
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
...@@ -257,13 +288,12 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -257,13 +288,12 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
case 1: case 1:
String versionName = ""; String versionName = "";
try { try {
versionName = getPackageManager().getPackageInfo( versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
getPackageName(), 0).versionName;
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
versionName = ""; versionName = "";
} }
showAToast(getString(R.string.about) + " (" + versionName + ")\n\n" showAToast(getString(R.string.about) + " (" + versionName + ")\n\n" + getString(
+ getString(R.string.copy_rights)); R.string.copy_rights));
break; break;
} }
...@@ -280,8 +310,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -280,8 +310,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
.getDefaultSharedPreferences(this);
Editor edit = settings.edit(); Editor edit = settings.edit();
...@@ -309,15 +338,13 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -309,15 +338,13 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
switchButton.setOnCheckedChangeListener(this); switchButton.setOnCheckedChangeListener(this);
PreferenceManager.getDefaultSharedPreferences(this) PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this); .registerOnSharedPreferenceChangeListener(this);
} }
private void setPreferenceEnabled() { private void setPreferenceEnabled() {
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(Shadowsocks.this);
.getDefaultSharedPreferences(Shadowsocks.this);
boolean enabled = !settings.getBoolean("isRunning", false) boolean enabled =
&& !settings.getBoolean("isConnecting", false); !settings.getBoolean("isRunning", false) && !settings.getBoolean("isConnecting", false);
for (String name : PROXY_PREFS) { for (String name : PROXY_PREFS) {
Preference pref = findPreference(name); Preference pref = findPreference(name);
...@@ -328,8 +355,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -328,8 +355,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
for (String name : FEATRUE_PREFS) { for (String name : FEATRUE_PREFS) {
Preference pref = findPreference(name); Preference pref = findPreference(name);
if (pref != null) { if (pref != null) {
if (name.equals("isBypassApps") if (name.equals("isBypassApps") || name.equals("proxyedApps")) {
|| name.equals("proxyedApps")) {
boolean isGlobalProxy = settings.getBoolean("isGlobalProxy", false); boolean isGlobalProxy = settings.getBoolean("isGlobalProxy", false);
pref.setEnabled(enabled && !isGlobalProxy); pref.setEnabled(enabled && !isGlobalProxy);
} else { } else {
...@@ -340,11 +366,9 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -340,11 +366,9 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
} }
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
String key) {
// Let's do something a preference value changes // Let's do something a preference value changes
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
.getDefaultSharedPreferences(this);
if (key.equals("isRunning")) { if (key.equals("isRunning")) {
if (settings.getBoolean("isRunning", false)) { if (settings.getBoolean("isRunning", false)) {
...@@ -357,9 +381,10 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -357,9 +381,10 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
if (key.equals("isConnecting")) { if (key.equals("isConnecting")) {
if (settings.getBoolean("isConnecting", false)) { if (settings.getBoolean("isConnecting", false)) {
Log.d(TAG, "Connecting start"); Log.d(TAG, "Connecting start");
if (mProgressDialog == null) if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(this, "", mProgressDialog =
getString(R.string.connecting), true, true); ProgressDialog.show(this, "", getString(R.string.connecting), true, true);
}
} else { } else {
Log.d(TAG, "Connecting finish"); Log.d(TAG, "Connecting finish");
if (mProgressDialog != null) { if (mProgressDialog != null) {
...@@ -378,45 +403,6 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -378,45 +403,6 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
EasyTracker.getInstance().activityStart(this); EasyTracker.getInstance().activityStart(this);
final SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(Shadowsocks.this);
boolean init = !settings.getBoolean("isRunning", false)
&& !settings.getBoolean("isConnecting", false);
if (init) {
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(this, "",
getString(R.string.initializing), true, true);
}
new Thread() {
@Override
public void run() {
Utils.isRoot();
String versionName;
try {
versionName = getPackageManager().getPackageInfo(
getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
versionName = "NONE";
}
if (!settings.getBoolean(versionName, false)) {
Editor edit = settings.edit();
edit.putBoolean(versionName, true);
edit.commit();
reset();
}
handler.sendEmptyMessage(MSG_INITIAL_FINISH);
}
}.start();
}
} }
@Override @Override
...@@ -441,15 +427,14 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -441,15 +427,14 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
+ "chmod 755 /data/data/com.github.shadowsocks/redsocks\n" + "chmod 755 /data/data/com.github.shadowsocks/redsocks\n"
+ "chmod 755 /data/data/com.github.shadowsocks/pdnsd\n" + "chmod 755 /data/data/com.github.shadowsocks/pdnsd\n"
+ "chmod 755 /data/data/com.github.shadowsocks/shadowsocks\n" + "chmod 755 /data/data/com.github.shadowsocks/shadowsocks\n"
+ "chmod 755 /data/data/com.github.shadowsocks/polipo\n" + "chmod 755 /data/data/com.github.shadowsocks/polipo\n");
);
} }
private void recovery() { private void recovery() {
if (mProgressDialog == null) if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(this, "", getString(R.string.recovering), mProgressDialog = ProgressDialog.show(this, "", getString(R.string.recovering), true, true);
true, true); }
final Handler h = new Handler() { final Handler h = new Handler() {
@Override @Override
...@@ -472,12 +457,9 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -472,12 +457,9 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
h.sendEmptyMessage(0); h.sendEmptyMessage(0);
} }
}.start(); }.start();
} }
/** /** Called when connect button is clicked. */
* Called when connect button is clicked.
*/
public boolean serviceStart() { public boolean serviceStart() {
if (ShadowsocksService.isServiceStarted()) { if (ShadowsocksService.isServiceStarted()) {
...@@ -485,16 +467,13 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -485,16 +467,13 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
return false; return false;
} }
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
.getDefaultSharedPreferences(this);
final String proxy = settings.getString("proxy", ""); final String proxy = settings.getString("proxy", "");
if (isTextEmpty(proxy, getString(R.string.proxy_empty))) if (isTextEmpty(proxy, getString(R.string.proxy_empty))) return false;
return false;
String portText = settings.getString("port", ""); String portText = settings.getString("port", "");
if (isTextEmpty(portText, getString(R.string.port_empty))) if (isTextEmpty(portText, getString(R.string.port_empty))) return false;
return false;
try { try {
int port = Integer.valueOf(portText); int port = Integer.valueOf(portText);
if (port <= 1024) { if (port <= 1024) {
...@@ -516,8 +495,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -516,8 +495,7 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg) builder.setMessage(msg)
.setCancelable(false) .setCancelable(false)
.setNegativeButton(getString(R.string.ok_iknow), .setNegativeButton(getString(R.string.ok_iknow), new DialogInterface.OnClickListener() {
new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
dialog.cancel(); dialog.cancel();
...@@ -531,11 +509,10 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -531,11 +509,10 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
implements OnSharedPreferenceChangeListener { implements OnSharedPreferenceChangeListener {
private void setPreferenceEnabled() { private void setPreferenceEnabled() {
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
.getDefaultSharedPreferences(getActivity());
boolean enabled = !settings.getBoolean("isRunning", false) boolean enabled =
&& !settings.getBoolean("isConnecting", false); !settings.getBoolean("isRunning", false) && !settings.getBoolean("isConnecting", false);
for (String name : PROXY_PREFS) { for (String name : PROXY_PREFS) {
Preference pref = findPreference(name); Preference pref = findPreference(name);
...@@ -551,17 +528,14 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -551,17 +528,14 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
setPreferenceEnabled(); setPreferenceEnabled();
// Set up a listener whenever a key changes // Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences() getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
.registerOnSharedPreferenceChangeListener(this);
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
// Unregister the listener whenever a key changes // Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences() getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
.unregisterOnSharedPreferenceChangeListener(this);
} }
@Override @Override
...@@ -576,17 +550,15 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -576,17 +550,15 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
implements OnSharedPreferenceChangeListener { implements OnSharedPreferenceChangeListener {
private void setPreferenceEnabled() { private void setPreferenceEnabled() {
SharedPreferences settings = PreferenceManager SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
.getDefaultSharedPreferences(getActivity());
boolean enabled = !settings.getBoolean("isRunning", false) boolean enabled =
&& !settings.getBoolean("isConnecting", false); !settings.getBoolean("isRunning", false) && !settings.getBoolean("isConnecting", false);
for (String name : FEATRUE_PREFS) { for (String name : FEATRUE_PREFS) {
Preference pref = findPreference(name); Preference pref = findPreference(name);
if (pref != null) { if (pref != null) {
if (name.equals("isBypassApps") if (name.equals("isBypassApps") || name.equals("proxyedApps")) {
|| name.equals("proxyedApps")) {
boolean isGlobalProxy = settings.getBoolean("isGlobalProxy", false); boolean isGlobalProxy = settings.getBoolean("isGlobalProxy", false);
pref.setEnabled(enabled && !isGlobalProxy); pref.setEnabled(enabled && !isGlobalProxy);
} else { } else {
...@@ -602,16 +574,14 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -602,16 +574,14 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
setPreferenceEnabled(); setPreferenceEnabled();
// Set up a listener whenever a key changes // Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences() getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
.registerOnSharedPreferenceChangeListener(this);
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
// Unregister the listener whenever a key changes // Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences() getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
.unregisterOnSharedPreferenceChangeListener(this);
} }
@Override @Override
...@@ -631,12 +601,10 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -631,12 +601,10 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
synchronized (cache) { synchronized (cache) {
if (!cache.containsKey(assetPath)) { if (!cache.containsKey(assetPath)) {
try { try {
Typeface t = Typeface.createFromAsset(c.getAssets(), Typeface t = Typeface.createFromAsset(c.getAssets(), assetPath);
assetPath);
cache.put(assetPath, t); cache.put(assetPath, t);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "Could not get typeface '" + assetPath Log.e(TAG, "Could not get typeface '" + assetPath + "' because " + e.getMessage());
+ "' because " + e.getMessage());
return null; return null;
} }
} }
...@@ -644,5 +612,4 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity ...@@ -644,5 +612,4 @@ public class Shadowsocks extends UnifiedSherlockPreferenceActivity
} }
} }
} }
} }
...@@ -54,5 +54,4 @@ public class ShadowsocksApplication extends Application { ...@@ -54,5 +54,4 @@ public class ShadowsocksApplication extends Application {
EasyTracker.getInstance().setContext(this); EasyTracker.getInstance().setContext(this);
sTmpDir = getCacheDir().getAbsolutePath(); sTmpDir = getCacheDir().getAbsolutePath();
} }
} }
...@@ -63,7 +63,8 @@ public class ShadowsocksReceiver extends BroadcastReceiver { ...@@ -63,7 +63,8 @@ public class ShadowsocksReceiver extends BroadcastReceiver {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
String versionName; String versionName;
try { try {
versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; versionName =
context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
versionName = "NONE"; versionName = "NONE";
} }
...@@ -89,5 +90,4 @@ public class ShadowsocksReceiver extends BroadcastReceiver { ...@@ -89,5 +90,4 @@ public class ShadowsocksReceiver extends BroadcastReceiver {
context.startService(it); context.startService(it);
} }
} }
} }
...@@ -55,8 +55,6 @@ import android.os.PowerManager; ...@@ -55,8 +55,6 @@ import android.os.PowerManager;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import com.google.analytics.tracking.android.EasyTracker; import com.google.analytics.tracking.android.EasyTracker;
import org.apache.http.conn.util.InetAddressUtils;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
...@@ -68,6 +66,7 @@ import java.net.Inet6Address; ...@@ -68,6 +66,7 @@ import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.HashSet; import java.util.HashSet;
import org.apache.http.conn.util.InetAddressUtils;
public class ShadowsocksService extends Service { public class ShadowsocksService extends Service {
...@@ -89,10 +88,10 @@ public class ShadowsocksService extends Service { ...@@ -89,10 +88,10 @@ public class ShadowsocksService extends Service {
final static String SHADOWSOCKS_CONF = final static String SHADOWSOCKS_CONF =
"{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}"; "{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}";
final static String CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN\n"; final static String CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN\n";
final static String CMD_IPTABLES_REDIRECT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp " final static String CMD_IPTABLES_REDIRECT_ADD_SOCKS =
+ "-j REDIRECT --to 8123\n"; " -t nat -A OUTPUT -p tcp " + "-j REDIRECT --to 8123\n";
final static String CMD_IPTABLES_DNAT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp " final static String CMD_IPTABLES_DNAT_ADD_SOCKS =
+ "-j DNAT --to-destination 127.0.0.1:8123\n"; " -t nat -A OUTPUT -p tcp " + "-j DNAT --to-destination 127.0.0.1:8123\n";
private static final int MSG_CONNECT_START = 0; private static final int MSG_CONNECT_START = 0;
private static final int MSG_CONNECT_FINISH = 1; private static final int MSG_CONNECT_FINISH = 1;
private static final int MSG_CONNECT_SUCCESS = 2; private static final int MSG_CONNECT_SUCCESS = 2;
...@@ -101,10 +100,11 @@ public class ShadowsocksService extends Service { ...@@ -101,10 +100,11 @@ public class ShadowsocksService extends Service {
private static final int MSG_STOP_SELF = 5; private static final int MSG_STOP_SELF = 5;
private static final String TAG = "ShadowsocksService"; private static final String TAG = "ShadowsocksService";
private final static int DNS_PORT = 8153; private final static int DNS_PORT = 8153;
private static final Class<?>[] mStartForegroundSignature = new Class[]{ private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class}; int.class, Notification.class
private static final Class<?>[] mStopForegroundSignature = new Class[]{boolean.class}; };
private static final Class<?>[] mSetForegroundSignature = new Class[]{boolean.class}; private static final Class<?>[] mStopForegroundSignature = new Class[] { boolean.class };
private static final Class<?>[] mSetForegroundSignature = new Class[] { boolean.class };
/* /*
* This is a hack see * This is a hack see
* http://www.mail-archive.com/android-developers@googlegroups * http://www.mail-archive.com/android-developers@googlegroups
...@@ -123,8 +123,9 @@ public class ShadowsocksService extends Service { ...@@ -123,8 +123,9 @@ public class ShadowsocksService extends Service {
ed.putBoolean("isConnecting", true); ed.putBoolean("isConnecting", true);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK mWakeLock =
| PowerManager.ON_AFTER_RELEASE, "GAEProxy"); pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,
"GAEProxy");
mWakeLock.acquire(); mWakeLock.acquire();
...@@ -132,8 +133,7 @@ public class ShadowsocksService extends Service { ...@@ -132,8 +133,7 @@ public class ShadowsocksService extends Service {
case MSG_CONNECT_FINISH: case MSG_CONNECT_FINISH:
ed.putBoolean("isConnecting", false); ed.putBoolean("isConnecting", false);
if (mWakeLock != null && mWakeLock.isHeld()) if (mWakeLock != null && mWakeLock.isHeld()) mWakeLock.release();
mWakeLock.release();
break; break;
case MSG_CONNECT_SUCCESS: case MSG_CONNECT_SUCCESS:
...@@ -209,10 +209,11 @@ public class ShadowsocksService extends Service { ...@@ -209,10 +209,11 @@ public class ShadowsocksService extends Service {
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
final String cmd = String.format(BASE + final String cmd = String.format(BASE
+
"shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f " "shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f "
+ BASE + "shadowsocks.pid", + BASE
appHost, remotePort, localPort, sitekey, encMethod); + "shadowsocks.pid", appHost, remotePort, localPort, sitekey, encMethod);
System.exec(cmd); System.exec(cmd);
} }
}.start(); }.start();
...@@ -222,8 +223,8 @@ public class ShadowsocksService extends Service { ...@@ -222,8 +223,8 @@ public class ShadowsocksService extends Service {
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
final String cmd = String.format(BASE + final String cmd = String.format(BASE
"polipo proxyPort=%d socksParentProxy=127.0.0.1:%d daemonise=true pidFile=\"%s\" logLevel=1 logFile=\"%s\"", + "polipo proxyPort=%d socksParentProxy=127.0.0.1:%d daemonise=true pidFile=\"%s\" logLevel=1 logFile=\"%s\"",
localPort + 1, localPort, BASE + "polipo.pid", BASE + "polipo.log"); localPort + 1, localPort, BASE + "polipo.pid", BASE + "polipo.log");
System.exec(cmd); System.exec(cmd);
} }
...@@ -238,8 +239,7 @@ public class ShadowsocksService extends Service { ...@@ -238,8 +239,7 @@ public class ShadowsocksService extends Service {
private String getVersionName() { private String getVersionName() {
String version; String version;
try { try {
PackageInfo pi = getPackageManager().getPackageInfo( PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
getPackageName(), 0);
version = pi.versionName; version = pi.versionName;
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
version = "Package name not found"; version = "Package name not found";
...@@ -320,23 +320,18 @@ public class ShadowsocksService extends Service { ...@@ -320,23 +320,18 @@ public class ShadowsocksService extends Service {
if (resolved && handleConnection()) { if (resolved && handleConnection()) {
// Connection and forward successful // Connection and forward successful
notifyAlert(getString(R.string.forward_success), notifyAlert(getString(R.string.forward_success), getString(R.string.service_running));
getString(R.string.service_running));
handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 500); handler.sendEmptyMessageDelayed(MSG_CONNECT_SUCCESS, 500);
} else { } else {
// Connection or forward unsuccessful // Connection or forward unsuccessful
notifyAlert(getString(R.string.forward_fail), notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed));
getString(R.string.service_failed));
stopSelf(); stopSelf();
handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500); handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500);
} }
handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 500); handler.sendEmptyMessageDelayed(MSG_CONNECT_FINISH, 500);
} }
}).start(); }).start();
markServiceStarted(); markServiceStarted();
...@@ -344,10 +339,8 @@ public class ShadowsocksService extends Service { ...@@ -344,10 +339,8 @@ public class ShadowsocksService extends Service {
private void startRedsocksDaemon() { private void startRedsocksDaemon() {
String conf = String.format(REDSOCKS_CONF, localPort); String conf = String.format(REDSOCKS_CONF, localPort);
String cmd = String.format("%sredsocks -p %sredsocks.pid -c %sredsocks.conf", String cmd = String.format("%sredsocks -p %sredsocks.pid -c %sredsocks.conf", BASE, BASE, BASE);
BASE, BASE, BASE); Utils.runRootCommand("echo \"" + conf + "\" > " + BASE + "redsocks.conf\n" + cmd);
Utils.runRootCommand("echo \"" + conf + "\" > " + BASE + "redsocks.conf\n"
+ cmd);
} }
private boolean waitForProcess(final String name) { private boolean waitForProcess(final String name) {
...@@ -370,9 +363,7 @@ public class ShadowsocksService extends Service { ...@@ -370,9 +363,7 @@ public class ShadowsocksService extends Service {
return !t.isAlive(); return !t.isAlive();
} }
/** /** Called when the activity is first created. */
* Called when the activity is first created.
*/
public boolean handleConnection() { public boolean handleConnection() {
if (isHTTPProxy) { if (isHTTPProxy) {
...@@ -417,8 +408,7 @@ public class ShadowsocksService extends Service { ...@@ -417,8 +408,7 @@ public class ShadowsocksService extends Service {
notification.flags = Notification.FLAG_ONGOING_EVENT; notification.flags = Notification.FLAG_ONGOING_EVENT;
initSoundVibrateLights(notification); initSoundVibrateLights(notification);
// notification.defaults = Notification.DEFAULT_SOUND; // notification.defaults = Notification.DEFAULT_SOUND;
notification.setLatestEventInfo(this, getString(R.string.app_name), notification.setLatestEventInfo(this, getString(R.string.app_name), info, pendIntent);
info, pendIntent);
startForegroundCompat(1, notification); startForegroundCompat(1, notification);
} }
...@@ -427,8 +417,7 @@ public class ShadowsocksService extends Service { ...@@ -427,8 +417,7 @@ public class ShadowsocksService extends Service {
notification.tickerText = title; notification.tickerText = title;
notification.flags = flags; notification.flags = flags;
initSoundVibrateLights(notification); initSoundVibrateLights(notification);
notification.setLatestEventInfo(this, getString(R.string.app_name), notification.setLatestEventInfo(this, getString(R.string.app_name), info, pendIntent);
info, pendIntent);
notificationManager.notify(0, notification); notificationManager.notify(0, notification);
} }
...@@ -441,12 +430,10 @@ public class ShadowsocksService extends Service { ...@@ -441,12 +430,10 @@ public class ShadowsocksService extends Service {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
EasyTracker.getTracker().trackEvent("service", "start", EasyTracker.getTracker().trackEvent("service", "start", getVersionName(), 0L);
getVersionName(), 0L);
settings = PreferenceManager.getDefaultSharedPreferences(this); settings = PreferenceManager.getDefaultSharedPreferences(this);
notificationManager = (NotificationManager) this notificationManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
.getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Shadowsocks.class); Intent intent = new Intent(this, Shadowsocks.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
...@@ -454,37 +441,30 @@ public class ShadowsocksService extends Service { ...@@ -454,37 +441,30 @@ public class ShadowsocksService extends Service {
notification = new Notification(); notification = new Notification();
try { try {
mStartForeground = getClass().getMethod("startForeground", mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature);
mStartForegroundSignature); mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
// Running on an older platform. // Running on an older platform.
mStartForeground = mStopForeground = null; mStartForeground = mStopForeground = null;
} }
try { try {
mSetForeground = getClass().getMethod("setForeground", mSetForeground = getClass().getMethod("setForeground", mSetForegroundSignature);
mSetForegroundSignature);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
throw new IllegalStateException( throw new IllegalStateException(
"OS doesn't have Service.startForeground OR Service.setForeground!"); "OS doesn't have Service.startForeground OR Service.setForeground!");
} }
} }
/** /** Called when the activity is closed. */
* Called when the activity is closed.
*/
@Override @Override
public void onDestroy() { public void onDestroy() {
EasyTracker.getTracker().trackEvent("service", "stop", EasyTracker.getTracker().trackEvent("service", "stop", getVersionName(), 0L);
getVersionName(), 0L);
stopForegroundCompat(1); stopForegroundCompat(1);
notifyAlert(getString(R.string.forward_stop), notifyAlert(getString(R.string.forward_stop), getString(R.string.service_stopped),
getString(R.string.service_stopped),
Notification.FLAG_AUTO_CANCEL); Notification.FLAG_AUTO_CANCEL);
new Thread() { new Thread() {
...@@ -536,7 +516,6 @@ public class ShadowsocksService extends Service { ...@@ -536,7 +516,6 @@ public class ShadowsocksService extends Service {
public void onStart(Intent intent, int startId) { public void onStart(Intent intent, int startId) {
handleCommand(intent); handleCommand(intent);
} }
@Override @Override
...@@ -563,14 +542,20 @@ public class ShadowsocksService extends Service { ...@@ -563,14 +542,20 @@ public class ShadowsocksService extends Service {
init_sb.append(cmd_bypass.replace("0.0.0.0", "127.0.0.1")); init_sb.append(cmd_bypass.replace("0.0.0.0", "127.0.0.1"));
if (!isDNSProxy) { if (!isDNSProxy) {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + 53)); init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + 53));
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " init_sb.append(
+ getApplicationInfo().uid)); cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + getApplicationInfo().uid));
} }
if (hasRedirectSupport) { if (hasRedirectSupport) {
init_sb.append(Utils.getIptables()).append(" -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to ").append(DNS_PORT).append("\n"); init_sb.append(Utils.getIptables())
.append(" -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to ")
.append(DNS_PORT)
.append("\n");
} else { } else {
init_sb.append(Utils.getIptables()).append(" -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:").append(DNS_PORT).append("\n"); init_sb.append(Utils.getIptables())
.append(" -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:")
.append(DNS_PORT)
.append("\n");
} }
if (isGFWList) { if (isGFWList) {
...@@ -581,14 +566,12 @@ public class ShadowsocksService extends Service { ...@@ -581,14 +566,12 @@ public class ShadowsocksService extends Service {
} }
} }
if (isGlobalProxy || isBypassApps) { if (isGlobalProxy || isBypassApps) {
http_sb.append(hasRedirectSupport ? Utils.getIptables() http_sb.append(hasRedirectSupport ? Utils.getIptables() + CMD_IPTABLES_REDIRECT_ADD_SOCKS
+ CMD_IPTABLES_REDIRECT_ADD_SOCKS : Utils.getIptables() : Utils.getIptables() + CMD_IPTABLES_DNAT_ADD_SOCKS);
+ CMD_IPTABLES_DNAT_ADD_SOCKS);
} }
if (!isGlobalProxy) { if (!isGlobalProxy) {
// for proxy specified apps // for proxy specified apps
if (apps == null || apps.length <= 0) if (apps == null || apps.length <= 0) apps = AppManager.getProxyedApps(this);
apps = AppManager.getProxyedApps(this);
HashSet<Integer> uidSet = new HashSet<Integer>(); HashSet<Integer> uidSet = new HashSet<Integer>();
for (ProxyedApp app : apps) { for (ProxyedApp app : apps) {
...@@ -598,9 +581,8 @@ public class ShadowsocksService extends Service { ...@@ -598,9 +581,8 @@ public class ShadowsocksService extends Service {
} }
for (int uid : uidSet) { for (int uid : uidSet) {
if (!isBypassApps) { if (!isBypassApps) {
http_sb.append((hasRedirectSupport ? Utils.getIptables() http_sb.append((hasRedirectSupport ? Utils.getIptables() + CMD_IPTABLES_REDIRECT_ADD_SOCKS
+ CMD_IPTABLES_REDIRECT_ADD_SOCKS : Utils.getIptables() : Utils.getIptables() + CMD_IPTABLES_DNAT_ADD_SOCKS).replace("-t nat",
+ CMD_IPTABLES_DNAT_ADD_SOCKS).replace("-t nat",
"-t nat -m owner --uid-owner " + uid)); "-t nat -m owner --uid-owner " + uid));
} else { } else {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + uid)); init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + uid));
...@@ -616,7 +598,6 @@ public class ShadowsocksService extends Service { ...@@ -616,7 +598,6 @@ public class ShadowsocksService extends Service {
Utils.runRootCommand(redt_rules); Utils.runRootCommand(redt_rules);
return true; return true;
} }
/** /**
...@@ -664,5 +645,4 @@ public class ShadowsocksService extends Service { ...@@ -664,5 +645,4 @@ public class ShadowsocksService extends Service {
mSetForegroundArgs[0] = Boolean.FALSE; mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs); invokeMethod(mSetForeground, mSetForegroundArgs);
} }
} }
...@@ -45,14 +45,19 @@ import android.content.pm.PackageManager.NameNotFoundException; ...@@ -45,14 +45,19 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Environment; import android.os.Environment;
import android.util.Log; import android.util.Log;
import org.apache.http.conn.util.InetAddressUtils; import java.io.BufferedReader;
import java.io.File;
import java.io.*; import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.http.conn.util.InetAddressUtils;
public class Utils { public class Utils {
...@@ -76,9 +81,7 @@ public class Utils { ...@@ -76,9 +81,7 @@ public class Utils {
private static String iptables = null; private static String iptables = null;
private static String data_path = null; private static String data_path = null;
/** /** Get IP address from first non-localhost interface */
* Get IP address from first non-localhost interface
*/
public static boolean isIPv6Support() { public static boolean isIPv6Support() {
try { try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
...@@ -158,13 +161,11 @@ public class Utils { ...@@ -158,13 +161,11 @@ public class Utils {
boolean version = false; boolean version = false;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String command = iptables + " --version\n" + iptables String command = iptables + " --version\n" + iptables + " -L -t nat -n\n" + "exit\n";
+ " -L -t nat -n\n" + "exit\n";
int exitcode = runScript(command, sb, 10 * 1000, true); int exitcode = runScript(command, sb, 10 * 1000, true);
if (exitcode == TIME_OUT) if (exitcode == TIME_OUT) return;
return;
lines = sb.toString(); lines = sb.toString();
...@@ -177,27 +178,22 @@ public class Utils { ...@@ -177,27 +178,22 @@ public class Utils {
if (!compatible || !version) { if (!compatible || !version) {
iptables = ALTERNATIVE_IPTABLES; iptables = ALTERNATIVE_IPTABLES;
if (!new File(iptables).exists()) if (!new File(iptables).exists()) iptables = "iptables";
iptables = "iptables";
} }
} }
public static Drawable getAppIcon(Context c, int uid) { public static Drawable getAppIcon(Context c, int uid) {
PackageManager pm = c.getPackageManager(); PackageManager pm = c.getPackageManager();
Drawable appIcon = c.getResources().getDrawable( Drawable appIcon = c.getResources().getDrawable(android.R.drawable.sym_def_app_icon);
android.R.drawable.sym_def_app_icon);
String[] packages = pm.getPackagesForUid(uid); String[] packages = pm.getPackagesForUid(uid);
if (packages != null) { if (packages != null) {
if (packages.length == 1) { if (packages.length == 1) {
try { try {
ApplicationInfo appInfo = pm.getApplicationInfo( ApplicationInfo appInfo = pm.getApplicationInfo(packages[0], 0);
packages[0], 0);
appIcon = pm.getApplicationIcon(appInfo); appIcon = pm.getApplicationIcon(appInfo);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
Log.e(c.getPackageName(), Log.e(c.getPackageName(), "No package found matching with the uid " + uid);
"No package found matching with the uid " + uid);
} }
} }
} else { } else {
...@@ -211,10 +207,8 @@ public class Utils { ...@@ -211,10 +207,8 @@ public class Utils {
if (data_path == null) { if (data_path == null) {
if (Environment.MEDIA_MOUNTED.equals(Environment if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
.getExternalStorageState())) { data_path = Environment.getExternalStorageDirectory().getAbsolutePath();
data_path = Environment.getExternalStorageDirectory()
.getAbsolutePath();
} else { } else {
data_path = ctx.getFilesDir().getAbsolutePath(); data_path = ctx.getFilesDir().getAbsolutePath();
} }
...@@ -226,34 +220,30 @@ public class Utils { ...@@ -226,34 +220,30 @@ public class Utils {
} }
public static boolean getHasRedirectSupport() { public static boolean getHasRedirectSupport() {
if (hasRedirectSupport == -1) if (hasRedirectSupport == -1) initHasRedirectSupported();
initHasRedirectSupported();
return hasRedirectSupport == 1; return hasRedirectSupport == 1;
} }
public static String getIptables() { public static String getIptables() {
if (iptables == null) if (iptables == null) checkIptables();
checkIptables();
return iptables; return iptables;
} }
private static String getShell() { private static String getShell() {
if (shell == null) { if (shell == null) {
shell = DEFAULT_SHELL; shell = DEFAULT_SHELL;
if (!new File(shell).exists()) if (!new File(shell).exists()) shell = "sh";
shell = "sh";
} }
return shell; return shell;
} }
public static void initHasRedirectSupported() { public static void initHasRedirectSupported() {
if (!Utils.isRoot()) if (!Utils.isRoot()) return;
return;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String command = Utils.getIptables() String command =
+ " -t nat -A OUTPUT -p udp --dport 54 -j REDIRECT --to 8154"; Utils.getIptables() + " -t nat -A OUTPUT -p udp --dport 54 -j REDIRECT --to 8154";
int exitcode = runScript(command, sb, 10 * 1000, true); int exitcode = runScript(command, sb, 10 * 1000, true);
...@@ -264,8 +254,7 @@ public class Utils { ...@@ -264,8 +254,7 @@ public class Utils {
// flush the check command // flush the check command
Utils.runRootCommand(command.replace("-A", "-D")); Utils.runRootCommand(command.replace("-A", "-D"));
if (exitcode == TIME_OUT) if (exitcode == TIME_OUT) return;
return;
if (lines.contains("No chain/target/match")) { if (lines.contains("No chain/target/match")) {
hasRedirectSupport = 0; hasRedirectSupport = 0;
...@@ -273,19 +262,17 @@ public class Utils { ...@@ -273,19 +262,17 @@ public class Utils {
} }
public static boolean isInitialized() { public static boolean isInitialized() {
if (initialized) if (initialized) {
return true; return true;
else { } else {
initialized = true; initialized = true;
return false; return false;
} }
} }
public static boolean isRoot() { public static boolean isRoot() {
if (isRoot != -1) if (isRoot != -1) return isRoot == 1;
return isRoot == 1;
// switch between binaries // switch between binaries
if (new File(DEFAULT_ROOT).exists()) { if (new File(DEFAULT_ROOT).exists()) {
...@@ -319,7 +306,6 @@ public class Utils { ...@@ -319,7 +306,6 @@ public class Utils {
public static boolean runCommand(String command) { public static boolean runCommand(String command) {
return runCommand(command, 10 * 1000); return runCommand(command, 10 * 1000);
} }
public static boolean runCommand(String command, int timeout) { public static boolean runCommand(String command, int timeout) {
...@@ -334,7 +320,6 @@ public class Utils { ...@@ -334,7 +320,6 @@ public class Utils {
public static boolean runRootCommand(String command) { public static boolean runRootCommand(String command) {
return runRootCommand(command, 10 * 1000); return runRootCommand(command, 10 * 1000);
} }
public static boolean runRootCommand(String command, int timeout) { public static boolean runRootCommand(String command, int timeout) {
...@@ -351,8 +336,8 @@ public class Utils { ...@@ -351,8 +336,8 @@ public class Utils {
return true; return true;
} }
private synchronized static int runScript(String script, StringBuilder result, private synchronized static int runScript(String script, StringBuilder result, long timeout,
long timeout, boolean asroot) { boolean asroot) {
final ScriptRunner runner = new ScriptRunner(script, result, asroot); final ScriptRunner runner = new ScriptRunner(script, result, asroot);
runner.start(); runner.start();
try { try {
...@@ -373,9 +358,7 @@ public class Utils { ...@@ -373,9 +358,7 @@ public class Utils {
return runner.exitcode; return runner.exitcode;
} }
/** /** Internal thread used to execute scripts (as root or not). */
* Internal thread used to execute scripts (as root or not).
*/
private static final class ScriptRunner extends Thread { private static final class ScriptRunner extends Thread {
private final String scripts; private final String scripts;
private final StringBuilder result; private final StringBuilder result;
...@@ -404,8 +387,7 @@ public class Utils { ...@@ -404,8 +387,7 @@ public class Utils {
* @param result result output * @param result result output
* @param asroot if true, executes the script as root * @param asroot if true, executes the script as root
*/ */
public ScriptRunner(String script, StringBuilder result, public ScriptRunner(String script, StringBuilder result, boolean asroot) {
boolean asroot) {
this.scripts = script; this.scripts = script;
this.result = result; this.result = result;
this.asroot = asroot; this.asroot = asroot;
...@@ -416,8 +398,8 @@ public class Utils { ...@@ -416,8 +398,8 @@ public class Utils {
String arg0 = argList.get(0); String arg0 = argList.get(0);
String[] args = argList.toArray(new String[1]); String[] args = argList.toArray(new String[1]);
return Exec.createSubprocess(result != null ? 1 : 0, arg0, args, null, return Exec.createSubprocess(result != null ? 1 : 0, arg0, args, null, scripts + "\nexit\n",
scripts + "\nexit\n", processId); processId);
} }
private ArrayList<String> parse(String cmd) { private ArrayList<String> parse(String cmd) {
...@@ -497,11 +479,9 @@ public class Utils { ...@@ -497,11 +479,9 @@ public class Utils {
read = stdout.read(buf); read = stdout.read(buf);
result.append(new String(buf, 0, read)); result.append(new String(buf, 0, read));
} }
} catch (Exception ex) { } catch (Exception ex) {
Log.e(TAG, "Cannot execute command", ex); Log.e(TAG, "Cannot execute command", ex);
if (result != null) if (result != null) result.append("\n").append(ex);
result.append("\n").append(ex);
} finally { } finally {
if (pipe != null) { if (pipe != null) {
Exec.close(pipe); Exec.close(pipe);
......
...@@ -3,7 +3,6 @@ package com.github.shadowsocks.preferences; ...@@ -3,7 +3,6 @@ package com.github.shadowsocks.preferences;
import android.content.Context; import android.content.Context;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.util.AttributeSet; import android.util.AttributeSet;
import com.github.shadowsocks.R;
public class SummaryEditTextPreference extends EditTextPreference { public class SummaryEditTextPreference extends EditTextPreference {
...@@ -24,15 +23,11 @@ public class SummaryEditTextPreference extends EditTextPreference { ...@@ -24,15 +23,11 @@ public class SummaryEditTextPreference extends EditTextPreference {
} }
@Override @Override
public void onDialogClosed(boolean positiveResult) { public void setSummary(CharSequence summary) {
super.onDialogClosed(positiveResult); if (summary.toString().isEmpty()) {
if (positiveResult) { super.setSummary(mDefaultSummary);
String value = getEditText().getText().toString();
if (value.isEmpty()) {
setSummary(mDefaultSummary);
} else { } else {
setSummary(value); super.setSummary(summary);
}
} }
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment