diff options
Diffstat (limited to 'mobile-kt/app/src/DNSProxyService.java')
-rw-r--r-- | mobile-kt/app/src/DNSProxyService.java | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/mobile-kt/app/src/DNSProxyService.java b/mobile-kt/app/src/DNSProxyService.java new file mode 100644 index 0000000..10e127b --- /dev/null +++ b/mobile-kt/app/src/DNSProxyService.java @@ -0,0 +1,171 @@ +package org.pihole.dnsproxy; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.SharedPreferences; + +import android.content.Context; +import android.content.Intent; + +import android.net.DhcpInfo; +import android.net.VpnService; +import android.net.wifi.WifiManager; + +import android.preference.PreferenceManager; + +import android.util.Log; + +import java.net.InetAddress; + +public class DNSProxyService extends VpnService { + + public static String LOG_TAG = "org.pihole.dnsproxy.log"; + public static String NOTIFICATION_NOTIFY = "org.pihole.dnsproxy.service.dnsproxy.notification.NOTIFY"; + public static String NOTIFICATION_CHANNEL_ID = "org.pihole.dnsproxy.service.dnsproxy.NOTIFICATION"; + public static String ACTION_START = "org.pihole.dnsproxy.service.dnsproxy.START"; + public static String ACTION_STOP = "org.pihole.dnsproxy.service.dnsproxy.STOP"; + + public static String PIHOLE_ADDRESS = ""; + + private static DNSProxyConnection connection; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent.getAction().equals(DNSProxyService.ACTION_START)) { + this.connect(); + + return Service.START_STICKY; + } else { + this.disconnect(); + + return Service.START_NOT_STICKY; + } + } + + @Override + public void onDestroy() { + this.disconnect(); + + super.onDestroy(); + } + + /** + * Builder has to be created by service + */ + public VpnService.Builder newBuilder() { + return new VpnService.Builder(); + } + + /** + * Whether the proxy is setup running + */ + public static boolean isRunning() + { + return DNSProxyService.connection != null; + } + + /** + * Start this service + */ + public static void start(Context context) { + context.startService((new Intent(context, DNSProxyService.class)).setAction(DNSProxyService.ACTION_START)); + } + + /** + * Stop this service + */ + public static void stop(Context context) { + context.startService((new Intent(context, DNSProxyService.class)).setAction(DNSProxyService.ACTION_STOP)); + } + + /** + * Setup connection + */ + private void connect() { + this.setPiholeAddress(); + + DNSProxyService.connection = new DNSProxyConnection(this); + DNSProxyService.connection.start(); + + this.startForeground(); + + // send notification when started + Intent notification = new Intent(DNSProxyService.NOTIFICATION_NOTIFY); + sendBroadcast(notification); + } + + /** + * Disconnect from connection + */ + private void disconnect() { + DNSProxyService.connection.stop(); + DNSProxyService.connection = null; + + stopForeground(true); + + // send notification when stopped + Intent notification = new Intent(DNSProxyService.NOTIFICATION_NOTIFY); + sendBroadcast(notification); + } + + /** + * Get and set IP address of Pihole DNS server + */ + private void setPiholeAddress() { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + if (!sharedPreferences.getBoolean("use_automatic_dns_server_discovery", true)) { + DNSProxyService.PIHOLE_ADDRESS = sharedPreferences.getString("dns_server_address", ""); + return; + } + + WifiManager manager = (WifiManager) getSystemService(WIFI_SERVICE); + DhcpInfo info = manager.getDhcpInfo(); + + byte[] addressBytes = { + (byte) (0xff & info.dns1), + (byte) (0xff & (info.dns1 >> 8)), + (byte) (0xff & (info.dns1 >> 16)), + (byte) (0xff & (info.dns1 >> 24)), + }; + + try { + DNSProxyService.PIHOLE_ADDRESS = InetAddress.getByAddress(addressBytes).toString().replaceAll("/", ""); + } catch (Exception e) { + DNSProxyService.PIHOLE_ADDRESS = ""; + } + } + + /** + * Start the Foreground notification process + */ + private void startForeground() { + NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + NotificationChannel channel = new NotificationChannel( + DNSProxyService.NOTIFICATION_CHANNEL_ID, + DNSProxyService.NOTIFICATION_CHANNEL_ID, + NotificationManager.IMPORTANCE_DEFAULT + ); + manager.createNotificationChannel(channel); + + Notification notification = new Notification.Builder(this, DNSProxyService.NOTIFICATION_CHANNEL_ID) + .setSmallIcon(R.drawable.logo) + .setContentTitle(getString(R.string.app_label)) + .setContentText(String.format(getString(R.string.dns_proxy_service__notification__text), DNSProxyService.PIHOLE_ADDRESS)) + .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK)) + .addAction( + R.drawable.logo, + getString(R.string.dns_proxy_service__notification__action__stop), + PendingIntent.getService(this, 0, + (new Intent(this, DNSProxyService.class)).setAction(DNSProxyService.ACTION_STOP), + PendingIntent.FLAG_IMMUTABLE + ) + ) + .build(); + + startForeground(1, notification); + } +} |