diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..9c4de582
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 00000000..a9073f3e
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+NetGuard for Android
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 00000000..96cc43ef
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 00000000..e7bedf33
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 00000000..0833b17c
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..1a3eaffb
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..31295291
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 00000000..7f68460d
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..6564d52d
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NetGuard.iml b/NetGuard.iml
new file mode 100644
index 00000000..ae0881d8
--- /dev/null
+++ b/NetGuard.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 3083de94..3c6ed140 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
# NetGuard
+
+No root Android firewall
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 00000000..796b96d1
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 00000000..3ddd50b4
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ generateDebugAndroidTestSources
+ generateDebugSources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 00000000..add2371d
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,40 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 23
+ buildToolsVersion "23.0.1"
+
+ defaultConfig {
+ applicationId "eu.faircode.netguard"
+ minSdkVersion 21
+ targetSdkVersion 23
+ versionCode 1
+ versionName "0.2"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ applicationVariants.all { variant ->
+ setOutputFile(variant, defaultConfig)
+ }
+ }
+ }
+}
+
+def setOutputFile(variant, defaultConfig) {
+ variant.outputs.each { output ->
+ def fileName = "NetGuard-v" + defaultConfig.versionName + ".apk"
+ if (output.zipAlign)
+ output.outputFile = new File(output.outputFile.parent, fileName)
+ else
+ output.packageApplication.outputFile = new File(output.packageApplication.outputFile.parent, fileName)
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ testCompile 'junit:junit:4.12'
+ compile 'com.android.support:appcompat-v7:23.1.0'
+ compile 'com.android.support:recyclerview-v7:23.1.0'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 00000000..c4fd90e4
--- /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 /home/marcel/Android/Sdk/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/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..0be917b7
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/eu/faircode/netguard/ActivityMain.java b/app/src/main/java/eu/faircode/netguard/ActivityMain.java
new file mode 100644
index 00000000..dfcb4404
--- /dev/null
+++ b/app/src/main/java/eu/faircode/netguard/ActivityMain.java
@@ -0,0 +1,102 @@
+package eu.faircode.netguard;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.VpnService;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.Switch;
+
+import java.util.List;
+
+public class ActivityMain extends AppCompatActivity {
+ private static final String TAG = "NetGuard.Main";
+ private static final int REQUEST_VPN = 1;
+
+ private boolean running = false;
+ private RuleAdapter adapter = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ running = true;
+
+ View view = getLayoutInflater().inflate(R.layout.actionbar, null);
+ getSupportActionBar().setDisplayShowCustomEnabled(true);
+ getSupportActionBar().setCustomView(view);
+
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+ Switch swEnabled = (Switch) view.findViewById(R.id.swEnabled);
+ swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ prefs.edit().putBoolean("enabled", isChecked).apply();
+
+ if (isChecked) {
+ Log.i(TAG, "On");
+ Intent intent = VpnService.prepare(ActivityMain.this);
+ if (intent == null) {
+ Log.e(TAG, "Prepare done");
+ onActivityResult(REQUEST_VPN, RESULT_OK, null);
+ } else {
+ Log.i(TAG, "Start intent=" + intent);
+ startActivityForResult(intent, REQUEST_VPN);
+ }
+ } else {
+ Log.i(TAG, "Off");
+ Intent intent = new Intent(ActivityMain.this, BlackHoleService.class);
+ intent.putExtra(BlackHoleService.EXTRA_START, false);
+ Log.i(TAG, "Stop service=" + intent);
+ startService(intent);
+ }
+ }
+ });
+ swEnabled.setChecked(prefs.getBoolean("enabled", false));
+
+ final RecyclerView rvApplication = (RecyclerView) findViewById(R.id.rvApplication);
+ rvApplication.setHasFixedSize(true);
+ rvApplication.setLayoutManager(new LinearLayoutManager(this));
+
+ new AsyncTask