Merge branch 'master' into api-31

# Conflicts:
#	app/build.gradle
#	build.gradle
This commit is contained in:
PeratX 2022-05-23 11:49:37 +08:00
commit 010096a4e3
53 changed files with 787 additions and 592 deletions

View File

@ -7,8 +7,8 @@ android:
components: components:
- tools - tools
- platform-tools - platform-tools
- build-tools-28.0.3 - build-tools-29.0.2
- android-28 - android-29
- extra-android-support - extra-android-support
- extra-google-m2repository - extra-google-m2repository
- extra-android-m2repository - extra-android-m2repository

View File

@ -1,6 +1,6 @@
# iTXTech Daedalus # iTXTech Daedalus
[![Donate](https://img.shields.io/badge/alipay-donate-yellow.svg)](https://qr.alipay.com/a6x07022gffiehykicipv1a) [![Donate](https://img.shields.io/badge/alipay-donate-yellow.svg)](https://qr.alipay.com/FKX04751EZDP0SQ0BOT137)
[![Build Status](https://travis-ci.org/iTXTech/Daedalus.svg?branch=master)](https://travis-ci.org/iTXTech/Daedalus) [![Build Status](https://travis-ci.org/iTXTech/Daedalus.svg?branch=master)](https://travis-ci.org/iTXTech/Daedalus)
[![Jenkins](https://img.shields.io/jenkins/s/http/dev.itxtech.org:10298/job/Daedalus.svg)](http://dev.itxtech.org:10298/job/Daedalus/) [![Jenkins](https://img.shields.io/jenkins/s/http/dev.itxtech.org:10298/job/Daedalus.svg)](http://dev.itxtech.org:10298/job/Daedalus/)
@ -66,14 +66,13 @@ __Users must comply with local laws and regulations.__<br>
* __[ClearEditText](https://github.com/MrFuFuFu/ClearEditText)__ by *[Yuan Fu](https://github.com/MrFuFuFu)* - [APL 2.0](https://github.com/MrFuFuFu/ClearEditText) * __[ClearEditText](https://github.com/MrFuFuFu/ClearEditText)__ by *[Yuan Fu](https://github.com/MrFuFuFu)* - [APL 2.0](https://github.com/MrFuFuFu/ClearEditText)
* __[DNS66](https://github.com/julian-klode/dns66)__ by *[Julian Andres Klode](https://github.com/julian-klode)* - [GPLv3](https://github.com/julian-klode/dns66/blob/master/COPYING) * __[DNS66](https://github.com/julian-klode/dns66)__ by *[Julian Andres Klode](https://github.com/julian-klode)* - [GPLv3](https://github.com/julian-klode/dns66/blob/master/COPYING)
* __[Pcap4J](https://github.com/kaitoy/pcap4j)__ by *[Kaito Yamada](https://github.com/kaitoy)* - [MIT](https://github.com/kaitoy/pcap4j) * __[Pcap4J](https://github.com/kaitoy/pcap4j)__ by *[Kaito Yamada](https://github.com/kaitoy)* - [MIT](https://github.com/kaitoy/pcap4j)
* __[MiniDNS](https://github.com/rtreffer/minidns)__ by *[Rene Treffer](https://github.com/rtreffer)* - [LGPLv2.1](https://github.com/rtreffer/minidns/blob/master/LICENCE_LGPL2.1) * __[MiniDNS](https://github.com/MiniDNS/minidns)__ by *[MiniDNS](https://github.com/MiniDNS)* - [APL 2.0](https://github.com/MiniDNS/minidns/blob/master/LICENCE_APACHE)
* __[Gson](https://github.com/google/gson)__ by *[Google](https://github.com/google)* - [APL 2.0](https://github.com/google/gson/blob/master/LICENSE) * __[Gson](https://github.com/google/gson)__ by *[Google](https://github.com/google)* - [APL 2.0](https://github.com/google/gson/blob/master/LICENSE)
* __[Shadowsocks](https://github.com/shadowsocks/shadowsocks-android)__ by *[Shadowsocks](https://github.com/shadowsocks)* - [GPLv3](https://github.com/shadowsocks/shadowsocks-android/blob/master/LICENSE) * __[Shadowsocks](https://github.com/shadowsocks/shadowsocks-android)__ by *[Shadowsocks](https://github.com/shadowsocks)* - [GPLv3](https://github.com/shadowsocks/shadowsocks-android/blob/master/LICENSE)
## Credits ## Credits
* __[JetBrains](https://www.jetbrains.com/)__ - For providing free license for [IntelliJ IDEA](https://www.jetbrains.com/idea/) * __[JetBrains](https://www.jetbrains.com/)__ - For providing free license for [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* __[ShenniaoTech](https://www.sncidc.com/)__ - For supporting us with love
## License ## License

View File

@ -58,6 +58,7 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.7.0-alpha01' implementation 'com.google.android.material:material:1.7.0-alpha01'
implementation 'androidx.recyclerview:recyclerview:1.3.0-alpha02' implementation 'androidx.recyclerview:recyclerview:1.3.0-alpha02'
implementation 'androidx.preference:preference:1.1.0'
//DNS //DNS
implementation 'org.pcap4j:pcap4j-core:1.7.6' implementation 'org.pcap4j:pcap4j-core:1.7.6'
implementation 'org.pcap4j:pcap4j-packetfactory-static:1.7.6' implementation 'org.pcap4j:pcap4j-packetfactory-static:1.7.6'

View File

@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/> android:maxSdkVersion="18"/>

View File

@ -10,20 +10,20 @@ import android.graphics.drawable.Icon;
import android.net.Uri; import android.net.Uri;
import android.net.VpnService; import android.net.VpnService;
import android.os.Build; import android.os.Build;
import android.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import android.util.Log;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import org.itxtech.daedalus.activity.MainActivity; import org.itxtech.daedalus.activity.MainActivity;
import org.itxtech.daedalus.server.AbstractDnsServer;
import org.itxtech.daedalus.server.DnsServer;
import org.itxtech.daedalus.server.DnsServerHelper;
import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.service.DaedalusVpnService;
import org.itxtech.daedalus.util.Configurations; import org.itxtech.daedalus.util.Configurations;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.Rule; import org.itxtech.daedalus.util.Rule;
import org.itxtech.daedalus.util.RuleResolver; import org.itxtech.daedalus.util.RuleResolver;
import org.itxtech.daedalus.util.server.DNSServer;
import org.itxtech.daedalus.util.server.DNSServerHelper;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -45,16 +45,16 @@ public class Daedalus extends Application {
private static final String SHORTCUT_ID_ACTIVATE = "shortcut_activate"; private static final String SHORTCUT_ID_ACTIVATE = "shortcut_activate";
public static final List<DNSServer> DNS_SERVERS = new ArrayList<DNSServer>() {{ public static final List<DnsServer> DNS_SERVERS = new ArrayList<DnsServer>() {{
add(new DNSServer("101.101.101.101", R.string.server_twnic_primary)); add(new DnsServer("101.101.101.101", R.string.server_twnic_primary));
add(new DNSServer("101.102.103.104", R.string.server_twnic_secondary)); add(new DnsServer("101.102.103.104", R.string.server_twnic_secondary));
add(new DNSServer("dns.rubyfish.cn/dns-query", R.string.server_rubyfish)); add(new DnsServer("rubyfish.cn/dns-query", R.string.server_rubyfish));
add(new DNSServer("cloudflare-dns.com/dns-query", R.string.server_cloudflare)); add(new DnsServer("cloudflare-dns.com/dns-query", R.string.server_cloudflare));
add(new DNSServer("dns.google/dns-query", R.string.server_google_ietf)); add(new DnsServer("dns.google/dns-query", R.string.server_google_ietf));
add(new DNSServer("dns.google/resolve", R.string.server_google_json)); add(new DnsServer("dns.google/resolve", R.string.server_google_json));
}}; }};
public static final List<Rule> RULES = new ArrayList<Rule>() {{ public static final ArrayList<Rule> RULES = new ArrayList<Rule>() {{
add(new Rule("googlehosts/hosts", "googlehosts.hosts", Rule.TYPE_HOSTS, add(new Rule("googlehosts/hosts", "googlehosts.hosts", Rule.TYPE_HOSTS,
"https://raw.githubusercontent.com/googlehosts/hosts/master/hosts-files/hosts", false)); "https://raw.githubusercontent.com/googlehosts/hosts/master/hosts-files/hosts", false));
add(new Rule("vokins/yhosts", "vokins.hosts", Rule.TYPE_HOSTS, add(new Rule("vokins/yhosts", "vokins.hosts", Rule.TYPE_HOSTS,
@ -66,7 +66,7 @@ public class Daedalus extends Application {
"https://raw.githubusercontent.com/vokins/yhosts/master/dnsmasq/union.conf", false)); "https://raw.githubusercontent.com/vokins/yhosts/master/dnsmasq/union.conf", false));
}}; }};
public static final String[] DEFAULT_TEST_DOMAINS = new String[]{ public static final String[] DEFAULT_TEST_DOMAINS = {
"google.com", "google.com",
"twitter.com", "twitter.com",
"youtube.com", "youtube.com",
@ -75,12 +75,11 @@ public class Daedalus extends Application {
}; };
public static Configurations configurations; public static Configurations configurations;
public static String rulePath;
public static String logPath;
private static String configPath;
public static String rulePath = null; private static Daedalus instance;
public static String logPath = null;
private static String configPath = null;
private static Daedalus instance = null;
private SharedPreferences prefs; private SharedPreferences prefs;
private Thread mResolver; private Thread mResolver;
@ -89,12 +88,9 @@ public class Daedalus extends Application {
super.onCreate(); super.onCreate();
instance = this; instance = this;
Logger.init(); Logger.init();
mResolver = new Thread(new RuleResolver()); mResolver = new Thread(new RuleResolver());
mResolver.start(); mResolver.start();
initData(); initData();
} }
@ -135,30 +131,30 @@ public class Daedalus extends Application {
} }
public static void initRuleResolver() { public static void initRuleResolver() {
ArrayList<String> pendingLoad = new ArrayList<>(); ArrayList<String> pendingLoad = new ArrayList<>();
ArrayList<Rule> usingRules = configurations.getUsingRules(); ArrayList<Rule> usingRules = configurations.getUsingRules();
if (usingRules != null && usingRules.size() > 0) { if (usingRules != null && usingRules.size() > 0) {
for (Rule rule : usingRules) { for (Rule rule : usingRules) {
if (rule.isUsing()) { if (rule.isUsing()) {
pendingLoad.add(rulePath + rule.getFileName()); pendingLoad.add(rulePath + rule.getFileName());
}
} }
if (pendingLoad.size() > 0) { }
String[] arr = new String[pendingLoad.size()]; if (pendingLoad.size() > 0) {
pendingLoad.toArray(arr); String[] arr = new String[pendingLoad.size()];
switch (usingRules.get(0).getType()) { pendingLoad.toArray(arr);
case Rule.TYPE_HOSTS: switch (usingRules.get(0).getType()) {
RuleResolver.startLoadHosts(arr); case Rule.TYPE_HOSTS:
break; RuleResolver.startLoadHosts(arr);
case Rule.TYPE_DNAMASQ: break;
RuleResolver.startLoadDnsmasq(arr); case Rule.TYPE_DNAMASQ:
break; RuleResolver.startLoadDnsmasq(arr);
} break;
} else {
RuleResolver.clear();
} }
} else { } else {
RuleResolver.clear(); RuleResolver.clear();
}
} else {
RuleResolver.clear();
} }
} }
@ -178,7 +174,6 @@ public class Daedalus extends Application {
@Override @Override
public void onTerminate() { public void onTerminate() {
Log.d("Daedalus", "onTerminate");
super.onTerminate(); super.onTerminate();
instance = null; instance = null;
@ -199,23 +194,38 @@ public class Daedalus extends Application {
deactivateService(instance); deactivateService(instance);
return false; return false;
} else { } else {
activateService(instance); prepareAndActivateService(instance);
return true; return true;
} }
} }
public static boolean activateService(Context context) { public static boolean prepareAndActivateService(Context context) {
Intent intent = VpnService.prepare(context); Intent intent = VpnService.prepare(context);
if (intent != null) { if (intent != null) {
return false; return false;
} else { } else {
DaedalusVpnService.primaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getPrimary()); activateService(context);
DaedalusVpnService.secondaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getSecondary());
context.startService(Daedalus.getServiceIntent(context).setAction(DaedalusVpnService.ACTION_ACTIVATE));
return true; return true;
} }
} }
public static void activateService(Context context) {
activateService(context, false);
}
public static void activateService(Context context, boolean forceForeground) {
DaedalusVpnService.primaryServer = (AbstractDnsServer) DnsServerHelper.getServerById(DnsServerHelper.getPrimary()).clone();
DaedalusVpnService.secondaryServer = (AbstractDnsServer) DnsServerHelper.getServerById(DnsServerHelper.getSecondary()).clone();
if ((getInstance().prefs.getBoolean("settings_foreground", false) || forceForeground)
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
Logger.info("Starting foreground service");
context.startForegroundService(Daedalus.getServiceIntent(context).setAction(DaedalusVpnService.ACTION_ACTIVATE));
} else {
Logger.info("Starting background service");
context.startService(Daedalus.getServiceIntent(context).setAction(DaedalusVpnService.ACTION_ACTIVATE));
}
}
public static void deactivateService(Context context) { public static void deactivateService(Context context) {
context.startService(getServiceIntent(context).setAction(DaedalusVpnService.ACTION_DEACTIVATE)); context.startService(getServiceIntent(context).setAction(DaedalusVpnService.ACTION_DEACTIVATE));
context.stopService(getServiceIntent(context)); context.stopService(getServiceIntent(context));
@ -223,7 +233,7 @@ public class Daedalus extends Application {
public static void updateShortcut(Context context) { public static void updateShortcut(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
Log.d("Daedalus", "Updating shortcut"); Logger.info("Updating shortcut");
boolean activate = DaedalusVpnService.isActivated(); boolean activate = DaedalusVpnService.isActivated();
String notice = activate ? context.getString(R.string.button_text_deactivate) : context.getString(R.string.button_text_activate); String notice = activate ? context.getString(R.string.button_text_deactivate) : context.getString(R.string.button_text_activate);
ShortcutInfo info = new ShortcutInfo.Builder(context, Daedalus.SHORTCUT_ID_ACTIVATE) ShortcutInfo info = new ShortcutInfo.Builder(context, Daedalus.SHORTCUT_ID_ACTIVATE)
@ -239,7 +249,7 @@ public class Daedalus extends Application {
} }
public static void donate() { public static void donate() {
openUri("https://qr.alipay.com/a6x07022gffiehykicipv1a"); openUri("https://qr.alipay.com/FKX04751EZDP0SQ0BOT137");
} }
public static void openUri(String uri) { public static void openUri(String uri) {

View File

@ -40,7 +40,6 @@ import java.util.Objects;
* (at your option) any later version. * (at your option) any later version.
*/ */
public class AppFilterActivity extends AppCompatActivity { public class AppFilterActivity extends AppCompatActivity {
private RecyclerViewAdapter adapter; private RecyclerViewAdapter adapter;
@Override @Override
@ -78,7 +77,7 @@ public class AppFilterActivity extends AppCompatActivity {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
private class AppObject { private static class AppObject {
private String appName; private String appName;
private String appPackageName; private String appPackageName;
private Drawable appIcon; private Drawable appIcon;
@ -111,13 +110,11 @@ public class AppFilterActivity extends AppCompatActivity {
void updateList(ArrayList<AppObject> appObjects) { void updateList(ArrayList<AppObject> appObjects) {
appList = appObjects; appList = appObjects;
for (int i = 0; i < appObjects.size(); i++) { for (int i = 0; i < appObjects.size(); i++) {
if (Daedalus.configurations.getAppObjects().contains(appObjects.get(i).appPackageName)) { if (Daedalus.configurations.getAppObjects().contains(appObjects.get(i).appPackageName)) {
checkStatus.put(i, true); checkStatus.put(i, true);
} }
} }
runOnUiThread(this::notifyDataSetChanged); runOnUiThread(this::notifyDataSetChanged);
} }
@ -158,7 +155,7 @@ public class AppFilterActivity extends AppCompatActivity {
} }
} }
private class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private static class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView appIcon; private ImageView appIcon;
private TextView appName; private TextView appName;
private CheckBox appCheck; private CheckBox appCheck;
@ -172,7 +169,6 @@ public class AppFilterActivity extends AppCompatActivity {
itemView.setOnClickListener(this); itemView.setOnClickListener(this);
} }
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (appCheck.isChecked()) { if (appCheck.isChecked()) {

View File

@ -1,7 +1,5 @@
package org.itxtech.daedalus.activity; package org.itxtech.daedalus.activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
@ -9,10 +7,12 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.fragment.ConfigFragment; import org.itxtech.daedalus.fragment.ConfigFragment;
import org.itxtech.daedalus.fragment.DNSServerConfigFragment; import org.itxtech.daedalus.fragment.DnsServerConfigFragment;
import org.itxtech.daedalus.fragment.RuleConfigFragment; import org.itxtech.daedalus.fragment.RuleConfigFragment;
/** /**
@ -44,14 +44,12 @@ public class ConfigActivity extends AppCompatActivity {
ConfigFragment fragment; ConfigFragment fragment;
switch (getIntent().getIntExtra(LAUNCH_ACTION_FRAGMENT, LAUNCH_FRAGMENT_DNS_SERVER)) { switch (getIntent().getIntExtra(LAUNCH_ACTION_FRAGMENT, LAUNCH_FRAGMENT_DNS_SERVER)) {
case LAUNCH_FRAGMENT_DNS_SERVER:
fragment = new DNSServerConfigFragment();
break;
case LAUNCH_FRAGMENT_RULE: case LAUNCH_FRAGMENT_RULE:
fragment = new RuleConfigFragment(); fragment = new RuleConfigFragment();
break; break;
case LAUNCH_FRAGMENT_DNS_SERVER:
default://should never reach this default://should never reach this
fragment = new DNSServerConfigFragment(); fragment = new DnsServerConfigFragment();
break; break;
} }
@ -64,7 +62,7 @@ public class ConfigActivity extends AppCompatActivity {
toolbar.setOnMenuItemClickListener(fragment); toolbar.setOnMenuItemClickListener(fragment);
toolbar.inflateMenu(R.menu.custom_config); toolbar.inflateMenu(R.menu.custom_config);
FragmentManager manager = getFragmentManager(); FragmentManager manager = getSupportFragmentManager();
fragment.setIntent(getIntent()); fragment.setIntent(getIntent());
FragmentTransaction fragmentTransaction = manager.beginTransaction(); FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.replace(R.id.id_config, fragment); fragmentTransaction.replace(R.id.id_config, fragment);

View File

@ -1,9 +1,7 @@
package org.itxtech.daedalus.activity; package org.itxtech.daedalus.activity;
import android.app.Activity; import android.app.Activity;
import android.app.FragmentManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.VpnService; import android.net.VpnService;
import android.os.Bundle; import android.os.Bundle;
@ -26,7 +24,6 @@ import org.itxtech.daedalus.R;
import org.itxtech.daedalus.fragment.*; import org.itxtech.daedalus.fragment.*;
import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.service.DaedalusVpnService;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.server.DNSServerHelper;
/** /**
* Daedalus Project * Daedalus Project
@ -100,8 +97,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
if (currentFragment == null || fragmentClass != currentFragment.getClass()) { if (currentFragment == null || fragmentClass != currentFragment.getClass()) {
try { try {
ToolbarFragment fragment = (ToolbarFragment) fragmentClass.newInstance(); ToolbarFragment fragment = (ToolbarFragment) fragmentClass.newInstance();
FragmentManager fm = getFragmentManager(); getSupportFragmentManager().beginTransaction().replace(R.id.id_content, fragment).commit();
fm.beginTransaction().replace(R.id.id_content, fragment).commit();
currentFragment = fragment; currentFragment = fragment;
} catch (Exception e) { } catch (Exception e) {
Logger.logException(e); Logger.logException(e);
@ -153,22 +149,14 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle("觉得还不错?") .setTitle("觉得还不错?")
.setMessage("您的支持是我动力来源!\n请考虑为我买杯咖啡醒醒脑甚至其他…… ;)") .setMessage("您的支持是我动力来源!\n请考虑为我买杯咖啡醒醒脑甚至其他…… ;)")
.setPositiveButton("为我买杯咖啡", new DialogInterface.OnClickListener() { .setPositiveButton("为我买杯咖啡", (dialog, which) -> {
@Override Daedalus.donate();
public void onClick(DialogInterface dialog, int which) { new AlertDialog.Builder(MainActivity.this)
Daedalus.donate(); .setMessage("感谢您的支持!;)\n我会再接再厉")
new AlertDialog.Builder(MainActivity.this) .setPositiveButton("确认", null)
.setMessage("感谢您的支持!;)\n我会再接再厉") .show();
.setPositiveButton("确认", null)
.show();
}
})
.setNeutralButton("不再显示", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Daedalus.configurations.setActivateCounter(-1);
}
}) })
.setNeutralButton("不再显示", (dialog, which) -> Daedalus.configurations.setActivateCounter(-1))
.setNegativeButton("取消", null) .setNegativeButton("取消", null)
.show(); .show();
} }
@ -177,12 +165,11 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
public void onActivityResult(int request, int result, Intent data) { public void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data); super.onActivityResult(request, result, data);
if (result == Activity.RESULT_OK) { if (result == Activity.RESULT_OK) {
DaedalusVpnService.primaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getPrimary()); Daedalus.activateService(Daedalus.getInstance());
DaedalusVpnService.secondaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getSecondary());
Daedalus.getInstance().startService(Daedalus.getServiceIntent(getApplicationContext()).setAction(DaedalusVpnService.ACTION_ACTIVATE));
updateMainButton(R.string.button_text_deactivate); updateMainButton(R.string.button_text_deactivate);
Daedalus.updateShortcut(getApplicationContext()); Daedalus.updateShortcut(getApplicationContext());
} }
super.onActivityResult(request, result, data);
} }
private void updateMainButton(int id) { private void updateMainButton(int id) {
@ -194,7 +181,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void updateUserInterface(Intent intent) { private void updateUserInterface(Intent intent) {
int launchAction = intent.getIntExtra(LAUNCH_ACTION, LAUNCH_ACTION_NONE); int launchAction = intent.getIntExtra(LAUNCH_ACTION, LAUNCH_ACTION_NONE);
Log.d(TAG, "Updating user interface with Launch Action " + String.valueOf(launchAction)); Log.d(TAG, "Updating user interface with Launch Action " + launchAction);
if (launchAction == LAUNCH_ACTION_ACTIVATE) { if (launchAction == LAUNCH_ACTION_ACTIVATE) {
this.activateService(); this.activateService();
} else if (launchAction == LAUNCH_ACTION_DEACTIVATE) { } else if (launchAction == LAUNCH_ACTION_DEACTIVATE) {
@ -227,10 +214,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
switchFragment(AboutFragment.class); switchFragment(AboutFragment.class);
break; break;
case FRAGMENT_DNS_SERVERS: case FRAGMENT_DNS_SERVERS:
switchFragment(DNSServersFragment.class); switchFragment(DnsServersFragment.class);
break; break;
case FRAGMENT_DNS_TEST: case FRAGMENT_DNS_TEST:
switchFragment(DNSTestFragment.class); switchFragment(DnsTestFragment.class);
break; break;
case FRAGMENT_HOME: case FRAGMENT_HOME:
switchFragment(HomeFragment.class); switchFragment(HomeFragment.class);
@ -252,7 +239,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
@Override @Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) { public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId(); int id = item.getItemId();
switch (id) { switch (id) {
@ -260,10 +246,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
switchFragment(AboutFragment.class); switchFragment(AboutFragment.class);
break; break;
case R.id.nav_dns_server: case R.id.nav_dns_server:
switchFragment(DNSServersFragment.class); switchFragment(DnsServersFragment.class);
break; break;
case R.id.nav_dns_test: case R.id.nav_dns_test:
switchFragment(DNSTestFragment.class); switchFragment(DnsTestFragment.class);
break; break;
case R.id.nav_github: case R.id.nav_github:
Daedalus.openUri("https://github.com/iTXTech/Daedalus"); Daedalus.openUri("https://github.com/iTXTech/Daedalus");

View File

@ -13,6 +13,7 @@ import android.webkit.WebViewClient;
import org.itxtech.daedalus.BuildConfig; import org.itxtech.daedalus.BuildConfig;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.util.Logger;
import java.util.Locale; import java.util.Locale;
@ -64,7 +65,7 @@ public class AboutFragment extends ToolbarFragment {
mWebView.loadUrl("javascript:changeColor('"+(Daedalus.isDarkTheme() ? "#FFFFFF" : "#000000")+"')"); mWebView.loadUrl("javascript:changeColor('"+(Daedalus.isDarkTheme() ? "#FFFFFF" : "#000000")+"')");
mWebView.loadUrl("javascript:changeVersionInfo('" + Daedalus.getInstance().getPackageManager().getPackageInfo(Daedalus.getInstance().getPackageName(), 0).versionName + "', '" + BuildConfig.BUILD_TIME + "', '" + BuildConfig.GIT_COMMIT + "')"); mWebView.loadUrl("javascript:changeVersionInfo('" + Daedalus.getInstance().getPackageManager().getPackageInfo(Daedalus.getInstance().getPackageName(), 0).versionName + "', '" + BuildConfig.BUILD_TIME + "', '" + BuildConfig.GIT_COMMIT + "')");
} catch (Exception e) { } catch (Exception e) {
Log.e("DAboutActivity", e.toString()); Logger.logException(e);
} }
} }
}); });
@ -82,8 +83,6 @@ public class AboutFragment extends ToolbarFragment {
super.onDestroyView(); super.onDestroyView();
if (mWebView != null) { if (mWebView != null) {
Log.d("DAboutActivity", "onDestroy");
mWebView.removeAllViews(); mWebView.removeAllViews();
mWebView.setWebViewClient(null); mWebView.setWebViewClient(null);
((ViewGroup) mWebView.getParent()).removeView(mWebView); ((ViewGroup) mWebView.getParent()).removeView(mWebView);

View File

@ -1,8 +1,8 @@
package org.itxtech.daedalus.fragment; package org.itxtech.daedalus.fragment;
import android.content.Intent; import android.content.Intent;
import android.preference.PreferenceFragment;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.preference.PreferenceFragmentCompat;
/** /**
* Daedalus Project * Daedalus Project
@ -15,7 +15,7 @@ import androidx.appcompat.widget.Toolbar;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
abstract public class ConfigFragment extends PreferenceFragment implements Toolbar.OnMenuItemClickListener { abstract public class ConfigFragment extends PreferenceFragmentCompat implements Toolbar.OnMenuItemClickListener {
protected Intent intent = null; protected Intent intent = null;
public void setIntent(Intent intent) { public void setIntent(Intent intent) {

View File

@ -2,7 +2,7 @@ package org.itxtech.daedalus.fragment;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.os.Bundle; import android.os.Bundle;
import android.preference.EditTextPreference; import androidx.preference.EditTextPreference;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -11,8 +11,8 @@ import com.google.android.material.snackbar.Snackbar;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.activity.ConfigActivity; import org.itxtech.daedalus.activity.ConfigActivity;
import org.itxtech.daedalus.util.server.CustomDNSServer; import org.itxtech.daedalus.server.CustomDnsServer;
import org.itxtech.daedalus.util.server.DNSServer; import org.itxtech.daedalus.server.DnsServer;
/** /**
* Daedalus Project * Daedalus Project
@ -25,12 +25,11 @@ import org.itxtech.daedalus.util.server.DNSServer;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DNSServerConfigFragment extends ConfigFragment { public class DnsServerConfigFragment extends ConfigFragment {
private int index; private int index;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.perf_server); addPreferencesFromResource(R.xml.perf_server);
} }
@ -38,19 +37,19 @@ public class DNSServerConfigFragment extends ConfigFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState); View view = super.onCreateView(inflater, container, savedInstanceState);
EditTextPreference serverName = (EditTextPreference) findPreference("serverName"); EditTextPreference serverName = findPreference("serverName");
serverName.setOnPreferenceChangeListener((preference, newValue) -> { serverName.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
EditTextPreference serverAddress = (EditTextPreference) findPreference("serverAddress"); EditTextPreference serverAddress = findPreference("serverAddress");
serverAddress.setOnPreferenceChangeListener((preference, newValue) -> { serverAddress.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
EditTextPreference serverPort = (EditTextPreference) findPreference("serverPort"); EditTextPreference serverPort = findPreference("serverPort");
serverPort.setOnPreferenceChangeListener((preference, newValue) -> { serverPort.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
@ -59,7 +58,7 @@ public class DNSServerConfigFragment extends ConfigFragment {
index = intent.getIntExtra(ConfigActivity.LAUNCH_ACTION_ID, ConfigActivity.ID_NONE); index = intent.getIntExtra(ConfigActivity.LAUNCH_ACTION_ID, ConfigActivity.ID_NONE);
if (index != ConfigActivity.ID_NONE) { if (index != ConfigActivity.ID_NONE) {
CustomDNSServer server = Daedalus.configurations.getCustomDNSServers().get(index); CustomDnsServer server = Daedalus.configurations.getCustomDNSServers().get(index);
serverName.setText(server.getName()); serverName.setText(server.getName());
serverName.setSummary(server.getName()); serverName.setSummary(server.getName());
serverAddress.setText(server.getAddress()); serverAddress.setText(server.getAddress());
@ -69,7 +68,7 @@ public class DNSServerConfigFragment extends ConfigFragment {
} else { } else {
serverName.setText(""); serverName.setText("");
serverAddress.setText(""); serverAddress.setText("");
String port = String.valueOf(DNSServer.DNS_SERVER_DEFAULT_PORT); String port = String.valueOf(DnsServer.DNS_SERVER_DEFAULT_PORT);
serverPort.setText(port); serverPort.setText(port);
serverPort.setSummary(port); serverPort.setSummary(port);
} }
@ -93,9 +92,9 @@ public class DNSServerConfigFragment extends ConfigFragment {
} }
if (index == ConfigActivity.ID_NONE) { if (index == ConfigActivity.ID_NONE) {
Daedalus.configurations.getCustomDNSServers().add(new CustomDNSServer(serverName, serverAddress, Integer.parseInt(serverPort))); Daedalus.configurations.getCustomDNSServers().add(new CustomDnsServer(serverName, serverAddress, Integer.parseInt(serverPort)));
} else { } else {
CustomDNSServer server = Daedalus.configurations.getCustomDNSServers().get(index); CustomDnsServer server = Daedalus.configurations.getCustomDNSServers().get(index);
server.setName(serverName); server.setName(serverName);
server.setAddress(serverAddress); server.setAddress(serverAddress);
server.setPort(Integer.parseInt(serverPort)); server.setPort(Integer.parseInt(serverPort));

View File

@ -15,8 +15,8 @@ import com.google.android.material.snackbar.Snackbar;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.activity.ConfigActivity; import org.itxtech.daedalus.activity.ConfigActivity;
import org.itxtech.daedalus.util.server.CustomDNSServer; import org.itxtech.daedalus.server.CustomDnsServer;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.DnsServerHelper;
/** /**
* Daedalus Project * Daedalus Project
@ -29,9 +29,9 @@ import org.itxtech.daedalus.util.server.DNSServerHelper;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DNSServersFragment extends ToolbarFragment { public class DnsServersFragment extends ToolbarFragment {
private DNSServerAdapter adapter; private DNSServerAdapter adapter;
private CustomDNSServer server = null; private CustomDnsServer server = null;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -47,7 +47,7 @@ public class DNSServersFragment extends ToolbarFragment {
if (viewHolder instanceof ViewHolder) { if (viewHolder instanceof ViewHolder) {
int index = ((ViewHolder) viewHolder).getIndex(); int index = ((ViewHolder) viewHolder).getIndex();
if (index < Daedalus.configurations.getCustomDNSServers().size() && if (index < Daedalus.configurations.getCustomDNSServers().size() &&
DNSServerHelper.isInUsing(Daedalus.configurations.getCustomDNSServers().get(index))) { DnsServerHelper.isInUsing(Daedalus.configurations.getCustomDNSServers().get(index))) {
return 0; return 0;
} }
} }
@ -118,7 +118,7 @@ public class DNSServersFragment extends ToolbarFragment {
private class DNSServerAdapter extends RecyclerView.Adapter<ViewHolder> { private class DNSServerAdapter extends RecyclerView.Adapter<ViewHolder> {
@Override @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
CustomDNSServer server = Daedalus.configurations.getCustomDNSServers().get(position); CustomDnsServer server = Daedalus.configurations.getCustomDNSServers().get(position);
holder.setIndex(position); holder.setIndex(position);
holder.textViewName.setText(server.getName()); holder.textViewName.setText(server.getName());
holder.textViewAddress.setText(server.getRealName()); holder.textViewAddress.setText(server.getRealName());
@ -159,7 +159,7 @@ public class DNSServersFragment extends ToolbarFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (!DNSServerHelper.isInUsing(Daedalus.configurations.getCustomDNSServers().get(index))) { if (!DnsServerHelper.isInUsing(Daedalus.configurations.getCustomDNSServers().get(index))) {
Daedalus.getInstance().startActivity(new Intent(Daedalus.getInstance(), ConfigActivity.class) Daedalus.getInstance().startActivity(new Intent(Daedalus.getInstance(), ConfigActivity.class)
.putExtra(ConfigActivity.LAUNCH_ACTION_ID, index) .putExtra(ConfigActivity.LAUNCH_ACTION_ID, index)
.putExtra(ConfigActivity.LAUNCH_ACTION_FRAGMENT, ConfigActivity.LAUNCH_FRAGMENT_DNS_SERVER) .putExtra(ConfigActivity.LAUNCH_ACTION_FRAGMENT, ConfigActivity.LAUNCH_FRAGMENT_DNS_SERVER)

View File

@ -12,8 +12,8 @@ import android.widget.*;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.server.AbstractDNSServer; import org.itxtech.daedalus.server.AbstractDnsServer;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.DnsServerHelper;
import org.minidns.dnsmessage.DnsMessage; import org.minidns.dnsmessage.DnsMessage;
import org.minidns.dnsmessage.Question; import org.minidns.dnsmessage.Question;
import org.minidns.record.Record; import org.minidns.record.Record;
@ -36,7 +36,7 @@ import java.util.Random;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DNSTestFragment extends ToolbarFragment { public class DnsTestFragment extends ToolbarFragment {
private class Type { private class Type {
private Record.TYPE type; private Record.TYPE type;
private String name; private String name;
@ -67,9 +67,9 @@ public class DNSTestFragment extends ToolbarFragment {
final TextView textViewTestInfo = view.findViewById(R.id.textView_test_info); final TextView textViewTestInfo = view.findViewById(R.id.textView_test_info);
final Spinner spinnerServerChoice = view.findViewById(R.id.spinner_server_choice); final Spinner spinnerServerChoice = view.findViewById(R.id.spinner_server_choice);
ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, DNSServerHelper.getAllServers()); ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, DnsServerHelper.getAllServers());
spinnerServerChoice.setAdapter(spinnerArrayAdapter); spinnerServerChoice.setAdapter(spinnerArrayAdapter);
spinnerServerChoice.setSelection(DNSServerHelper.getPosition(DNSServerHelper.getPrimary())); spinnerServerChoice.setSelection(DnsServerHelper.getPosition(DnsServerHelper.getPrimary()));
ArrayList<Type> types = new ArrayList<Type>() {{ ArrayList<Type> types = new ArrayList<Type>() {{
add(new Type("A", Record.TYPE.A)); add(new Type("A", Record.TYPE.A));
@ -110,38 +110,38 @@ public class DNSTestFragment extends ToolbarFragment {
testDomain = Daedalus.DEFAULT_TEST_DOMAINS[0]; testDomain = Daedalus.DEFAULT_TEST_DOMAINS[0];
} }
StringBuilder testText = new StringBuilder(); StringBuilder testText = new StringBuilder();
ArrayList<AbstractDNSServer> dnsServers = new ArrayList<AbstractDNSServer>() {{ ArrayList<AbstractDnsServer> dnsServers = new ArrayList<AbstractDnsServer>() {{
add(((AbstractDNSServer) spinnerServerChoice.getSelectedItem())); add(((AbstractDnsServer) spinnerServerChoice.getSelectedItem()));
String servers = Daedalus.getPrefs().getString("dns_test_servers", ""); String servers = Daedalus.getPrefs().getString("dns_test_servers", "");
if (!servers.equals("")) { if (!servers.equals("")) {
for (String server : servers.split(",")) { for (String server : servers.split(",")) {
if (server.contains(".") && server.contains(":")) {//IPv4 if (server.contains(".") && server.contains(":")) {//IPv4
String[] pieces = servers.split(":"); String[] pieces = servers.split(":");
int port = AbstractDNSServer.DNS_SERVER_DEFAULT_PORT; int port = AbstractDnsServer.DNS_SERVER_DEFAULT_PORT;
try { try {
port = Integer.parseInt(pieces[1]); port = Integer.parseInt(pieces[1]);
} catch (Exception e) { } catch (Exception e) {
Logger.logException(e); Logger.logException(e);
} }
add(new AbstractDNSServer(pieces[0], port)); add(new AbstractDnsServer(pieces[0], port));
} else if (!server.contains(".") && server.contains("|")) {//IPv6 } else if (!server.contains(".") && server.contains("|")) {//IPv6
String[] pieces = servers.split("\\|"); String[] pieces = servers.split("\\|");
int port = AbstractDNSServer.DNS_SERVER_DEFAULT_PORT; int port = AbstractDnsServer.DNS_SERVER_DEFAULT_PORT;
try { try {
port = Integer.parseInt(pieces[1]); port = Integer.parseInt(pieces[1]);
} catch (Exception e) { } catch (Exception e) {
Logger.logException(e); Logger.logException(e);
} }
add(new AbstractDNSServer(pieces[0], port)); add(new AbstractDnsServer(pieces[0], port));
} else { } else {
add(new AbstractDNSServer(server, AbstractDNSServer.DNS_SERVER_DEFAULT_PORT)); add(new AbstractDnsServer(server, AbstractDnsServer.DNS_SERVER_DEFAULT_PORT));
} }
} }
} }
}}; }};
DnsQuery dnsQuery = new DnsQuery(); DnsQuery dnsQuery = new DnsQuery();
Record.TYPE type = ((Type) spinnerType.getSelectedItem()).getType(); Record.TYPE type = ((Type) spinnerType.getSelectedItem()).getType();
for (AbstractDNSServer dnsServer : dnsServers) { for (AbstractDnsServer dnsServer : dnsServers) {
testText = testServer(dnsQuery, type, dnsServer, testDomain, testText); testText = testServer(dnsQuery, type, dnsServer, testDomain, testText);
} }
mHandler.obtainMessage(DnsTestHandler.MSG_TEST_DONE).sendToTarget(); mHandler.obtainMessage(DnsTestHandler.MSG_TEST_DONE).sendToTarget();
@ -151,8 +151,7 @@ public class DNSTestFragment extends ToolbarFragment {
} }
} }
private StringBuilder testServer(DnsQuery dnsQuery, Record.TYPE type, AbstractDnsServer server, String domain, StringBuilder testText) {
private StringBuilder testServer(DnsQuery dnsQuery, Record.TYPE type, AbstractDNSServer server, String domain, StringBuilder testText) {
Logger.debug("Testing DNS server " + server.getRealName()); Logger.debug("Testing DNS server " + server.getRealName());
testText.append(getString(R.string.test_domain)).append(" ").append(domain).append("\n") testText.append(getString(R.string.test_domain)).append(" ").append(domain).append("\n")
.append(getString(R.string.test_dns_server)).append(" ").append(server.getRealName()); .append(getString(R.string.test_dns_server)).append(" ").append(server.getRealName());
@ -181,7 +180,7 @@ public class DNSTestFragment extends ToolbarFragment {
} }
} }
testText.append("\n").append(getString(R.string.test_time_used)).append(" "). testText.append("\n").append(getString(R.string.test_time_used)).append(" ").
append(String.valueOf(endTime - startTime)).append(" ms"); append(endTime - startTime).append(" ms");
succ = true; succ = true;
} }
} catch (SocketTimeoutException ignored) { } catch (SocketTimeoutException ignored) {

View File

@ -2,12 +2,14 @@ package org.itxtech.daedalus.fragment;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.preference.*; import androidx.preference.*;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.activity.AppFilterActivity; import org.itxtech.daedalus.activity.AppFilterActivity;
import org.itxtech.daedalus.activity.MainActivity; import org.itxtech.daedalus.activity.MainActivity;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.DnsServerHelper;
import java.util.ArrayList;
/** /**
* Daedalus Project * Daedalus Project
@ -20,52 +22,47 @@ import org.itxtech.daedalus.util.server.DNSServerHelper;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class GlobalConfigFragment extends PreferenceFragment { public class GlobalConfigFragment extends PreferenceFragmentCompat {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreate(savedInstanceState);
Daedalus.getPrefs().edit() Daedalus.getPrefs().edit()
.putString("primary_server", DNSServerHelper.getPrimary()) .putString("primary_server", DnsServerHelper.getPrimary())
.putString("secondary_server", DNSServerHelper.getSecondary()) .putString("secondary_server", DnsServerHelper.getSecondary())
.apply(); .apply();
addPreferencesFromResource(R.xml.perf_settings); addPreferencesFromResource(R.xml.perf_settings);
ListPreference primaryServer = (ListPreference) findPreference("primary_server"); boolean visible = !Daedalus.getPrefs().getBoolean("settings_use_system_dns", false);
primaryServer.setEntries(DNSServerHelper.getNames(Daedalus.getInstance())); for (String k : new ArrayList<String>() {{
primaryServer.setEntryValues(DNSServerHelper.getIds()); add("primary_server");
primaryServer.setSummary(DNSServerHelper.getDescription(primaryServer.getValue(), Daedalus.getInstance())); add("secondary_server");
primaryServer.setOnPreferenceChangeListener((preference, newValue) -> { }}) {
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance())); ListPreference listPref = findPreference(k);
return true; listPref.setEntries(DnsServerHelper.getNames(Daedalus.getInstance()));
}); listPref.setEntryValues(DnsServerHelper.getIds());
listPref.setSummary(DnsServerHelper.getDescription(listPref.getValue(), Daedalus.getInstance()));
listPref.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary(DnsServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
return true;
});
}
ListPreference secondaryServer = (ListPreference) findPreference("secondary_server"); EditTextPreference testDNSServers = findPreference("dns_test_servers");
secondaryServer.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
secondaryServer.setEntryValues(DNSServerHelper.getIds());
secondaryServer.setSummary(DNSServerHelper.getDescription(secondaryServer.getValue(), Daedalus.getInstance()));
secondaryServer.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
return true;
});
EditTextPreference testDNSServers = (EditTextPreference) findPreference("dns_test_servers");
testDNSServers.setSummary(testDNSServers.getText()); testDNSServers.setSummary(testDNSServers.getText());
testDNSServers.setOnPreferenceChangeListener((preference, newValue) -> { testDNSServers.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
EditTextPreference logSize = (EditTextPreference) findPreference("settings_log_size"); EditTextPreference logSize = findPreference("settings_log_size");
logSize.setSummary(logSize.getText()); logSize.setSummary(logSize.getText());
logSize.setOnPreferenceChangeListener((preference, newValue) -> { logSize.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
SwitchPreference darkTheme = (SwitchPreference) findPreference("settings_dark_theme"); SwitchPreference darkTheme = findPreference("settings_dark_theme");
darkTheme.setOnPreferenceChangeListener((preference, o) -> { darkTheme.setOnPreferenceChangeListener((preference, o) -> {
getActivity().startActivity(new Intent(Daedalus.getInstance(), MainActivity.class) getActivity().startActivity(new Intent(Daedalus.getInstance(), MainActivity.class)
.putExtra(MainActivity.LAUNCH_FRAGMENT, MainActivity.FRAGMENT_SETTINGS) .putExtra(MainActivity.LAUNCH_FRAGMENT, MainActivity.FRAGMENT_SETTINGS)
@ -73,13 +70,13 @@ public class GlobalConfigFragment extends PreferenceFragment {
return true; return true;
}); });
SwitchPreference advanced = (SwitchPreference) findPreference("settings_advanced_switch"); SwitchPreference advanced = findPreference("settings_advanced_switch");
advanced.setOnPreferenceChangeListener((preference, newValue) -> { advanced.setOnPreferenceChangeListener((preference, newValue) -> {
updateOptions((boolean) newValue, "settings_advanced"); updateOptions((boolean) newValue, "settings_advanced");
return true; return true;
}); });
SwitchPreference appFilter = (SwitchPreference) findPreference("settings_app_filter_switch"); SwitchPreference appFilter = findPreference("settings_app_filter_switch");
appFilter.setOnPreferenceChangeListener((p, w) -> { appFilter.setOnPreferenceChangeListener((p, w) -> {
updateOptions((boolean) w, "settings_app_filter"); updateOptions((boolean) w, "settings_app_filter");
return true; return true;
@ -115,7 +112,7 @@ public class GlobalConfigFragment extends PreferenceFragment {
} }
private void updateOptions(boolean checked, String pref) { private void updateOptions(boolean checked, String pref) {
PreferenceCategory category = (PreferenceCategory) findPreference(pref); PreferenceCategory category = findPreference(pref);
for (int i = 1; i < category.getPreferenceCount(); i++) { for (int i = 1; i < category.getPreferenceCount(); i++) {
Preference preference = category.getPreference(i); Preference preference = category.getPreference(i);
if (checked) { if (checked) {

View File

@ -49,16 +49,7 @@ public class HomeFragment extends ToolbarFragment {
updateUserInterface(); updateUserInterface();
} }
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
updateUserInterface();
}
}
private void updateUserInterface() { private void updateUserInterface() {
Log.d("DMainFragment", "updateInterface");
Button but = getView().findViewById(R.id.button_activate); Button but = getView().findViewById(R.id.button_activate);
if (DaedalusVpnService.isActivated()) { if (DaedalusVpnService.isActivated()) {
but.setText(R.string.button_text_deactivate); but.setText(R.string.button_text_deactivate);

View File

@ -44,7 +44,7 @@ public class LogFragment extends ToolbarFragment implements Toolbar.OnMenuItemCl
private void export() { private void export() {
try { try {
String file = Daedalus.logPath + String.valueOf(System.currentTimeMillis()) + ".log"; String file = Daedalus.logPath + System.currentTimeMillis() + ".log";
FileWriter fileWriter = new FileWriter(file); FileWriter fileWriter = new FileWriter(file);
fileWriter.write(Logger.getLog()); fileWriter.write(Logger.getLog());
fileWriter.close(); fileWriter.close();

View File

@ -7,8 +7,8 @@ import android.net.Uri;
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.EditTextPreference; import androidx.preference.EditTextPreference;
import android.preference.ListPreference; import androidx.preference.ListPreference;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -72,10 +72,8 @@ public class RuleConfigFragment extends ConfigFragment {
} }
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.perf_rule); addPreferencesFromResource(R.xml.perf_rule);
} }
@ -85,13 +83,13 @@ public class RuleConfigFragment extends ConfigFragment {
mHandler = new RuleConfigHandler().setView(view); mHandler = new RuleConfigHandler().setView(view);
final EditTextPreference ruleName = (EditTextPreference) findPreference("ruleName"); final EditTextPreference ruleName = findPreference("ruleName");
ruleName.setOnPreferenceChangeListener((preference, newValue) -> { ruleName.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
final ListPreference ruleType = (ListPreference) findPreference("ruleType"); final ListPreference ruleType = findPreference("ruleType");
final String[] entries = {"Hosts", "DNSMasq"}; final String[] entries = {"Hosts", "DNSMasq"};
String[] values = {"0", "1"}; String[] values = {"0", "1"};
ruleType.setEntries(entries); ruleType.setEntries(entries);
@ -101,19 +99,19 @@ public class RuleConfigFragment extends ConfigFragment {
return true; return true;
}); });
final EditTextPreference ruleDownloadUrl = (EditTextPreference) findPreference("ruleDownloadUrl"); final EditTextPreference ruleDownloadUrl = findPreference("ruleDownloadUrl");
ruleDownloadUrl.setOnPreferenceChangeListener((preference, newValue) -> { ruleDownloadUrl.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
final EditTextPreference ruleFilename = (EditTextPreference) findPreference("ruleFilename"); final EditTextPreference ruleFilename = findPreference("ruleFilename");
ruleFilename.setOnPreferenceChangeListener((preference, newValue) -> { ruleFilename.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary((String) newValue); preference.setSummary((String) newValue);
return true; return true;
}); });
ClickPreference ruleSync = (ClickPreference) findPreference("ruleSync"); ClickPreference ruleSync = findPreference("ruleSync");
ruleSync.setOnPreferenceClickListener(preference -> { ruleSync.setOnPreferenceClickListener(preference -> {
save(); save();
if (mThread == null) { if (mThread == null) {
@ -167,7 +165,7 @@ public class RuleConfigFragment extends ConfigFragment {
return false; return false;
}); });
ListPreference ruleImportBuildIn = (ListPreference) findPreference("ruleImportBuildIn"); ListPreference ruleImportBuildIn = findPreference("ruleImportBuildIn");
ruleImportBuildIn.setEntries(Rule.getBuildInRuleNames()); ruleImportBuildIn.setEntries(Rule.getBuildInRuleNames());
ruleImportBuildIn.setEntryValues(Rule.getBuildInRuleEntries()); ruleImportBuildIn.setEntryValues(Rule.getBuildInRuleEntries());
ruleImportBuildIn.setOnPreferenceChangeListener((preference, newValue) -> { ruleImportBuildIn.setOnPreferenceChangeListener((preference, newValue) -> {
@ -183,7 +181,7 @@ public class RuleConfigFragment extends ConfigFragment {
return true; return true;
}); });
ClickPreference ruleImportExternal = (ClickPreference) findPreference("ruleImportExternal"); ClickPreference ruleImportExternal = findPreference("ruleImportExternal");
ruleImportExternal.setOnPreferenceClickListener(preference -> { ruleImportExternal.setOnPreferenceClickListener(preference -> {
performFileSearch(); performFileSearch();
return false; return false;

View File

@ -1,7 +1,5 @@
package org.itxtech.daedalus.fragment; package org.itxtech.daedalus.fragment;
import android.app.FragmentManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -28,13 +26,7 @@ public class SettingsFragment extends ToolbarFragment {
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
FragmentManager fm; getChildFragmentManager().beginTransaction().replace(R.id.settings_content, new GlobalConfigFragment()).commit();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
fm = getChildFragmentManager();
} else {
fm = getFragmentManager();
}
fm.beginTransaction().replace(R.id.settings_content, new GlobalConfigFragment()).commit();
} }
@Override @Override

View File

@ -1,10 +1,10 @@
package org.itxtech.daedalus.fragment; package org.itxtech.daedalus.fragment;
import android.app.Fragment;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
import android.view.View; import android.view.View;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import com.google.android.material.navigation.NavigationView; import com.google.android.material.navigation.NavigationView;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;

View File

@ -10,7 +10,7 @@ import okhttp3.OkHttpClient;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.service.DaedalusVpnService;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.DnsServerHelper;
import org.minidns.dnsmessage.DnsMessage; import org.minidns.dnsmessage.DnsMessage;
import org.pcap4j.packet.IpPacket; import org.pcap4j.packet.IpPacket;
import org.pcap4j.packet.IpSelector; import org.pcap4j.packet.IpSelector;
@ -58,8 +58,8 @@ abstract public class HttpsProvider extends Provider {
.header("Accept", accept) .header("Accept", accept)
.build())) .build()))
.dns(hostname -> { .dns(hostname -> {
if (DNSServerHelper.domainCache.containsKey(hostname)) { if (DnsServerHelper.domainCache.containsKey(hostname)) {
return DNSServerHelper.domainCache.get(hostname); return DnsServerHelper.domainCache.get(hostname);
} }
return Arrays.asList(InetAddress.getAllByName(hostname)); return Arrays.asList(InetAddress.getAllByName(hostname));
}) })
@ -138,7 +138,7 @@ abstract public class HttpsProvider extends Provider {
return; return;
String uri; String uri;
try { try {
uri = service.dnsServers.get(destAddr.getHostAddress());//https uri uri = service.dnsServers.get(destAddr.getHostAddress()).getAddress();//https uri
} catch (Exception e) { } catch (Exception e) {
Logger.logException(e); Logger.logException(e);
return; return;
@ -161,7 +161,7 @@ abstract public class HttpsProvider extends Provider {
return; return;
} }
if (dnsMsg.getQuestion() == null) { if (dnsMsg.getQuestion() == null) {
Log.i(TAG, "handleDnsRequest: Discarding DNS packet with no query " + dnsMsg); Logger.debug("handleDnsRequest: Discarding DNS packet with no query " + dnsMsg);
return; return;
} }

View File

@ -15,7 +15,7 @@ import org.itxtech.daedalus.service.DaedalusVpnService;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class ProviderPicker { public abstract class ProviderPicker {
public static final int DNS_QUERY_METHOD_UDP = 0; public static final int DNS_QUERY_METHOD_UDP = 0;
public static final int DNS_QUERY_METHOD_TCP = 1; public static final int DNS_QUERY_METHOD_TCP = 1;
public static final int DNS_QUERY_METHOD_TLS = 2; public static final int DNS_QUERY_METHOD_TLS = 2;
@ -40,6 +40,6 @@ public class ProviderPicker {
} }
public static int getDnsQueryMethod() { public static int getDnsQueryMethod() {
return Integer.valueOf(Daedalus.getPrefs().getString("settings_dns_query_method", "0")); return Integer.parseInt(Daedalus.getPrefs().getString("settings_dns_query_method", "0"));
} }
} }

View File

@ -9,7 +9,7 @@ import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.service.DaedalusVpnService;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.AbstractDnsServer;
import org.pcap4j.packet.IpPacket; import org.pcap4j.packet.IpPacket;
import java.io.*; import java.io.*;
@ -123,7 +123,7 @@ public class TcpProvider extends UdpProvider {
} }
@Override @Override
protected void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket) throws DaedalusVpnService.VpnNetworkException { protected void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket, AbstractDnsServer dnsServer) throws DaedalusVpnService.VpnNetworkException {
Socket dnsSocket; Socket dnsSocket;
try { try {
// Packets to be sent to the real DNS server will need to be protected from the VPN // Packets to be sent to the real DNS server will need to be protected from the VPN
@ -131,7 +131,7 @@ public class TcpProvider extends UdpProvider {
service.protect(dnsSocket); service.protect(dnsSocket);
SocketAddress address = new InetSocketAddress(outPacket.getAddress(), DNSServerHelper.getPortOrDefault(outPacket.getAddress(), outPacket.getPort())); SocketAddress address = new InetSocketAddress(outPacket.getAddress(), dnsServer.getPort());
dnsSocket.connect(address, 5000); dnsSocket.connect(address, 5000);
dnsSocket.setSoTimeout(5000); dnsSocket.setSoTimeout(5000);
Logger.info("TcpProvider: Sending DNS query request"); Logger.info("TcpProvider: Sending DNS query request");
@ -161,7 +161,7 @@ public class TcpProvider extends UdpProvider {
try { try {
DataInputStream stream = new DataInputStream(dnsSocket.getInputStream()); DataInputStream stream = new DataInputStream(dnsSocket.getInputStream());
int length = stream.readUnsignedShort(); int length = stream.readUnsignedShort();
Log.d(TAG, "Reading length: " + String.valueOf(length)); Log.d(TAG, "Reading length: " + length);
byte[] data = new byte[length]; byte[] data = new byte[length];
stream.read(data); stream.read(data);
dnsSocket.close(); dnsSocket.close();

View File

@ -3,7 +3,7 @@ package org.itxtech.daedalus.provider;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.service.DaedalusVpnService;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.AbstractDnsServer;
import org.pcap4j.packet.IpPacket; import org.pcap4j.packet.IpPacket;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -28,13 +28,12 @@ public class TlsProvider extends TcpProvider{
} }
@Override @Override
protected void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket) { protected void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket, AbstractDnsServer dnsServer) {
Socket dnsSocket; Socket dnsSocket;
try { try {
SSLContext context = SSLContext.getInstance("TLSv1.2"); SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null, null, null); context.init(null, null, null);
dnsSocket = context.getSocketFactory().createSocket(outPacket.getAddress(), dnsSocket = context.getSocketFactory().createSocket(outPacket.getAddress(), dnsServer.getPort());
DNSServerHelper.getPortOrDefault(outPacket.getAddress(), outPacket.getPort()));
//Create TLS v1.2 socket //Create TLS v1.2 socket
//TODO: SNI //TODO: SNI

View File

@ -9,7 +9,7 @@ import androidx.annotation.NonNull;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.service.DaedalusVpnService;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.server.DNSServerHelper; import org.itxtech.daedalus.server.AbstractDnsServer;
import org.minidns.dnsmessage.DnsMessage; import org.minidns.dnsmessage.DnsMessage;
import org.pcap4j.packet.IpPacket; import org.pcap4j.packet.IpPacket;
import org.pcap4j.packet.IpSelector; import org.pcap4j.packet.IpSelector;
@ -118,7 +118,7 @@ public class UdpProvider extends Provider {
} }
} }
protected void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket) throws DaedalusVpnService.VpnNetworkException { protected void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket, AbstractDnsServer dnsServer) throws DaedalusVpnService.VpnNetworkException {
DatagramSocket dnsSocket; DatagramSocket dnsSocket;
try { try {
// Packets to be sent to the real DNS server will need to be protected from the VPN // Packets to be sent to the real DNS server will need to be protected from the VPN
@ -158,7 +158,6 @@ public class UdpProvider extends Provider {
*/ */
@Override @Override
protected void handleDnsRequest(byte[] packetData) throws DaedalusVpnService.VpnNetworkException { protected void handleDnsRequest(byte[] packetData) throws DaedalusVpnService.VpnNetworkException {
IpPacket parsedPacket; IpPacket parsedPacket;
try { try {
parsedPacket = (IpPacket) IpSelector.newPacket(packetData, 0, packetData.length); parsedPacket = (IpPacket) IpSelector.newPacket(packetData, 0, packetData.length);
@ -168,15 +167,21 @@ public class UdpProvider extends Provider {
} }
if (!(parsedPacket.getPayload() instanceof UdpPacket)) { if (!(parsedPacket.getPayload() instanceof UdpPacket)) {
Log.i(TAG, "handleDnsRequest: Discarding unknown packet type " + parsedPacket.getPayload()); try {
Logger.debug("handleDnsRequest: Discarding unknown packet type " + parsedPacket.getPayload());
} catch (Exception ignored) {
}
return; return;
} }
InetAddress destAddr = parsedPacket.getHeader().getDstAddr(); InetAddress destAddr = parsedPacket.getHeader().getDstAddr();
if (destAddr == null) if (destAddr == null) {
return; return;
}
AbstractDnsServer dnsServer;
try { try {
destAddr = InetAddress.getByName(service.dnsServers.get(destAddr.getHostAddress())); dnsServer = service.dnsServers.get(destAddr.getHostAddress());
destAddr = InetAddress.getByName(dnsServer.getHostAddress());
} catch (Exception e) { } catch (Exception e) {
Logger.logException(e); Logger.logException(e);
Logger.error("handleDnsRequest: DNS server alias query failed for " + destAddr.getHostAddress()); Logger.error("handleDnsRequest: DNS server alias query failed for " + destAddr.getHostAddress());
@ -191,9 +196,8 @@ public class UdpProvider extends Provider {
// Let's be nice to Firefox. Firefox uses an empty UDP packet to // Let's be nice to Firefox. Firefox uses an empty UDP packet to
// the gateway to reduce the RTT. For further details, please see // the gateway to reduce the RTT. For further details, please see
// https://bugzilla.mozilla.org/show_bug.cgi?id=888268 // https://bugzilla.mozilla.org/show_bug.cgi?id=888268
DatagramPacket outPacket = new DatagramPacket(new byte[0], 0, 0, destAddr, DatagramPacket outPacket = new DatagramPacket(new byte[0], 0, 0, destAddr, dnsServer.getPort());
DNSServerHelper.getPortOrDefault(destAddr, parsedUdp.getHeader().getDstPort().valueAsInt())); forwardPacket(outPacket, null, dnsServer);
forwardPacket(outPacket, null);
return; return;
} }
@ -209,14 +213,13 @@ public class UdpProvider extends Provider {
return; return;
} }
if (dnsMsg.getQuestion() == null) { if (dnsMsg.getQuestion() == null) {
Log.i(TAG, "handleDnsRequest: Discarding DNS packet with no query " + dnsMsg); Logger.debug("handleDnsRequest: Discarding DNS packet with no query " + dnsMsg);
return; return;
} }
if (!resolve(parsedPacket, dnsMsg)) { if (!resolve(parsedPacket, dnsMsg)) {
DatagramPacket outPacket = new DatagramPacket(dnsRawData, 0, dnsRawData.length, destAddr, DatagramPacket outPacket = new DatagramPacket(dnsRawData, 0, dnsRawData.length, destAddr, dnsServer.getPort());
DNSServerHelper.getPortOrDefault(destAddr, parsedUdp.getHeader().getDstPort().valueAsInt())); forwardPacket(outPacket, parsedPacket, dnsServer);
forwardPacket(outPacket, parsedPacket);
} }
} }

View File

@ -21,7 +21,7 @@ public class BootBroadcastReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (Daedalus.getPrefs().getBoolean("settings_boot", false)) { if (Daedalus.getPrefs().getBoolean("settings_boot", false)) {
Daedalus.activateService(context); Daedalus.activateService(context, true);
Logger.info("Triggered boot receiver"); Logger.info("Triggered boot receiver");
} }
} }

View File

@ -1,4 +1,6 @@
package org.itxtech.daedalus.util.server; package org.itxtech.daedalus.server;
import androidx.annotation.NonNull;
/** /**
* Daedalus Project * Daedalus Project
@ -11,17 +13,26 @@ package org.itxtech.daedalus.util.server;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class AbstractDNSServer { public class AbstractDnsServer implements Cloneable {
public static final int DNS_SERVER_DEFAULT_PORT = 53; public static final int DNS_SERVER_DEFAULT_PORT = 53;
protected String address; protected String address;
protected int port; protected int port;
protected String hostAddress;
public AbstractDNSServer(String address, int port) { public AbstractDnsServer(String address, int port) {
this.address = address; this.address = address;
this.port = port; this.port = port;
} }
public void setHostAddress(String hostAddress) {
this.hostAddress = hostAddress;
}
public String getHostAddress() {
return hostAddress;
}
public void setAddress(String address) { public void setAddress(String address) {
this.address = address; this.address = address;
} }
@ -54,4 +65,14 @@ public class AbstractDNSServer {
public boolean isHttpsServer() { public boolean isHttpsServer() {
return address.contains("/"); return address.contains("/");
} }
@NonNull
@Override
public Object clone() {
try {
return super.clone();
} catch (Exception ignored) {
}
return new AbstractDnsServer("", 0);
}
} }

View File

@ -1,4 +1,4 @@
package org.itxtech.daedalus.util.server; package org.itxtech.daedalus.server;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
@ -13,11 +13,11 @@ import org.itxtech.daedalus.Daedalus;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class CustomDNSServer extends AbstractDNSServer { public class CustomDnsServer extends AbstractDnsServer {
private String name; private String name;
private String id; private String id;
public CustomDNSServer(String name, String address, int port) { public CustomDnsServer(String name, String address, int port) {
super(address, port); super(address, port);
this.name = name; this.name = name;
this.id = String.valueOf(Daedalus.configurations.getNextDnsId()); this.id = String.valueOf(Daedalus.configurations.getNextDnsId());

View File

@ -1,4 +1,4 @@
package org.itxtech.daedalus.util.server; package org.itxtech.daedalus.server;
import android.content.Context; import android.content.Context;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
@ -14,23 +14,27 @@ import org.itxtech.daedalus.Daedalus;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DNSServer extends AbstractDNSServer { public class DnsServer extends AbstractDnsServer {
private static int totalId = 0; private static int totalId = 0;
private String id; private String id;
private int description = 0; private int description;
public DNSServer(String address, int description, int port) { public DnsServer(String address, int description, int port) {
super(address, port); super(address, port);
this.id = String.valueOf(totalId++); this.id = String.valueOf(totalId++);
this.description = description; this.description = description;
} }
public DNSServer(String address, int description) { public DnsServer(String address, int description) {
this(address, description, DNS_SERVER_DEFAULT_PORT); this(address, description, DNS_SERVER_DEFAULT_PORT);
} }
public DnsServer(String address) {
this(address, 0);
}
public String getId() { public String getId() {
return id; return id;
} }

View File

@ -1,4 +1,4 @@
package org.itxtech.daedalus.util.server; package org.itxtech.daedalus.server;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
@ -25,31 +25,19 @@ import java.util.List;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DNSServerHelper { public class DnsServerHelper {
private static HashMap<String, Integer> portCache = new HashMap<>();
public static HashMap<String, List<InetAddress>> domainCache = new HashMap<>(); public static HashMap<String, List<InetAddress>> domainCache = new HashMap<>();
public static void clearCache() { public static void clearCache() {
portCache = new HashMap<>();
domainCache = new HashMap<>(); domainCache = new HashMap<>();
} }
public static void buildCache() { public static void buildCache() {
domainCache = new HashMap<>(); domainCache = new HashMap<>();
portCache = new HashMap<>();
if (ProviderPicker.getDnsQueryMethod() >= ProviderPicker.DNS_QUERY_METHOD_HTTPS_IETF && if (ProviderPicker.getDnsQueryMethod() >= ProviderPicker.DNS_QUERY_METHOD_HTTPS_IETF &&
!Daedalus.getPrefs().getBoolean("settings_dont_build_doh_cache", false)) { !Daedalus.getPrefs().getBoolean("settings_dont_build_cache", false)) {
buildDomainCache(getAddressById(getPrimary())); buildDomainCache(getServerById(getPrimary()).getAddress());
buildDomainCache(getAddressById(getSecondary())); buildDomainCache(getServerById(getSecondary()).getAddress());
}
for (DNSServer server : Daedalus.DNS_SERVERS) {
portCache.put(server.getAddress(), server.getPort());
}
for (CustomDNSServer server : Daedalus.configurations.getCustomDNSServers()) {
portCache.put(server.getAddress(), server.getPort());
} }
} }
@ -63,16 +51,6 @@ public class DNSServerHelper {
} }
} }
public static int getPortOrDefault(InetAddress address, int defaultPort) {
String hostAddress = address.getHostAddress();
if (portCache.containsKey(hostAddress)) {
return portCache.get(hostAddress);
}
return defaultPort;
}
public static int getPosition(String id) { public static int getPosition(String id) {
int intId = Integer.parseInt(id); int intId = Integer.parseInt(id);
if (intId < Daedalus.DNS_SERVERS.size()) { if (intId < Daedalus.DNS_SERVERS.size()) {
@ -88,18 +66,18 @@ public class DNSServerHelper {
} }
public static String getPrimary() { public static String getPrimary() {
return String.valueOf(DNSServerHelper.checkServerId(Integer.parseInt(Daedalus.getPrefs().getString("primary_server", "0")))); return String.valueOf(DnsServerHelper.checkServerId(Integer.parseInt(Daedalus.getPrefs().getString("primary_server", "0"))));
} }
public static String getSecondary() { public static String getSecondary() {
return String.valueOf(DNSServerHelper.checkServerId(Integer.parseInt(Daedalus.getPrefs().getString("secondary_server", "1")))); return String.valueOf(DnsServerHelper.checkServerId(Integer.parseInt(Daedalus.getPrefs().getString("secondary_server", "1"))));
} }
private static int checkServerId(int id) { private static int checkServerId(int id) {
if (id < Daedalus.DNS_SERVERS.size()) { if (id < Daedalus.DNS_SERVERS.size()) {
return id; return id;
} }
for (CustomDNSServer server : Daedalus.configurations.getCustomDNSServers()) { for (CustomDnsServer server : Daedalus.configurations.getCustomDNSServers()) {
if (server.getId().equals(String.valueOf(id))) { if (server.getId().equals(String.valueOf(id))) {
return id; return id;
} }
@ -107,26 +85,26 @@ public class DNSServerHelper {
return 0; return 0;
} }
public static String getAddressById(String id) { public static AbstractDnsServer getServerById(String id) {
for (DNSServer server : Daedalus.DNS_SERVERS) { for (DnsServer server : Daedalus.DNS_SERVERS) {
if (server.getId().equals(id)) { if (server.getId().equals(id)) {
return server.getAddress(); return server;
} }
} }
for (CustomDNSServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) { for (CustomDnsServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) {
if (customDNSServer.getId().equals(id)) { if (customDNSServer.getId().equals(id)) {
return customDNSServer.getAddress(); return customDNSServer;
} }
} }
return Daedalus.DNS_SERVERS.get(0).getAddress(); return Daedalus.DNS_SERVERS.get(0);
} }
public static String[] getIds() { public static String[] getIds() {
ArrayList<String> servers = new ArrayList<>(Daedalus.DNS_SERVERS.size()); ArrayList<String> servers = new ArrayList<>(Daedalus.DNS_SERVERS.size());
for (DNSServer server : Daedalus.DNS_SERVERS) { for (DnsServer server : Daedalus.DNS_SERVERS) {
servers.add(server.getId()); servers.add(server.getId());
} }
for (CustomDNSServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) { for (CustomDnsServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) {
servers.add(customDNSServer.getId()); servers.add(customDNSServer.getId());
} }
String[] stringServers = new String[Daedalus.DNS_SERVERS.size()]; String[] stringServers = new String[Daedalus.DNS_SERVERS.size()];
@ -135,30 +113,30 @@ public class DNSServerHelper {
public static String[] getNames(Context context) { public static String[] getNames(Context context) {
ArrayList<String> servers = new ArrayList<>(Daedalus.DNS_SERVERS.size()); ArrayList<String> servers = new ArrayList<>(Daedalus.DNS_SERVERS.size());
for (DNSServer server : Daedalus.DNS_SERVERS) { for (DnsServer server : Daedalus.DNS_SERVERS) {
servers.add(server.getStringDescription(context)); servers.add(server.getStringDescription(context));
} }
for (CustomDNSServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) { for (CustomDnsServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) {
servers.add(customDNSServer.getName()); servers.add(customDNSServer.getName());
} }
String[] stringServers = new String[Daedalus.DNS_SERVERS.size()]; String[] stringServers = new String[Daedalus.DNS_SERVERS.size()];
return servers.toArray(stringServers); return servers.toArray(stringServers);
} }
public static ArrayList<AbstractDNSServer> getAllServers() { public static ArrayList<AbstractDnsServer> getAllServers() {
ArrayList<AbstractDNSServer> servers = new ArrayList<>(Daedalus.DNS_SERVERS.size()); ArrayList<AbstractDnsServer> servers = new ArrayList<>(Daedalus.DNS_SERVERS.size());
servers.addAll(Daedalus.DNS_SERVERS); servers.addAll(Daedalus.DNS_SERVERS);
servers.addAll(Daedalus.configurations.getCustomDNSServers()); servers.addAll(Daedalus.configurations.getCustomDNSServers());
return servers; return servers;
} }
public static String getDescription(String id, Context context) { public static String getDescription(String id, Context context) {
for (DNSServer server : Daedalus.DNS_SERVERS) { for (DnsServer server : Daedalus.DNS_SERVERS) {
if (server.getId().equals(id)) { if (server.getId().equals(id)) {
return server.getStringDescription(context); return server.getStringDescription(context);
} }
} }
for (CustomDNSServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) { for (CustomDnsServer customDNSServer : Daedalus.configurations.getCustomDNSServers()) {
if (customDNSServer.getId().equals(id)) { if (customDNSServer.getId().equals(id)) {
return customDNSServer.getName(); return customDNSServer.getName();
} }
@ -166,7 +144,7 @@ public class DNSServerHelper {
return Daedalus.DNS_SERVERS.get(0).getStringDescription(context); return Daedalus.DNS_SERVERS.get(0).getStringDescription(context);
} }
public static boolean isInUsing(CustomDNSServer server) { public static boolean isInUsing(CustomDnsServer server) {
return DaedalusVpnService.isActivated() && (server.getId().equals(getPrimary()) || server.getId().equals(getSecondary())); return DaedalusVpnService.isActivated() && (server.getId().equals(getPrimary()) || server.getId().equals(getSecondary()));
} }
} }

View File

@ -4,14 +4,18 @@ import android.app.Notification;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.VpnService; import android.net.VpnService;
import android.os.Build; import android.os.Build;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.system.OsConstants; import android.system.OsConstants;
import android.util.Log; import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
@ -19,9 +23,12 @@ import org.itxtech.daedalus.activity.MainActivity;
import org.itxtech.daedalus.provider.Provider; import org.itxtech.daedalus.provider.Provider;
import org.itxtech.daedalus.provider.ProviderPicker; import org.itxtech.daedalus.provider.ProviderPicker;
import org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver; import org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver;
import org.itxtech.daedalus.server.AbstractDnsServer;
import org.itxtech.daedalus.server.DnsServer;
import org.itxtech.daedalus.server.DnsServerHelper;
import org.itxtech.daedalus.util.DnsServersDetector;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.RuleResolver; import org.itxtech.daedalus.util.RuleResolver;
import org.itxtech.daedalus.util.server.DNSServerHelper;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
@ -51,22 +58,21 @@ public class DaedalusVpnService extends VpnService implements Runnable {
private static final String CHANNEL_ID = "daedalus_channel_1"; private static final String CHANNEL_ID = "daedalus_channel_1";
private static final String CHANNEL_NAME = "daedalus_channel"; private static final String CHANNEL_NAME = "daedalus_channel";
public static String primaryServer; public static AbstractDnsServer primaryServer;
public static String secondaryServer; public static AbstractDnsServer secondaryServer;
private static InetAddress aliasPrimary;
private static InetAddress aliasSecondary;
private NotificationCompat.Builder notification = null; private NotificationCompat.Builder notification = null;
private boolean running = false; private boolean running = false;
private long lastUpdate = 0; private long lastUpdate = 0;
private boolean statisticQuery; private boolean statisticQuery;
private Provider provider; private Provider provider;
private ParcelFileDescriptor descriptor; private ParcelFileDescriptor descriptor;
private Thread mThread = null; private Thread mThread = null;
public HashMap<String, AbstractDnsServer> dnsServers;
public HashMap<String, String> dnsServers;
private static boolean activated = false; private static boolean activated = false;
private static BroadcastReceiver receiver;
public static boolean isActivated() { public static boolean isActivated() {
return activated; return activated;
@ -75,6 +81,44 @@ public class DaedalusVpnService extends VpnService implements Runnable {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
if (Daedalus.getPrefs().getBoolean("settings_use_system_dns", false)) {
registerReceiver(receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateUpstreamServers(context);
}
}, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
private static void updateUpstreamServers(Context context) {
String[] servers = DnsServersDetector.getServers(context);
if (servers != null) {
if (servers.length >= 2 && (aliasPrimary == null || !aliasPrimary.getHostAddress().equals(servers[0])) &&
(aliasSecondary == null || !aliasSecondary.getHostAddress().equals(servers[0])) &&
(aliasPrimary == null || !aliasPrimary.getHostAddress().equals(servers[1])) &&
(aliasSecondary == null || !aliasSecondary.getHostAddress().equals(servers[1]))) {
primaryServer.setAddress(servers[0]);
primaryServer.setPort(DnsServer.DNS_SERVER_DEFAULT_PORT);
secondaryServer.setAddress(servers[1]);
secondaryServer.setPort(DnsServer.DNS_SERVER_DEFAULT_PORT);
} else if ((aliasPrimary == null || !aliasPrimary.getHostAddress().equals(servers[0])) &&
(aliasSecondary == null || !aliasSecondary.getHostAddress().equals(servers[0]))) {
primaryServer.setAddress(servers[0]);
primaryServer.setPort(DnsServer.DNS_SERVER_DEFAULT_PORT);
secondaryServer.setAddress(servers[0]);
secondaryServer.setPort(DnsServer.DNS_SERVER_DEFAULT_PORT);
} else {
StringBuilder buf = new StringBuilder();
for (String server : servers) {
buf.append(server).append(" ");
}
Logger.error("Invalid upstream DNS " + buf);
}
Logger.info("Upstream DNS updated: " + primaryServer.getAddress() + " " + secondaryServer.getAddress());
} else {
Logger.error("Cannot obtain upstream DNS server!");
}
} }
@Override @Override
@ -84,7 +128,6 @@ public class DaedalusVpnService extends VpnService implements Runnable {
case ACTION_ACTIVATE: case ACTION_ACTIVATE:
activated = true; activated = true;
if (Daedalus.getPrefs().getBoolean("settings_notification", true)) { if (Daedalus.getPrefs().getBoolean("settings_notification", true)) {
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder; NotificationCompat.Builder builder;
@ -126,12 +169,7 @@ public class DaedalusVpnService extends VpnService implements Runnable {
} }
Daedalus.initRuleResolver(); Daedalus.initRuleResolver();
startThread();
if (this.mThread == null) {
this.mThread = new Thread(this, "DaedalusVpn");
this.running = true;
this.mThread.start();
}
Daedalus.updateShortcut(getApplicationContext()); Daedalus.updateShortcut(getApplicationContext());
if (MainActivity.getInstance() != null) { if (MainActivity.getInstance() != null) {
MainActivity.getInstance().startActivity(new Intent(getApplicationContext(), MainActivity.class) MainActivity.getInstance().startActivity(new Intent(getApplicationContext(), MainActivity.class)
@ -146,9 +184,21 @@ public class DaedalusVpnService extends VpnService implements Runnable {
return START_NOT_STICKY; return START_NOT_STICKY;
} }
private void startThread() {
if (this.mThread == null) {
this.mThread = new Thread(this, "DaedalusVpn");
this.running = true;
this.mThread.start();
}
}
@Override @Override
public void onDestroy() { public void onDestroy() {
stopThread(); stopThread();
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
} }
private void stopThread() { private void stopThread() {
@ -185,7 +235,7 @@ public class DaedalusVpnService extends VpnService implements Runnable {
if (shouldRefresh) { if (shouldRefresh) {
RuleResolver.clear(); RuleResolver.clear();
DNSServerHelper.clearCache(); DnsServerHelper.clearCache();
Logger.info("Daedalus VPN service has stopped"); Logger.info("Daedalus VPN service has stopped");
} }
@ -202,27 +252,30 @@ public class DaedalusVpnService extends VpnService implements Runnable {
stopThread(); stopThread();
} }
private InetAddress addDnsServer(Builder builder, String format, byte[] ipv6Template, String addr) throws UnknownHostException { private InetAddress addDnsServer(Builder builder, String format, byte[] ipv6Template, AbstractDnsServer addr)
throws UnknownHostException {
int size = dnsServers.size(); int size = dnsServers.size();
size++; size++;
if (addr.contains("/")) {//https uri if (addr.getAddress().contains("/")) {//https uri
String alias = String.format(format, size + 1); String alias = String.format(format, size + 1);
dnsServers.put(alias, addr); dnsServers.put(alias, addr);
builder.addRoute(alias, 32); builder.addRoute(alias, 32);
return InetAddress.getByName(alias); return InetAddress.getByName(alias);
} }
InetAddress address = InetAddress.getByName(addr); InetAddress address = InetAddress.getByName(addr.getAddress());
if (address instanceof Inet6Address && ipv6Template == null) { if (address instanceof Inet6Address && ipv6Template == null) {
Log.i(TAG, "addDnsServer: Ignoring DNS server " + address); Log.i(TAG, "addDnsServer: Ignoring DNS server " + address);
} else if (address instanceof Inet4Address) { } else if (address instanceof Inet4Address) {
String alias = String.format(format, size + 1); String alias = String.format(format, size + 1);
dnsServers.put(alias, address.getHostAddress()); addr.setHostAddress(address.getHostAddress());
dnsServers.put(alias, addr);
builder.addRoute(alias, 32); builder.addRoute(alias, 32);
return InetAddress.getByName(alias); return InetAddress.getByName(alias);
} else if (address instanceof Inet6Address) { } else if (address instanceof Inet6Address) {
ipv6Template[ipv6Template.length - 1] = (byte) (size + 1); ipv6Template[ipv6Template.length - 1] = (byte) (size + 1);
InetAddress i6addr = Inet6Address.getByAddress(ipv6Template); InetAddress i6addr = Inet6Address.getByAddress(ipv6Template);
dnsServers.put(i6addr.getHostAddress(), address.getHostAddress()); addr.setHostAddress(address.getHostAddress());
dnsServers.put(i6addr.getHostAddress(), addr);
return i6addr; return i6addr;
} }
return null; return null;
@ -231,14 +284,13 @@ public class DaedalusVpnService extends VpnService implements Runnable {
@Override @Override
public void run() { public void run() {
try { try {
DNSServerHelper.buildCache(); DnsServerHelper.buildCache();
Builder builder = new Builder() Builder builder = new Builder()
.setSession("Daedalus") .setSession("Daedalus")
.setConfigureIntent(PendingIntent.getActivity(this, 0, .setConfigureIntent(PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class).putExtra(MainActivity.LAUNCH_FRAGMENT, MainActivity.FRAGMENT_SETTINGS), new Intent(this, MainActivity.class).putExtra(MainActivity.LAUNCH_FRAGMENT, MainActivity.FRAGMENT_SETTINGS),
PendingIntent.FLAG_ONE_SHOT)); PendingIntent.FLAG_ONE_SHOT));
//Set App Filter
if (Daedalus.getPrefs().getBoolean("settings_app_filter_switch", false)) { if (Daedalus.getPrefs().getBoolean("settings_app_filter_switch", false)) {
ArrayList<String> apps = Daedalus.configurations.getAppObjects(); ArrayList<String> apps = Daedalus.configurations.getAppObjects();
if (apps.size() > 0) { if (apps.size() > 0) {
@ -275,36 +327,28 @@ public class DaedalusVpnService extends VpnService implements Runnable {
statisticQuery = Daedalus.getPrefs().getBoolean("settings_count_query_times", false); statisticQuery = Daedalus.getPrefs().getBoolean("settings_count_query_times", false);
byte[] ipv6Template = new byte[]{32, 1, 13, (byte) (184 & 0xFF), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte[] ipv6Template = new byte[]{32, 1, 13, (byte) (184 & 0xFF), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if (primaryServer.contains(":") || secondaryServer.contains(":")) {//IPv6 try {
try { InetAddress addr = Inet6Address.getByAddress(ipv6Template);
InetAddress addr = Inet6Address.getByAddress(ipv6Template); Log.d(TAG, "configure: Adding IPv6 address" + addr);
Log.d(TAG, "configure: Adding IPv6 address" + addr); builder.addAddress(addr, 120);
builder.addAddress(addr, 120); } catch (Exception e) {
} catch (Exception e) { Logger.logException(e);
Logger.logException(e);
ipv6Template = null;
}
} else {
ipv6Template = null; ipv6Template = null;
} }
InetAddress aliasPrimary;
InetAddress aliasSecondary;
if (advanced) { if (advanced) {
dnsServers = new HashMap<>(); dnsServers = new HashMap<>();
aliasPrimary = addDnsServer(builder, format, ipv6Template, primaryServer); aliasPrimary = addDnsServer(builder, format, ipv6Template, primaryServer);
aliasSecondary = addDnsServer(builder, format, ipv6Template, secondaryServer); aliasSecondary = addDnsServer(builder, format, ipv6Template, secondaryServer);
} else { } else {
aliasPrimary = InetAddress.getByName(primaryServer); aliasPrimary = InetAddress.getByName(primaryServer.getAddress());
aliasSecondary = InetAddress.getByName(secondaryServer); aliasSecondary = InetAddress.getByName(secondaryServer.getAddress());
} }
InetAddress primaryDNSServer = aliasPrimary; Logger.info("Daedalus VPN service is listening on " + primaryServer.getAddress() + " as " + aliasPrimary.getHostAddress());
InetAddress secondaryDNSServer = aliasSecondary; Logger.info("Daedalus VPN service is listening on " + secondaryServer.getAddress() + " as " + aliasSecondary.getHostAddress());
Logger.info("Daedalus VPN service is listening on " + primaryServer + " as " + primaryDNSServer.getHostAddress()); builder.addDnsServer(aliasPrimary).addDnsServer(aliasSecondary);
Logger.info("Daedalus VPN service is listening on " + secondaryServer + " as " + secondaryDNSServer.getHostAddress());
builder.addDnsServer(primaryDNSServer).addDnsServer(secondaryDNSServer);
if (advanced) { if (advanced) {
builder.setBlocking(true); builder.setBlocking(true);
@ -324,13 +368,17 @@ public class DaedalusVpnService extends VpnService implements Runnable {
Thread.sleep(1000); Thread.sleep(1000);
} }
} }
} catch ( } catch (InterruptedException ignored) {
InterruptedException ignored) { } catch (Exception e) {
} catch ( MainActivity.getInstance().runOnUiThread(() ->
Exception e) { new AlertDialog.Builder(MainActivity.getInstance())
.setTitle(R.string.error_occurred)
.setMessage(Logger.getExceptionMessage(e))
.setPositiveButton(android.R.string.ok, (d, id) -> {
})
.show());
Logger.logException(e); Logger.logException(e);
} finally { } finally {
Log.d(TAG, "quit");
stopThread(); stopThread();
} }
} }
@ -346,14 +394,13 @@ public class DaedalusVpnService extends VpnService implements Runnable {
if (time - lastUpdate >= 1000) { if (time - lastUpdate >= 1000) {
lastUpdate = time; lastUpdate = time;
if (notification != null) { if (notification != null) {
notification.setContentTitle(getResources().getString(R.string.notice_queries) + " " + String.valueOf(provider.getDnsQueryTimes())); notification.setContentTitle(getResources().getString(R.string.notice_queries) + " " + provider.getDnsQueryTimes());
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(NOTIFICATION_ACTIVATED, notification.build()); manager.notify(NOTIFICATION_ACTIVATED, notification.build());
} }
} }
} }
public static class VpnNetworkException extends Exception { public static class VpnNetworkException extends Exception {
public VpnNetworkException(String s) { public VpnNetworkException(String s) {
super(s); super(s);
@ -362,7 +409,5 @@ public class DaedalusVpnService extends VpnService implements Runnable {
public VpnNetworkException(String s, Throwable t) { public VpnNetworkException(String s, Throwable t) {
super(s, t); super(s, t);
} }
} }
} }

View File

@ -3,7 +3,7 @@ package org.itxtech.daedalus.util;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.util.server.CustomDNSServer; import org.itxtech.daedalus.server.CustomDnsServer;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
@ -27,7 +27,7 @@ public class Configurations {
private static File file; private static File file;
private ArrayList<CustomDNSServer> customDNSServers; private ArrayList<CustomDnsServer> customDNSServers;
private ArrayList<String> appObjects; private ArrayList<String> appObjects;
private ArrayList<Rule> hostsRules; private ArrayList<Rule> hostsRules;
@ -60,7 +60,7 @@ public class Configurations {
this.activateCounter = activateCounter; this.activateCounter = activateCounter;
} }
public ArrayList<CustomDNSServer> getCustomDNSServers() { public ArrayList<CustomDnsServer> getCustomDNSServers() {
if (customDNSServers == null) { if (customDNSServers == null) {
customDNSServers = new ArrayList<>(); customDNSServers = new ArrayList<>();
} }

View File

@ -0,0 +1,166 @@
package org.itxtech.daedalus.util;
import android.content.Context;
import android.net.*;
import android.os.Build;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Daedalus Project
*
* @author iTX Technologies
* @link https://itxtech.org
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
public class DnsServersDetector {
//https://stackoverflow.com/a/48973823
private static final String METHOD_EXEC_PROP_DELIM = "]: [";
public static String[] getServers(Context context) {
String[] result;
result = getServersMethodSystemProperties();
if (result != null && result.length > 0) {
return result;
}
result = getServersMethodConnectivityManager(context);
if (result != null && result.length > 0) {
return result;
}
result = getServersMethodExec();
if (result != null && result.length > 0) {
return result;
}
return null;
}
private static String[] getServersMethodConnectivityManager(Context context) {
ArrayList<String> priorityServersArrayList = new ArrayList<>();
ArrayList<String> serversArrayList = new ArrayList<>();
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
for (Network network : connectivityManager.getAllNetworks()) {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
if (networkInfo.isConnected()) {
LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
List<InetAddress> dnsServersList = linkProperties.getDnsServers();
if (linkPropertiesHasDefaultRoute(linkProperties)) {
for (InetAddress element : dnsServersList) {
String dnsHost = element.getHostAddress();
priorityServersArrayList.add(dnsHost);
}
} else {
for (InetAddress element : dnsServersList) {
String dnsHost = element.getHostAddress();
serversArrayList.add(dnsHost);
}
}
}
}
}
if (priorityServersArrayList.isEmpty()) {
priorityServersArrayList.addAll(serversArrayList);
}
if (priorityServersArrayList.size() > 0) {
return priorityServersArrayList.toArray(new String[0]);
}
return null;
}
private static String[] getServersMethodSystemProperties() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
String re1 = "^\\d+(\\.\\d+){3}$";
String re2 = "^[0-9a-f]+(:[0-9a-f]*)+:[0-9a-f]+$";
ArrayList<String> serversArrayList = new ArrayList<>();
try {
Class SystemProperties = Class.forName("android.os.SystemProperties");
Method method = SystemProperties.getMethod("get", new Class[]{String.class});
String[] netdns = new String[]{"net.dns1", "net.dns2", "net.dns3", "net.dns4"};
for (String dns : netdns) {
Object[] args = new Object[]{dns};
String v = (String) method.invoke(null, args);
if (v != null && (v.matches(re1) || v.matches(re2)) && !serversArrayList.contains(v)) {
serversArrayList.add(v);
}
}
if (serversArrayList.size() > 0) {
return serversArrayList.toArray(new String[0]);
}
} catch (Exception ex) {
Logger.logException(ex);
}
}
return null;
}
private static String[] getServersMethodExec() {
try {
Process process = Runtime.getRuntime().exec("getprop");
InputStream inputStream = process.getInputStream();
LineNumberReader lineNumberReader = new LineNumberReader(new InputStreamReader(inputStream));
Set<String> serversSet = methodExecParseProps(lineNumberReader);
if (serversSet.size() > 0) {
return serversSet.toArray(new String[0]);
}
} catch (Exception ex) {
Logger.logException(ex);
}
return null;
}
private static Set<String> methodExecParseProps(BufferedReader lineNumberReader) throws Exception {
String line;
HashSet<String> serversSet = new HashSet<>();
while ((line = lineNumberReader.readLine()) != null) {
int split = line.indexOf(METHOD_EXEC_PROP_DELIM);
if (split == -1) {
continue;
}
String property = line.substring(1, split);
int valueStart = split + METHOD_EXEC_PROP_DELIM.length();
int valueEnd = line.length() - 1;
if (valueEnd < valueStart) {
continue;
}
String value = line.substring(valueStart, valueEnd);
if (value.isEmpty()) {
continue;
}
if (property.endsWith(".dns") || property.endsWith(".dns1") || property.endsWith(".dns2") ||
property.endsWith(".dns3") || property.endsWith(".dns4")) {
InetAddress ip = InetAddress.getByName(value);
if (ip == null) {
continue;
}
value = ip.getHostAddress();
if (value == null || value.length() == 0) {
continue;
}
serversSet.add(value);
}
}
return serversSet;
}
private static boolean linkPropertiesHasDefaultRoute(LinkProperties linkProperties) {
for (RouteInfo route : linkProperties.getRoutes()) {
if (route.isDefaultRoute()) {
return true;
}
}
return false;
}
}

View File

@ -1,7 +1,7 @@
package org.itxtech.daedalus.widget; package org.itxtech.daedalus.widget;
import android.content.Context; import android.content.Context;
import android.preference.ListPreference; import androidx.preference.ListPreference;
import android.util.AttributeSet; import android.util.AttributeSet;
/** /**

View File

@ -25,7 +25,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"> app:layout_behavior="@string/appbar_scrolling_view_behavior">
</androidx.recyclerview.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,32 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"> android:gravity="center_vertical">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/app_icon" android:id="@+id/app_icon"
android:layout_width="46dp" android:layout_width="46dp"
android:layout_height="46dp" android:layout_height="46dp"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:paddingLeft="14dp" android:paddingStart="14dp"/>
android:paddingRight="10dp"
android:paddingStart="14dp" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/app_name" android:id="@+id/app_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.0" /> android:layout_weight="1.0"/>
<androidx.appcompat.widget.AppCompatCheckBox <androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/app_check" android:id="@+id/app_check"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="false" android:clickable="false"
android:paddingEnd="6dp" android:paddingEnd="6dp"
android:paddingLeft="2dp" android:paddingStart="2dp"/>
android:paddingRight="6dp"
android:paddingStart="2dp" />
</LinearLayout> </LinearLayout>

View File

@ -14,47 +14,39 @@
app:cardPreventCornerOverlap="true" app:cardPreventCornerOverlap="true"
android:id="@+id/cardView_indicator"> android:id="@+id/cardView_indicator">
<LinearLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" android:focusable="true"
android:orientation="vertical" android:orientation="vertical"
android:background="?android:attr/selectableItemBackground"> android:background="?android:attr/selectableItemBackground"
<RelativeLayout android:layout_marginStart="@dimen/margin_small">
<TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_small" android:padding="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_small"> android:id="@+id/textView_rule_name"
android:textAppearance="?android:attr/textAppearanceLarge"
<TextView android:layout_alignParentTop="true"
android:layout_width="match_parent" android:layout_alignParentStart="true"/>
android:layout_height="wrap_content" <TextView
android:padding="@dimen/margin_small" android:layout_width="match_parent"
android:id="@+id/textView_rule_name" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" android:layout_below="@+id/textView_rule_name"
android:layout_alignParentTop="true" android:padding="@dimen/margin_small"
android:layout_alignParentLeft="true" android:id="@+id/textView_rule_detail"
android:layout_alignParentStart="true"/> android:textAppearance="?android:attr/textAppearanceSmall"
<TextView android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_alignParentStart="true"/>
android:layout_height="wrap_content" <TextView
android:layout_below="@+id/textView_rule_name" android:id="@+id/textView_rule_size"
android:padding="@dimen/margin_small" android:layout_width="wrap_content"
android:id="@+id/textView_rule_detail" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" android:layout_gravity="bottom"
android:layout_alignParentBottom="true" android:padding="@dimen/margin_small"
android:layout_alignParentLeft="true" android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"/> android:ellipsize="end"
<TextView android:id="@+id/textView_rule_size" android:textAppearance="?android:attr/textAppearanceSmall"/>
android:layout_width="wrap_content" </RelativeLayout>
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="@dimen/margin_small"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
</FrameLayout> </FrameLayout>

View File

@ -5,6 +5,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:clickable="true" android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground" android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="10dp" app:cardCornerRadius="10dp"
app:cardPreventCornerOverlap="true" app:cardPreventCornerOverlap="true"
@ -23,7 +24,6 @@
android:id="@+id/textView_custom_dns_name" android:id="@+id/textView_custom_dns_name"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/> android:layout_alignParentStart="true"/>
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -34,8 +34,7 @@
android:id="@+id/textView_custom_dns_address" android:id="@+id/textView_custom_dns_address"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/> android:layout_alignParentStart="true"/>
</RelativeLayout> </RelativeLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

View File

@ -11,7 +11,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="horizontal" android:scrollbars="horizontal"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/> android:layout_alignParentStart="true"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@ -23,4 +22,4 @@
android:src="@drawable/ic_note_add" android:src="@drawable/ic_note_add"
android:tint="#FFFFFF"/> android:tint="#FFFFFF"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -41,18 +41,15 @@
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:id="@+id/button_start_test" android:id="@+id/button_start_test"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"/>
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/button_start_test" android:layout_below="@+id/button_start_test"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:id="@+id/textView_test_info" android:id="@+id/textView_test_info"
android:textIsSelectable="true" android:textIsSelectable="true"
android:textSize="18sp"/> android:textSize="18sp"/>
</RelativeLayout> </RelativeLayout>
</ScrollView> </ScrollView>

View File

@ -13,7 +13,6 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="org.itxtech.daedalus.fragment.HomeFragment"> tools:context="org.itxtech.daedalus.fragment.HomeFragment">
<ImageView <ImageView
android:contentDescription="icon"
android:id="@+id/imageView_icon" android:id="@+id/imageView_icon"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
@ -21,7 +20,7 @@
app:srcCompat="@mipmap/ic_launcher" app:srcCompat="@mipmap/ic_launcher"
app:layout_widthPercent="40%" app:layout_widthPercent="40%"
app:layout_heightPercent="20%" app:layout_heightPercent="20%"
app:layout_marginTopPercent="5%" app:layout_marginTopPercent="10%"
android:layout_alignParentTop="true" android:layout_centerHorizontal="true"/> android:layout_alignParentTop="true" android:layout_centerHorizontal="true"/>
<TextView <TextView
android:text="@string/app_name" android:text="@string/app_name"
@ -33,21 +32,12 @@
android:textAppearance="@android:style/TextAppearance.DeviceDefault" android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:fontFamily="sans-serif" android:fontFamily="sans-serif"
android:layout_centerHorizontal="true" android:id="@+id/textView_app_name"/> android:layout_centerHorizontal="true" android:id="@+id/textView_app_name"/>
<TextView
android:text="@string/notice_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView_notice"
app:layout_marginTopPercent="5%"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:fontFamily="sans-serif"
android:layout_below="@+id/textView_app_name" android:layout_centerHorizontal="true"/>
<Button <Button
android:text="@string/button_text_activate" android:text="@string/button_text_activate"
android:textSize="15sp" android:textSize="15sp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/button_activate" android:id="@+id/button_activate"
app:layout_marginTopPercent="10%" app:layout_marginTopPercent="15%"
android:layout_alignTop="@+id/textView_notice" android:layout_centerHorizontal="true"/> android:layout_alignTop="@+id/textView_app_name" android:layout_centerHorizontal="true"/>
</androidx.percentlayout.widget.PercentRelativeLayout> </androidx.percentlayout.widget.PercentRelativeLayout>

View File

@ -11,7 +11,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="horizontal" android:scrollbars="horizontal"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/> android:layout_alignParentStart="true"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
@ -23,4 +22,4 @@
android:src="@drawable/ic_note_add" android:src="@drawable/ic_note_add"
android:tint="#FFFFFF"/> android:tint="#FFFFFF"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,20 +0,0 @@
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
</style>
<style name="AppTheme.NoActionBar.TransparentStatusBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppTheme.Dark.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
</style>
<style name="AppTheme.Dark.NoActionBar.TransparentStatusBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>

View File

@ -3,7 +3,6 @@
<string name="app_name">Daedalus</string> <string name="app_name">Daedalus</string>
<string name="quick_toggle">开关</string> <string name="quick_toggle">开关</string>
<string name="notice_main">世界很大,我要去看看。</string>
<string name="notice_activated">已启用 iTXTech Daedalus。</string> <string name="notice_activated">已启用 iTXTech Daedalus。</string>
<string name="notice_start_test">正在测试指定的 DNS 服务器……</string> <string name="notice_start_test">正在测试指定的 DNS 服务器……</string>
<string name="notice_queries">DNS 查询次数:</string> <string name="notice_queries">DNS 查询次数:</string>
@ -63,9 +62,11 @@
<string name="settings_manual_summary">访问 GitHub wiki 页面。</string> <string name="settings_manual_summary">访问 GitHub wiki 页面。</string>
<string name="settings_log_size">日志大小限制</string> <string name="settings_log_size">日志大小限制</string>
<string name="settings_debug_output">调试输出</string> <string name="settings_debug_output">调试输出</string>
<string name="settings_dont_build_doh_cache">不缓存 DoH DNS 的 IP地址</string> <string name="settings_dont_build_cache">不缓存 DNS 的 IP地址</string>
<string name="settings_dark_theme">使用暗主题</string> <string name="settings_dark_theme">使用暗主题</string>
<string name="settings_dns_query_method">DNS 查询方式</string> <string name="settings_dns_query_method">DNS 查询方式</string>
<string name="settings_foreground">运行前台服务</string>
<string name="settings_use_system_dns">使用系統DNS作為上游DNS</string>
<string name="settings_rule_name">规则名称</string> <string name="settings_rule_name">规则名称</string>
<string name="settings_rule_type">规则类型</string> <string name="settings_rule_type">规则类型</string>
@ -103,4 +104,6 @@
<string name="test_test_domain">google.com</string> <string name="test_test_domain">google.com</string>
<string name="nav_version">版本:</string> <string name="nav_version">版本:</string>
<string name="error_occurred">启动时出现了一个错误</string>
</resources> </resources>

View File

@ -3,7 +3,6 @@
<string name="app_name">Daedalus</string> <string name="app_name">Daedalus</string>
<string name="quick_toggle">开关</string> <string name="quick_toggle">开关</string>
<string name="notice_main">世界很大,我要去看看。</string>
<string name="notice_activated">已啟動 iTXTech Daedalus。</string> <string name="notice_activated">已啟動 iTXTech Daedalus。</string>
<string name="notice_start_test">正在測試指定的 DNS 伺服器……</string> <string name="notice_start_test">正在測試指定的 DNS 伺服器……</string>
<string name="notice_queries">DNS 查詢次數:</string> <string name="notice_queries">DNS 查詢次數:</string>
@ -63,7 +62,7 @@
<string name="settings_manual_summary">造訪 GitHub wiki 頁面。</string> <string name="settings_manual_summary">造訪 GitHub wiki 頁面。</string>
<string name="settings_log_size">紀錄檔大小限制</string> <string name="settings_log_size">紀錄檔大小限制</string>
<string name="settings_debug_output">调试输出 TODO</string> <string name="settings_debug_output">调试输出 TODO</string>
<string name="settings_dont_build_doh_cache">不緩存 DoH DNS 的 IP地址</string> <string name="settings_dont_build_cache">不緩存 DNS 的 IP地址</string>
<string name="settings_dark_theme">使用暗主题</string> <string name="settings_dark_theme">使用暗主题</string>
<string name="settings_rule_name">規則名稱</string> <string name="settings_rule_name">規則名稱</string>
@ -76,6 +75,7 @@
<string name="settings_rule_import_built_in">内置</string> <string name="settings_rule_import_built_in">内置</string>
<string name="settings_rule_import_external">外部</string> <string name="settings_rule_import_external">外部</string>
<string name="settings_dns_query_method">DNS 查询方式</string> <string name="settings_dns_query_method">DNS 查询方式</string>
<string name="settings_foreground">運行前臺服務</string>
<string name="settings_server_name">伺服器名稱</string> <string name="settings_server_name">伺服器名稱</string>
<string name="settings_server_address">伺服器網址</string> <string name="settings_server_address">伺服器網址</string>
@ -101,4 +101,6 @@
<string name="test_test_domain">google.com</string> <string name="test_test_domain">google.com</string>
<string name="nav_version">版本:</string> <string name="nav_version">版本:</string>
<string name="error_occurred">啟動時出現了一個錯誤</string>
</resources> </resources>

View File

@ -2,7 +2,6 @@
<string name="app_name">Daedalus</string> <string name="app_name">Daedalus</string>
<string name="quick_toggle">Toggle</string> <string name="quick_toggle">Toggle</string>
<string name="notice_main">See the world outside.</string>
<string name="notice_activated">iTXTech Daedalus is activated.</string> <string name="notice_activated">iTXTech Daedalus is activated.</string>
<string name="notice_start_test">Testing specified DNS server…</string> <string name="notice_start_test">Testing specified DNS server…</string>
<string name="notice_queries">DNS query times:</string> <string name="notice_queries">DNS query times:</string>
@ -61,10 +60,12 @@
<string name="settings_log_size">Log Size Limit</string> <string name="settings_log_size">Log Size Limit</string>
<string name="settings_manual">Manual</string> <string name="settings_manual">Manual</string>
<string name="settings_manual_summary">Visit GitHub wiki page.</string> <string name="settings_manual_summary">Visit GitHub wiki page.</string>
<string name="settings_dont_build_doh_cache">Don\'t build DNS Cache for DoH DNS</string> <string name="settings_dont_build_cache">Don\'t cache IP for DNS servers</string>
<string name="settings_debug_output">Debug Output</string> <string name="settings_debug_output">Debug Output</string>
<string name="settings_dark_theme">Use Dark Theme</string> <string name="settings_dark_theme">Use Dark Theme</string>
<string name="settings_dns_query_method">DNS Query Method</string> <string name="settings_dns_query_method">DNS Query Method</string>
<string name="settings_foreground">Run service in Foreground</string>
<string name="settings_use_system_dns">Use System DNS as upstream DNS</string>
<string name="settings_dns_tcp">TCP</string> <string name="settings_dns_tcp">TCP</string>
<string name="settings_dns_udp">UDP</string> <string name="settings_dns_udp">UDP</string>
@ -111,4 +112,6 @@
<string name="nav_version">Version:</string> <string name="nav_version">Version:</string>
<string name="nav_git_commit">Git commit:</string> <string name="nav_git_commit">Git commit:</string>
<string name="nav_github">GitHub</string> <string name="nav_github">GitHub</string>
<string name="error_occurred">An error occurred at startup</string>
</resources> </resources>

View File

@ -1,8 +1,5 @@
<resources> <resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
@ -12,15 +9,25 @@
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorPrimaryLight</item> <item name="colorAccent">@color/colorPrimaryLight</item>
</style> </style>
<style name="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
</style> </style>
<style name="AppTheme.Dark.NoActionBar"> <style name="AppTheme.Dark.NoActionBar" parent="AppTheme.Dark">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
</style> </style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
<style name="AppTheme.NoActionBar.TransparentStatusBar" parent="AppTheme.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppTheme.Dark.NoActionBar.TransparentStatusBar" parent="AppTheme.Dark.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources> </resources>

View File

@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference <EditTextPreference
android:key="ruleName" android:key="ruleName"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
android:singleLine="true" android:singleLine="true"
android:title="@string/settings_rule_name"/> android:title="@string/settings_rule_name"/>
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="rulSettings" android:key="rulSettings"
android:title="@string/settings_rule"> android:title="@string/settings_rule">
<ListPreference <ListPreference
@ -27,7 +30,9 @@
android:key="ruleSync" android:key="ruleSync"
android:title="@string/settings_rule_sync"/> android:title="@string/settings_rule_sync"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="Import" android:key="Import"
android:title="@string/settings_rule_import"> android:title="@string/settings_rule_import">
<ListPreference <ListPreference
@ -37,4 +42,4 @@
android:key="ruleImportExternal" android:key="ruleImportExternal"
android:title="@string/settings_rule_import_external"/> android:title="@string/settings_rule_import_external"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </androidx.preference.PreferenceScreen>

View File

@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference <EditTextPreference
android:key="serverName" android:key="serverName"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
android:singleLine="true" android:singleLine="true"
android:title="@string/settings_server_name"/> android:title="@string/settings_server_name"/>
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="serverSettings" android:key="serverSettings"
android:title="@string/settings_server"> android:title="@string/settings_server">
<EditTextPreference <EditTextPreference
@ -20,4 +23,4 @@
android:numeric="integer" android:numeric="integer"
android:title="@string/settings_server_port"/> android:title="@string/settings_server_port"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </androidx.preference.PreferenceScreen>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="settingsServer" android:key="settingsServer"
android:title="@string/settings_server"> android:title="@string/settings_server">
@ -10,7 +11,6 @@
android:title="@string/primary_server" android:title="@string/primary_server"
android:defaultValue="0"> android:defaultValue="0">
</ListPreference> </ListPreference>
<ListPreference <ListPreference
android:key="secondary_server" android:key="secondary_server"
android:title="@string/secondary_server" android:title="@string/secondary_server"
@ -23,7 +23,9 @@
android:singleLine="true" android:singleLine="true"
android:title="@string/settings_dns_test_servers"/> android:title="@string/settings_dns_test_servers"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="settings_system" android:key="settings_system"
android:title="@string/settings_system"> android:title="@string/settings_system">
@ -39,6 +41,10 @@
android:key="settings_dark_theme" android:key="settings_dark_theme"
android:title="@string/settings_dark_theme" android:title="@string/settings_dark_theme"
android:defaultValue="false"/> android:defaultValue="false"/>
<SwitchPreference
android:key="settings_foreground"
android:title="@string/settings_foreground"
android:defaultValue="false"/>
<EditTextPreference <EditTextPreference
android:key="settings_log_size" android:key="settings_log_size"
android:selectAllOnFocus="false" android:selectAllOnFocus="false"
@ -49,25 +55,27 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:key="settings_app_filter" app:iconSpaceReserved="false"
android:title="@string/settings_app_filter"> android:key="settings_app_filter"
android:title="@string/settings_app_filter">
<SwitchPreference <SwitchPreference
android:key="settings_app_filter_switch" android:key="settings_app_filter_switch"
android:title="@string/settings_app_filter" android:title="@string/settings_app_filter"
android:defaultValue="false"/> android:defaultValue="false"/>
<SwitchPreference <SwitchPreference
android:key="settings_app_filter_mode_switch" android:key="settings_app_filter_mode_switch"
android:title="@string/settings_app_filter_mode" android:title="@string/settings_app_filter_mode"
android:defaultValue="false" android:defaultValue="false"
android:enabled="false"/> android:enabled="false"/>
<org.itxtech.daedalus.widget.ClickPreference <org.itxtech.daedalus.widget.ClickPreference
android:key="settings_app_filter_list" android:key="settings_app_filter_list"
android:title="@string/settings_app_filter_list" android:title="@string/settings_app_filter_list"
android:summary="@string/settings_app_filter_list_summary" android:summary="@string/settings_app_filter_list_summary"
android:enabled="false"/> android:enabled="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="settings_advanced" android:key="settings_advanced"
android:title="@string/settings_advanced"> android:title="@string/settings_advanced">
<SwitchPreference <SwitchPreference
@ -80,10 +88,14 @@
android:defaultValue="false" android:defaultValue="false"
android:enabled="false"/> android:enabled="false"/>
<SwitchPreference <SwitchPreference
android:key="settings_dont_build_doh_cache" android:key="settings_dont_build_cache"
android:title="@string/settings_dont_build_doh_cache" android:title="@string/settings_dont_build_cache"
android:defaultValue="false" android:defaultValue="false"
android:enabled="false"/> android:enabled="false"/>
<SwitchPreference
android:key="settings_use_system_dns"
android:title="@string/settings_use_system_dns"
android:defaultValue="false"/>
<ListPreference <ListPreference
android:key="settings_dns_query_method" android:key="settings_dns_query_method"
android:title="@string/settings_dns_query_method" android:title="@string/settings_dns_query_method"
@ -100,6 +112,7 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
app:iconSpaceReserved="false"
android:key="settings_help" android:key="settings_help"
android:title="@string/settings_help_and_support"> android:title="@string/settings_help_and_support">
<org.itxtech.daedalus.widget.ClickPreference <org.itxtech.daedalus.widget.ClickPreference
@ -118,4 +131,4 @@
android:title="@string/settings_manual" android:title="@string/settings_manual"
android:summary="@string/settings_manual_summary"/> android:summary="@string/settings_manual_summary"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </androidx.preference.PreferenceScreen>

Binary file not shown.

View File

@ -1,6 +1,5 @@
#Wed Aug 23 01:02:45 CST 2017
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-5.5.1-bin.zip

225
gradlew vendored
View File

@ -1,5 +1,21 @@
#!/usr/bin/env sh #!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## ##
## Gradle start up script for UN*X ## Gradle start up script for UN*X
@ -10,38 +26,38 @@
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" PRG="$0"
# Need this for relative symlinks. # Need this for relative symlinks.
while [ -h "$PRG" ] ; do while [ -h "$PRG" ]; do
ls=`ls -ld "$PRG"` ls=$(ls -ld "$PRG")
link=`expr "$ls" : '.*-> \(.*\)$'` link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' > /dev/null; then if expr "$link" : '/.*' >/dev/null; then
PRG="$link" PRG="$link"
else else
PRG=`dirname "$PRG"`"/$link" PRG=$(dirname "$PRG")"/$link"
fi fi
done done
SAVED="`pwd`" SAVED="$(pwd)"
cd "`dirname \"$PRG\"`/" >/dev/null cd "$(dirname \"$PRG\")/" >/dev/null
APP_HOME="`pwd -P`" APP_HOME="$(pwd -P)"
cd "$SAVED" >/dev/null cd "$SAVED" >/dev/null
APP_NAME="Gradle" APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=$(basename "$0")
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="" DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
warn ( ) { warn() {
echo "$*" echo "$*"
} }
die ( ) { die() {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} }
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
@ -49,124 +65,119 @@ cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false nonstop=false
case "`uname`" in case "$(uname)" in
CYGWIN* ) CYGWIN*)
cygwin=true cygwin=true
;; ;;
Darwin* ) Darwin*)
darwin=true darwin=true
;; ;;
MINGW* ) MINGW*)
msys=true msys=true
;; ;;
NONSTOP* ) NONSTOP*)
nonstop=true nonstop=true
;; ;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java" JAVACMD="$JAVA_HOME/jre/sh/java"
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD="$JAVA_HOME/bin/java"
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ]; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD="java" JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then
MAX_FD_LIMIT=`ulimit -H -n` MAX_FD_LIMIT=$(ulimit -H -n)
if [ $? -eq 0 ] ; then if [ $? -eq 0 ]; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
MAX_FD="$MAX_FD_LIMIT" MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi fi
ulimit -n $MAX_FD
if [ $? -ne 0 ]; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi fi
# For Darwin, add options to specify how the application appears in the dock # For Darwin, add options to specify how the application appears in the dock
if $darwin; then if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if $cygwin ; then if [ "$cygwin" = "true" -o "$msys" = "true" ]; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=$(cygpath --path --mixed "$APP_HOME")
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=$(cygpath --path --mixed "$CLASSPATH")
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=$(cygpath --unix "$JAVACMD")
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)
SEP="" SEP=""
for dir in $ROOTDIRSRAW ; do for dir in $ROOTDIRSRAW; do
ROOTDIRS="$ROOTDIRS$SEP$dir" ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|" SEP="|"
done done
OURCYGPATTERN="(^($ROOTDIRS))" OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments # Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then if [ "$GRADLE_CYGPATTERN" != "" ]; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@"; do
CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -)
CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition
eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg")
else
eval $(echo args$i)="\"$arg\""
fi fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh i=$(expr $i + 1)
i=0 done
for arg in "$@" ; do case $i in
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 0) set -- ;;
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 3) set -- "$args0" "$args1" "$args2" ;;
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
else 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
eval `echo args$i`="\"$arg\"" 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
fi 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
i=$((i+1)) 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
done 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
case $i in esac
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi fi
# Escape application args # Escape application args
save ( ) { save() {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done
echo " " echo " "
} }
APP_ARGS=$(save "$@") APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules # Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

18
gradlew.bat vendored
View File

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS= set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome