From d73cf6e0c2aeaa6498cb491d3e8cc324b68748ee Mon Sep 17 00:00:00 2001 From: PeratX <1215714524@qq.com> Date: Mon, 3 Apr 2017 22:07:32 +0800 Subject: [PATCH] Initial commit --- .gitignore | 3 + app/.gitignore | 1 + app/build.gradle | 36 ++++ app/proguard-rules.pro | 17 ++ .../daedalus/ExampleInstrumentedTest.java | 26 +++ app/src/main/AndroidManifest.xml | 50 ++++++ .../org/itxtech/daedalus/AboutActivity.java | 13 ++ .../daedalus/BootBroadcastReceiver.java | 41 +++++ .../itxtech/daedalus/DaedalusVpnService.java | 135 +++++++++++++++ .../java/org/itxtech/daedalus/DnsServers.java | 26 +++ .../org/itxtech/daedalus/MainActivity.java | 159 +++++++++++++++++ .../itxtech/daedalus/SettingsActivity.java | 27 +++ .../itxtech/daedalus/SettingsFragment.java | 22 +++ app/src/main/res/layout-land/content_main.xml | 31 ++++ app/src/main/res/layout/activity_about.xml | 25 +++ app/src/main/res/layout/activity_main.xml | 34 ++++ app/src/main/res/layout/activity_settings.xml | 14 ++ app/src/main/res/layout/content_main.xml | 41 +++++ app/src/main/res/menu/menu_main.xml | 13 ++ app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 6258 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 6258 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 6258 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6258 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 6258 bytes app/src/main/res/values-v21/styles.xml | 8 + app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values-zh/strings.xml | 26 +++ app/src/main/res/values/array.xml | 12 ++ app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 6 + app/src/main/res/values/strings.xml | 27 +++ app/src/main/res/values/styles.xml | 17 ++ app/src/main/res/xml/perf_settings.xml | 33 ++++ .../org/itxtech/daedalus/ExampleUnitTest.java | 17 ++ build.gradle | 23 +++ gradle.properties | 13 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 ++++++++++++++++++ gradlew.bat | 90 ++++++++++ settings.gradle | 1 + 41 files changed, 1165 insertions(+) create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/org/itxtech/daedalus/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/org/itxtech/daedalus/AboutActivity.java create mode 100644 app/src/main/java/org/itxtech/daedalus/BootBroadcastReceiver.java create mode 100644 app/src/main/java/org/itxtech/daedalus/DaedalusVpnService.java create mode 100644 app/src/main/java/org/itxtech/daedalus/DnsServers.java create mode 100644 app/src/main/java/org/itxtech/daedalus/MainActivity.java create mode 100644 app/src/main/java/org/itxtech/daedalus/SettingsActivity.java create mode 100644 app/src/main/java/org/itxtech/daedalus/SettingsFragment.java create mode 100644 app/src/main/res/layout-land/content_main.xml create mode 100644 app/src/main/res/layout/activity_about.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_settings.xml create mode 100644 app/src/main/res/layout/content_main.xml create mode 100644 app/src/main/res/menu/menu_main.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-v21/styles.xml create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100644 app/src/main/res/values-zh/strings.xml create mode 100644 app/src/main/res/values/array.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/xml/perf_settings.xml create mode 100644 app/src/test/java/org/itxtech/daedalus/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index f6b286c..e56ed97 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,9 @@ local.properties # Proguard folder generated by Eclipse proguard/ +#IDE files +.idea/ + # Log Files *.log diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..a2f02ee --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,36 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + defaultConfig { + applicationId "org.itxtech.daedalus" + minSdkVersion 21 + targetSdkVersion 25 + versionCode 1 + versionName "1.0.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions{ + checkReleaseBuilds false + abortOnError false + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:design:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + testCompile 'junit:junit:4.12' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..1ef984a --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in E:\development\android-sdk-windows/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/org/itxtech/daedalus/ExampleInstrumentedTest.java b/app/src/androidTest/java/org/itxtech/daedalus/ExampleInstrumentedTest.java new file mode 100644 index 0000000..c35071c --- /dev/null +++ b/app/src/androidTest/java/org/itxtech/daedalus/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package org.itxtech.daedalus; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("org.itxtech.daedalus", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6aa2347 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/org/itxtech/daedalus/AboutActivity.java b/app/src/main/java/org/itxtech/daedalus/AboutActivity.java new file mode 100644 index 0000000..1c01de5 --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/AboutActivity.java @@ -0,0 +1,13 @@ +package org.itxtech.daedalus; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class AboutActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/BootBroadcastReceiver.java b/app/src/main/java/org/itxtech/daedalus/BootBroadcastReceiver.java new file mode 100644 index 0000000..540228f --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/BootBroadcastReceiver.java @@ -0,0 +1,41 @@ +package org.itxtech.daedalus; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.VpnService; +import android.preference.PreferenceManager; +import android.util.Log; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class BootBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + PreferenceManager.setDefaultValues(context, R.xml.perf_settings, false); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.getBoolean("settings_boot", false)) { + + Intent vIntent = VpnService.prepare(context); + if (vIntent != null) { + context.startActivity(vIntent); + } + + DaedalusVpnService.primaryServer = DnsServers.getDnsServerAddress(prefs.getString("primary_server", "0")); + DaedalusVpnService.secondaryServer = DnsServers.getDnsServerAddress(prefs.getString("secondary_server", "1")); + + context.startService((new Intent(context, DaedalusVpnService.class)).setAction(DaedalusVpnService.ACTION_ACTIVATE)); + + Log.d("DVpn", "Boot service"); + } + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/DaedalusVpnService.java b/app/src/main/java/org/itxtech/daedalus/DaedalusVpnService.java new file mode 100644 index 0000000..e14e720 --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/DaedalusVpnService.java @@ -0,0 +1,135 @@ +package org.itxtech.daedalus; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.VpnService; +import android.os.ParcelFileDescriptor; +import android.support.v7.app.NotificationCompat; +import android.util.Log; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class DaedalusVpnService extends VpnService implements Runnable { + public static final String ACTION_ACTIVATE = "org.itxtech.daedalus.DaedalusVpnServer.ACTIVATE"; + public static final String ACTION_DEACTIVATE = "org.itxtech.daedalus.DaedalusVpnServer.DEACTIVATE"; + + public static String primaryServer; + public static String secondaryServer; + + private Thread mThread = null; + private static int ip = 0; + private ParcelFileDescriptor descriptor; + + @Override + public void onCreate() { + super.onCreate(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent != null) { + switch (intent.getAction()) { + case ACTION_ACTIVATE: + + NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + + NotificationCompat.Builder builder = new NotificationCompat.Builder(this); + + Intent nIntent = new Intent(this, MainActivity.class); + PendingIntent pIntent = PendingIntent.getActivity(this, 0, nIntent, PendingIntent.FLAG_UPDATE_CURRENT); + builder.setContentTitle(getResources().getString(R.string.notification_activated)) + .setDefaults(NotificationCompat.DEFAULT_LIGHTS) + .setSmallIcon(R.mipmap.ic_launcher) + .setAutoCancel(true) + .setOngoing(true) + .setContentIntent(pIntent); + + Notification notification = builder.build(); + notification.flags = Notification.FLAG_NO_CLEAR; + + manager.notify(0, notification); + + if (this.mThread == null) { + this.mThread = new Thread(this, "DaedalusVpn"); + this.mThread.start(); + } + return START_STICKY; + case ACTION_DEACTIVATE: + stopThread(); + + NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + + return START_NOT_STICKY; + } + } + return START_NOT_STICKY; + } + + @Override + public void onDestroy() { + stopThread(); + } + + private void stopThread() { + try { + if (this.descriptor != null) { + this.descriptor.close(); + this.descriptor = null; + } + } catch (Exception e) { + Log.d("DVpn", e.toString()); + } + stopSelf(); + } + + @Override + public void onRevoke() { + stopThread(); + } + + @Override + public void run() { + try { + int i; + Builder builder = new Builder(); + StringBuilder stringBuilder = new StringBuilder("10.0.0."); + if (ip == 254) { + ip = 0; + i = 0; + } else { + i = ip; + ip = i + 1; + } + String ipAdd = stringBuilder.append(i).toString(); + if (this.descriptor != null) { + this.descriptor.close(); + } + + builder.addAddress(ipAdd, 24); + Log.d("DVpn", "tun0 add " + ipAdd + " pServ " + primaryServer + " sServ " + secondaryServer); + builder.addDnsServer(primaryServer).addDnsServer(secondaryServer); + this.descriptor = builder.setSession("DVpn").establish(); + + while (true) { + Thread.sleep(8000); + } + } catch (Exception e) { + Log.d("DVpn", e.toString()); + } finally { + Log.d("DVpn", "quit"); + stopThread(); + } + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/DnsServers.java b/app/src/main/java/org/itxtech/daedalus/DnsServers.java new file mode 100644 index 0000000..83d7bcc --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/DnsServers.java @@ -0,0 +1,26 @@ +package org.itxtech.daedalus; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class DnsServers { + public static String getDnsServerAddress(String id) { + switch (id) { + case "0": + return "113.107.249.56"; + case "1": + return "120.27.103.230"; + case "2": + return "123.206.61.167"; + default: + return "123.206.61.167"; + } + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/MainActivity.java b/app/src/main/java/org/itxtech/daedalus/MainActivity.java new file mode 100644 index 0000000..01dfa8a --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/MainActivity.java @@ -0,0 +1,159 @@ +package org.itxtech.daedalus; + +import android.app.ActivityManager; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.net.VpnService; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.app.NotificationCompat; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Button; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class MainActivity extends AppCompatActivity { + private boolean serviceActivated = false; + private SharedPreferences prefs; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + initConfig(); + + serviceActivated = isServiceActivated(); + setContentView(R.layout.activity_main); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Snackbar.make(view, R.string.fab_text, Snackbar.LENGTH_LONG) + .setAction("Action", null).show(); + + Intent intent = new Intent(); + intent.setAction("android.intent.action.VIEW"); + Uri siteURL = Uri.parse("http://www.cutedns.cn"); + intent.setData(siteURL); + startActivity(intent); + } + }); + + final Button but = (Button) findViewById(R.id.button); + if (serviceActivated) { + but.setText(R.string.deactivate); + } else { + but.setText(R.string.activate); + } + but.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + serviceActivated = isServiceActivated(); + if (serviceActivated) { + deactivateService(); + but.setText(R.string.activate); + } else { + activateService(); + but.setText(R.string.deactivate); + } + } + }); + } + + private void initConfig() { + PreferenceManager.setDefaultValues(this, R.xml.perf_settings, false); + prefs = PreferenceManager.getDefaultSharedPreferences(this); + } + + private void activateService() { + Intent intent = VpnService.prepare(this); + if (intent != null) { + startActivityForResult(intent, 0); + } else { + onActivityResult(0, RESULT_OK, null); + } + } + + + private void deactivateService() { + startService(getServiceIntent().setAction(DaedalusVpnService.ACTION_DEACTIVATE)); + stopService(getServiceIntent()); + } + + private boolean isServiceActivated() { + ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); + for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if ("org.itxtech.daedalus.DaedalusVpnService".equals(service.service.getClassName())) { + return true; + } + } + return false; + } + + private Intent getServiceIntent() { + return new Intent(this, DaedalusVpnService.class); + } + + protected void onActivityResult(int request, int result, Intent data) { + if (result == RESULT_OK) { + DaedalusVpnService.primaryServer = DnsServers.getDnsServerAddress(prefs.getString("primary_server", "0")); + DaedalusVpnService.secondaryServer = DnsServers.getDnsServerAddress(prefs.getString("secondary_server", "1")); + + startService(getServiceIntent().setAction(DaedalusVpnService.ACTION_ACTIVATE)); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + Intent intent = new Intent(); + intent.setClass(this, SettingsActivity.class); + startActivity(intent); + return true; + } + + if (id == R.id.action_about) { + Intent intent = new Intent(); + intent.setClass(this, AboutActivity.class); + startActivity(intent); + return true; + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/SettingsActivity.java b/app/src/main/java/org/itxtech/daedalus/SettingsActivity.java new file mode 100644 index 0000000..2d3f6f6 --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/SettingsActivity.java @@ -0,0 +1,27 @@ +package org.itxtech.daedalus; + +import android.app.FragmentManager; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class SettingsActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + SettingsFragment settingsFragment = new SettingsFragment(); + FragmentManager manager = getFragmentManager(); + manager.beginTransaction().replace(R.id.activity_settings, settingsFragment).commit(); + } +} diff --git a/app/src/main/java/org/itxtech/daedalus/SettingsFragment.java b/app/src/main/java/org/itxtech/daedalus/SettingsFragment.java new file mode 100644 index 0000000..72e7da4 --- /dev/null +++ b/app/src/main/java/org/itxtech/daedalus/SettingsFragment.java @@ -0,0 +1,22 @@ +package org.itxtech.daedalus; + +import android.os.Bundle; +import android.preference.PreferenceFragment; + +/** + * Daedalus Project + * + * @author iTXTech + * @link https://itxtech.org + *

+ * 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, version 3. + */ +public class SettingsFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.perf_settings); + } +} diff --git a/app/src/main/res/layout-land/content_main.xml b/app/src/main/res/layout-land/content_main.xml new file mode 100644 index 0000000..e85616f --- /dev/null +++ b/app/src/main/res/layout-land/content_main.xml @@ -0,0 +1,31 @@ + + +