diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Readme.md | 4 | ||||
-rw-r--r-- | WORKSPACE | 11 | ||||
-rw-r--r-- | app/java/AndroidManifest.xml | 7 | ||||
-rw-r--r-- | app/java/BUILD | 2 | ||||
-rw-r--r-- | app/java/res/layout/main.xml | 4 | ||||
-rw-r--r-- | app/java/res/values/strings.xml | 16 | ||||
-rw-r--r-- | app/java/src/DNSProxyConnection.java | 39 | ||||
-rw-r--r-- | app/java/src/DNSProxyRunner.java | 53 | ||||
-rw-r--r-- | app/java/src/DNSProxyService.java | 52 | ||||
-rw-r--r-- | app/java/src/DNSService.java | 33 | ||||
-rw-r--r-- | app/java/src/MainActivity.java | 118 |
12 files changed, 261 insertions, 79 deletions
@@ -1 +1,2 @@ /bazel-* +/result @@ -5,3 +5,7 @@ - https://stackoverflow.com/questions/600207/how-to-check-if-a-service-is-running-on-android - https://www.vogella.com/tutorials/AndroidServices/article.html#communication-with-services - https://github.com/googlecodelabs/bazel-android-intro/blob/master/sample/mediarecorder/java/com/example/android/mediarecorder/MainActivity.java +- https://github.com/schwabe/ics-openvpn + +>:( +- https://github.com/bazelbuild/bazel/pull/12626 @@ -1,14 +1,3 @@ -# Load the Android build rules -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -http_archive( - name = "build_bazel_rules_android", - urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"], - sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", - strip_prefix = "rules_android-0.1.1", -) - -# Configure Android SDK Path -load("@build_bazel_rules_android//android:rules.bzl", "android_sdk_repository") android_sdk_repository( name = "androidsdk", ) diff --git a/app/java/AndroidManifest.xml b/app/java/AndroidManifest.xml index ef81463..6d4ea3e 100644 --- a/app/java/AndroidManifest.xml +++ b/app/java/AndroidManifest.xml @@ -8,10 +8,11 @@ > <uses-sdk android:minSdkVersion="16" - android:targetSdkVersion="28" + android:targetSdkVersion="30" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.INTERNET" /> @@ -19,7 +20,7 @@ android:usesCleartextTraffic="true" > <service - android:name=".DNSService" + android:name=".DNSProxyService" android:permission="android.permission.BIND_VPN_SERVICE" > <intent-filter> @@ -29,7 +30,7 @@ <activity android:name=".MainActivity" - android:label="@string/label" + android:label="@string/app_label" android:screenOrientation="portrait" > <intent-filter> diff --git a/app/java/BUILD b/app/java/BUILD index c19473f..e533161 100644 --- a/app/java/BUILD +++ b/app/java/BUILD @@ -1,5 +1,3 @@ -load("@build_bazel_rules_android//android:rules.bzl", "android_library", "android_binary") - android_library( name = "main", srcs = glob(["src/*.java"]), diff --git a/app/java/res/layout/main.xml b/app/java/res/layout/main.xml index 4a644b6..430036f 100644 --- a/app/java/res/layout/main.xml +++ b/app/java/res/layout/main.xml @@ -23,7 +23,7 @@ android:layout_height="fill_parent" android:id="@+id/button_start" android:layout_gravity="center" - android:onClick="onStartClick" - android:text="@string/btnStart" + android:onClick="onClickButtonStart" + android:text="@string/button_start__start" /> </FrameLayout> diff --git a/app/java/res/values/strings.xml b/app/java/res/values/strings.xml index beab6c5..2f5e4e6 100644 --- a/app/java/res/values/strings.xml +++ b/app/java/res/values/strings.xml @@ -1,10 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="label"> + <string name="app_label"> Pihole DNS Proxy </string> - <string name="btnStart"> - Start Proxy + <string name="service_starting"> + starting + </string> + <string name="service_stopping"> + stopping + </string> + + <string name="button_start__start"> + Start Proxy + </string> + <string name="button_start__stop"> + Stop Proxy </string> </resources> diff --git a/app/java/src/DNSProxyConnection.java b/app/java/src/DNSProxyConnection.java new file mode 100644 index 0000000..f96af80 --- /dev/null +++ b/app/java/src/DNSProxyConnection.java @@ -0,0 +1,39 @@ +package org.pihole.dnsproxy; + +import android.os.ParcelFileDescriptor; + +import android.util.Log; + +import java.io.IOException; + +public class DNSProxyConnection { + + public static String THREAD_NAME = "org.pihole.dnsproxy.service.thread"; + + private DNSProxyService service; + private Thread thread; + private ParcelFileDescriptor networkInterface; + + public DNSProxyConnection(DNSProxyService service) { + this.service = service; + } + + public void start() { + DNSProxyRunner runner = new DNSProxyRunner(this.service); + runner.setOnEstablishListener(parcelFileDescriptor -> { + this.networkInterface = parcelFileDescriptor; + }); + + this.thread = new Thread(runner, DNSProxyConnection.THREAD_NAME); + this.thread.start(); + } + + public void stop() { + try { + this.thread.stop(); + this.networkInterface.close(); + } catch (IOException exception) { + Log.e(DNSProxyService.LOG_TAG, "Connection failed", exception); + } + } +} diff --git a/app/java/src/DNSProxyRunner.java b/app/java/src/DNSProxyRunner.java new file mode 100644 index 0000000..0c136e8 --- /dev/null +++ b/app/java/src/DNSProxyRunner.java @@ -0,0 +1,53 @@ +package org.pihole.dnsproxy; + +import android.os.ParcelFileDescriptor; + +import android.util.Log; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import java.nio.channels.DatagramChannel; + +public class DNSProxyRunner implements Runnable { + public interface OnEstablishListener { + void onEstablish(ParcelFileDescriptor networkInterface); + } + private OnEstablishListener onEstablishListener; + + private DNSProxyService service; + + DNSProxyRunner(DNSProxyService service) { + this.service = service; + } + + @Override + public void run() { + try { + DatagramChannel tunnel = DatagramChannel.open(); + + if(!this.service.protect(tunnel.socket())) { + throw new IllegalStateException("Cannot protect tunnel"); + } + + // SocketAddress server = new InetSocketAddress("servername", "serverport"); + // + // tunnel.connect(server); + // tunnel.configureBlocking(false); + // + // ParcelFileDescriptor networkInterface = this.handshake(tunnel); + // FileInputStream in = new FileInputStream(networkInterface.getFileDescriptor()); + // FileOutputStream out = new FileOutputStream(networkInterface.getFileDescriptor()); + } catch (IOException exception) { + Log.e(DNSProxyService.LOG_TAG, "Cannot use socket", exception); + } + } + + public void setOnEstablishListener(OnEstablishListener listener) { + this.onEstablishListener = listener; + } +} diff --git a/app/java/src/DNSProxyService.java b/app/java/src/DNSProxyService.java new file mode 100644 index 0000000..117e6fc --- /dev/null +++ b/app/java/src/DNSProxyService.java @@ -0,0 +1,52 @@ +package org.pihole.dnsproxy; + +import android.app.Service; + +import android.content.Intent; + +import android.net.VpnService; + +public class DNSProxyService extends VpnService { + + public static String LOG_TAG = "org.pihole.dnsproxy.log"; + public static String NOTIFICATION = "org.pihole.dnsproxy.service"; + + private static DNSProxyConnection connection; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + this.start(); + + return Service.START_STICKY; + } + + @Override + public void onDestroy() { + this.stop(); + + super.onDestroy(); + } + + public static boolean isRunning() + { + return DNSProxyService.connection != null; + } + + public void start() { + DNSProxyService.connection = new DNSProxyConnection(this); + // DNSProxyService.connection.start(); + + // send notification when started + Intent notification = new Intent(DNSProxyService.NOTIFICATION); + sendBroadcast(notification); + } + + public void stop() { + // DNSProxyService.connection.stop(); + DNSProxyService.connection = null; + + // send notification when stopped + Intent notification = new Intent(DNSProxyService.NOTIFICATION); + sendBroadcast(notification); + } +} diff --git a/app/java/src/DNSService.java b/app/java/src/DNSService.java deleted file mode 100644 index 4f760a5..0000000 --- a/app/java/src/DNSService.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.pihole.dnsproxy; - -import android.app.AlertDialog; -import android.app.Service; - -import android.content.Intent; - -import android.net.VpnService; - -public class DNSService extends VpnService { - - private static boolean isRunning = false; - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - //VpnService.prepare(); - - DNSService.isRunning = true; - - return Service.START_STICKY; - } - - @Override - public void onDestroy() { - DNSService.isRunning = false; - super.onDestroy(); - } - - public static boolean isRunning() - { - return DNSService.isRunning; - } -} diff --git a/app/java/src/MainActivity.java b/app/java/src/MainActivity.java index 9fd99f6..f437c9d 100644 --- a/app/java/src/MainActivity.java +++ b/app/java/src/MainActivity.java @@ -3,7 +3,10 @@ package org.pihole.dnsproxy; import android.app.Activity; import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.net.VpnService; @@ -18,51 +21,116 @@ import android.widget.Toast; public class MainActivity extends Activity { private Button buttonStart; + private Intent dnsProxyService; + + private BroadcastReceiver receiver = new BroadcastReceiver() { + + /** + * Set button_start state on receive from DNSProxyService + */ + @Override + public void onReceive(Context context, Intent intent) { + Bundle bundle = intent.getExtras(); + // if (bundle != null) { + setStateButtonStart(); + // } + } + }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.main); this.buttonStart = (Button) findViewById(R.id.button_start); - this.buttonStart.setText(DNSService.isRunning() ? "Stop" : "Start"); + this.dnsProxyService = new Intent(this, DNSProxyService.class); } @Override public void onResume() { super.onResume(); - this.buttonStart.setText("on RESSSSUME"); + + this.setStateButtonStart(); + registerReceiver(this.receiver, new IntentFilter(DNSProxyService.NOTIFICATION)); } @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {} + public void onPause() { + super.onPause(); - public void onStartClick(View view) { - Intent intent = VpnService.prepare(this); - if (intent != null) { - startActivityForResult(intent, 0); + unregisterReceiver(receiver); + } + + /** + * is called by "startActivityForResult" internally + */ + @Override + public void onActivityResult(int request, int result, Intent data) { + if (result == RESULT_OK) { + this.start(); } - //Intent intent = new Intent(this, DNSService.class); + } - if (!DNSService.isRunning()) { - startService(intent); + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {} - new AlertDialog.Builder(this) - .setTitle("PROXY START") - .setMessage("BRRR") - .show(); - Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); - this.buttonStart.setText("Stop"); + /** + * button_start is clicked + */ + public void onClickButtonStart(View view) { + if (!DNSProxyService.isRunning()) { //start + Intent intent = DNSProxyService.prepare(this); + + if (intent != null) { + startActivityForResult(intent, 0); + } else { + this.onActivityResult(0, RESULT_OK, null); + } + } + else { // stop + this.stop(); } - else { - stopService(intent); - - new AlertDialog.Builder(this) - .setTitle("PROXY STOP") - .setMessage("RRRB") - .show(); - Toast.makeText(this, "service stopping", Toast.LENGTH_SHORT).show(); - this.buttonStart.setText("Start"); + } + + /** + * Set button_start text + */ + public void setStateButtonStart() { + if (!DNSProxyService.isRunning()) { + this.buttonStart.setText(getString(R.string.button_start__start)); + } else { + this.buttonStart.setText(getString(R.string.button_start__stop)); } } + + /** + * Start DNSProxyService + */ + public void start() { + startService(this.dnsProxyService); + + Toast + .makeText( + this, + getString(R.string.service_starting), + Toast.LENGTH_SHORT + ) + .show(); + } + + /** + * Stop DNSProxyService + */ + public void stop() { + stopService(this.dnsProxyService); + + Toast + .makeText( + this, + getString(R.string.service_stopping), + Toast.LENGTH_SHORT + ) + .show(); + } } |