Skip to content

Commit 6a7869a

Browse files
authored
Merge pull request dawei101#30 from so898/Pre-App
Pre-App Support 感谢 👍
2 parents 4b1e217 + b46a9fe commit 6a7869a

File tree

15 files changed

+553
-25
lines changed

15 files changed

+553
-25
lines changed

app/build.gradle

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ buildscript {
1111
}
1212

1313
android {
14-
compileSdkVersion 19
14+
compileSdkVersion 25
1515
buildToolsVersion "23.0.1"
16+
useLibrary 'org.apache.http.legacy'
1617

1718
defaultConfig {
1819
applicationId "com.vm.shadowsocks"
19-
minSdkVersion 14
20-
targetSdkVersion 19
20+
minSdkVersion 15
21+
targetSdkVersion 25
2122
versionCode 1
2223
versionName "1.1"
2324
}
@@ -44,6 +45,8 @@ dependencies {
4445
compile 'com.embarkmobile:zxing-android-integration:2.0.0@aar'
4546
compile 'com.google.zxing:core:3.0.1'
4647
compile 'org.bouncycastle:bcprov-jdk15on:1.52'
48+
compile 'com.futuremind.recyclerfastscroll:fastscroll:0.2.5'
49+
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
4750
compile('com.googlecode.json-simple:json-simple:1.1.1') {
4851
exclude group: 'junit', module: 'junit'
4952
exclude group: 'org.hamcrest', module: 'hamcrest-core'

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
</intent-filter>
2323
</activity>
2424

25+
<activity
26+
android:name="com.vm.shadowsocks.ui.AppManager"
27+
android:label="@string/proxied_apps"
28+
android:excludeFromRecents="true"
29+
android:launchMode="singleTask"/>
30+
2531
<service
2632
android:name="com.vm.shadowsocks.core.LocalVpnService"
2733
android:permission="android.permission.BIND_VPN_SERVICE">
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.vm.shadowsocks.core;
2+
3+
import android.graphics.drawable.Drawable;
4+
5+
public class AppInfo {
6+
private Drawable appIcon;
7+
private String appLabel;
8+
private String pkgName;
9+
10+
public AppInfo() {
11+
}
12+
13+
public Drawable getAppIcon() {
14+
return this.appIcon;
15+
}
16+
17+
public String getAppLabel() {
18+
return this.appLabel;
19+
}
20+
21+
public String getPkgName() {
22+
return this.pkgName;
23+
}
24+
25+
public void setAppIcon(Drawable var1) {
26+
this.appIcon = var1;
27+
}
28+
29+
public void setAppLabel(String var1) {
30+
this.appLabel = var1;
31+
}
32+
33+
public void setPkgName(String var1) {
34+
this.pkgName = var1;
35+
}
36+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.vm.shadowsocks.core;
2+
3+
import android.content.Context;
4+
import android.content.SharedPreferences;
5+
import android.graphics.drawable.Drawable;
6+
import android.os.Build;
7+
8+
import org.json.JSONArray;
9+
import org.json.JSONObject;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
import static android.content.Context.MODE_PRIVATE;
15+
16+
public class AppProxyManager {
17+
public static boolean isLollipopOrAbove = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
18+
19+
public static AppProxyManager Instance;
20+
private static final String PROXY_APPS = "PROXY_APPS";
21+
private Context mContext;
22+
23+
public List<AppInfo> mlistAppInfo = new ArrayList<AppInfo>();
24+
public List<AppInfo> proxyAppInfo = new ArrayList<AppInfo>();
25+
26+
public AppProxyManager(Context context){
27+
this.mContext = context;
28+
Instance = this;
29+
readProxyAppsList();
30+
}
31+
32+
public void removeProxyApp(String pkg){
33+
for (AppInfo app : this.proxyAppInfo) {
34+
if (app.getPkgName().equals(pkg)){
35+
proxyAppInfo.remove(app);
36+
break;
37+
}
38+
}
39+
writeProxyAppsList();
40+
}
41+
42+
public void addProxyApp(String pkg){
43+
for (AppInfo app : this.mlistAppInfo) {
44+
if (app.getPkgName().equals(pkg)){
45+
proxyAppInfo.add(app);
46+
break;
47+
}
48+
}
49+
writeProxyAppsList();
50+
}
51+
52+
public boolean isAppProxy(String pkg){
53+
for (AppInfo app : this.proxyAppInfo) {
54+
if (app.getPkgName().equals(pkg)){
55+
return true;
56+
}
57+
}
58+
return false;
59+
}
60+
61+
private void readProxyAppsList() {
62+
SharedPreferences preferences = mContext.getSharedPreferences("shadowsocksProxyUrl", MODE_PRIVATE);
63+
String tmpString = preferences.getString(PROXY_APPS, "");
64+
try {
65+
if (proxyAppInfo != null){
66+
proxyAppInfo.clear();
67+
}
68+
if (tmpString.isEmpty()){
69+
return;
70+
}
71+
JSONArray jsonArray = new JSONArray(tmpString);
72+
for (int i = 0; i < jsonArray.length() ; i++){
73+
JSONObject object = jsonArray.getJSONObject(i);
74+
AppInfo appInfo = new AppInfo();
75+
appInfo.setAppLabel(object.getString("label"));
76+
appInfo.setPkgName(object.getString("pkg"));
77+
proxyAppInfo.add(appInfo);
78+
}
79+
} catch (Exception e){
80+
e.printStackTrace();
81+
}
82+
}
83+
84+
private void writeProxyAppsList() {
85+
SharedPreferences preferences = mContext.getSharedPreferences("shadowsocksProxyUrl", MODE_PRIVATE);
86+
try {
87+
JSONArray jsonArray = new JSONArray();
88+
for (int i = 0; i < proxyAppInfo.size() ; i++){
89+
JSONObject object = new JSONObject();
90+
AppInfo appInfo = proxyAppInfo.get(i);
91+
object.put("label", appInfo.getAppLabel());
92+
object.put("pkg", appInfo.getPkgName());
93+
jsonArray.put(object);
94+
}
95+
SharedPreferences.Editor editor = preferences.edit();
96+
editor.putString(PROXY_APPS, jsonArray.toString());
97+
editor.apply();
98+
} catch (Exception e){
99+
e.printStackTrace();
100+
}
101+
}
102+
}

app/src/main/java/com/vm/shadowsocks/core/LocalVpnService.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ String getAppInstallID() {
140140
appInstallID = UUID.randomUUID().toString();
141141
Editor editor = preferences.edit();
142142
editor.putString("AppInstallID", appInstallID);
143-
editor.commit();
143+
editor.apply();
144144
}
145145
return appInstallID;
146146
}
@@ -379,12 +379,34 @@ private ParcelFileDescriptor establishVPN() throws Exception {
379379
String value = (String) method.invoke(null, name);
380380
if (value != null && !"".equals(value) && !servers.contains(value)) {
381381
servers.add(value);
382-
builder.addRoute(value, 32);
382+
if (value.replaceAll("\\d", "").length() == 3){//防止IPv6地址导致问题
383+
builder.addRoute(value, 32);
384+
} else {
385+
builder.addRoute(value, 128);
386+
}
383387
if (ProxyConfig.IS_DEBUG)
384388
System.out.printf("%s=%s\n", name, value);
385389
}
386390
}
387391

392+
if (AppProxyManager.isLollipopOrAbove){
393+
if (AppProxyManager.Instance.proxyAppInfo.size() == 0){
394+
writeLog("Proxy All Apps");
395+
}
396+
for (AppInfo app : AppProxyManager.Instance.proxyAppInfo){
397+
builder.addAllowedApplication("com.vm.shadowsocks");//需要把自己加入代理,不然会无法进行网络连接
398+
try{
399+
builder.addAllowedApplication(app.getPkgName());
400+
writeLog("Proxy App: " + app.getAppLabel());
401+
} catch (Exception e){
402+
e.printStackTrace();
403+
writeLog("Proxy App Fail: " + app.getAppLabel());
404+
}
405+
}
406+
} else {
407+
writeLog("No Pre-App proxy, due to low Android version.");
408+
}
409+
388410
Intent intent = new Intent(this, MainActivity.class);
389411
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
390412
builder.setConfigureIntent(pendingIntent);

0 commit comments

Comments
 (0)