diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml new file mode 100644 index 00000000..32b86bcf --- /dev/null +++ b/.github/workflows/build-debug.yml @@ -0,0 +1,26 @@ +name: Debug Build + +on: workflow_dispatch + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew assembleDebug + - name: Upload APK + uses: actions/upload-artifact@v3 + with: + name: debugApk + path: app/build/outputs/apk/debug/**.apk diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b6f238b2..d7391608 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,10 +17,10 @@ - + @@ -41,11 +41,17 @@ android:label="@string/action_about" android:parentActivityName=".MainActivity" android:theme="@style/AppTheme" /> + + @@ -55,8 +61,9 @@ + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" /> + - \ No newline at end of file + diff --git a/app/src/main/java/org/jak_linux/dns66/LogsActivity.java b/app/src/main/java/org/jak_linux/dns66/LogsActivity.java new file mode 100644 index 00000000..b3e8c485 --- /dev/null +++ b/app/src/main/java/org/jak_linux/dns66/LogsActivity.java @@ -0,0 +1,129 @@ +package org.jak_linux.dns66; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import org.jak_linux.dns66.vpn.DnsPacketProxy; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class LogsActivity extends AppCompatActivity { + + private final List logcatOutput = new ArrayList<>(100); + private boolean showDnsRequestsOnly = true; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_logs); + + ((TextView) findViewById(R.id.logs_output)).setHorizontallyScrolling(true); + + viewLogcat(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.logcat, menu); + menu.findItem(R.id.option_only_show_dns_requests).setChecked(showDnsRequestsOnly); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_send_logcat: + sendLogcat(); + break; + case R.id.action_refresh_logcat: + viewLogcat(); + break; + case R.id.option_only_show_dns_requests: + toggleDnsRequestsFilter(item); + break; + } + return super.onOptionsItemSelected(item); + } + + private void toggleDnsRequestsFilter(MenuItem item) { + showDnsRequestsOnly = !showDnsRequestsOnly; + item.setChecked(showDnsRequestsOnly); + } + + private void viewLogcat() { + try { + updateLogcatOutput(); + + if (logcatOutput.isEmpty()) { + Toast.makeText(this, R.string.logcat_empty, Toast.LENGTH_SHORT).show(); + return; + } + + List filteredLogs = logcatOutput; + if (showDnsRequestsOnly) { + filteredLogs = new ArrayList<>(20); + for (String line : logcatOutput) { + if (line.contains(DnsPacketProxy.DNS_REQUESTS_FILTER_MESSAGE)) { + filteredLogs.add(line); + } + } + } + + String logsString = TextUtils.join("\n", filteredLogs); + ((TextView) findViewById(R.id.logs_output)).setText(logsString); + } catch (Exception e) { + e.printStackTrace(); + Toast.makeText(this, "Not supported: " + e, Toast.LENGTH_LONG).show(); + } + } + + private void updateLogcatOutput() throws IOException { + logcatOutput.clear(); + Process process = null; + try { + process = Runtime.getRuntime().exec("logcat -d"); + InputStream is = process.getInputStream(); + BufferedReader bis = new BufferedReader(new InputStreamReader(is)); + String line; + while ((line = bis.readLine()) != null) { + logcatOutput.add(line); + } + } finally { + if (process != null) { + process.destroy(); + } + } + } + + private void sendLogcat() { + if (logcatOutput.isEmpty()) { + Toast.makeText(this, R.string.logcat_empty, Toast.LENGTH_SHORT).show(); + return; + } + + String logsString = TextUtils.join("\n", logcatOutput); + + Intent eMailIntent = new Intent(Intent.ACTION_SEND); + eMailIntent.setType("text/plain"); + eMailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"jak@jak-linux.org"}); + eMailIntent.putExtra(Intent.EXTRA_SUBJECT, "DNS66 Logcat"); + eMailIntent.putExtra(Intent.EXTRA_TEXT, logsString); + eMailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(eMailIntent); + } +} diff --git a/app/src/main/java/org/jak_linux/dns66/MainActivity.java b/app/src/main/java/org/jak_linux/dns66/MainActivity.java index 005fca94..6c49df58 100644 --- a/app/src/main/java/org/jak_linux/dns66/MainActivity.java +++ b/app/src/main/java/org/jak_linux/dns66/MainActivity.java @@ -211,42 +211,14 @@ public void onClick(DialogInterface dialogInterface, int i) { startActivity(infoIntent); break; case R.id.action_logcat: - sendLogcat(); + Intent logsIntent = new Intent(this, LogsActivity.class); + startActivity(logsIntent); break; } return super.onOptionsItemSelected(item); } - private void sendLogcat() { - Process proc = null; - try { - proc = Runtime.getRuntime().exec("logcat -d"); - InputStream is = proc.getInputStream(); - BufferedReader bis = new BufferedReader(new InputStreamReader(is)); - StringBuilder logcat = new StringBuilder(); - String line; - while ((line = bis.readLine()) != null) { - logcat.append(line); - logcat.append('\n'); - } - - Intent eMailIntent = new Intent(Intent.ACTION_SEND); - eMailIntent.setType("text/plain"); - eMailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"jak@jak-linux.org"}); - eMailIntent.putExtra(Intent.EXTRA_SUBJECT, "DNS66 Logcat"); - eMailIntent.putExtra(Intent.EXTRA_TEXT, logcat.toString()); - eMailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(eMailIntent); - } catch (Exception e) { - e.printStackTrace(); - Toast.makeText(this, "Not supported: " + e, Toast.LENGTH_LONG).show(); - } finally { - if (proc != null) - proc.destroy(); - } - } - @Override protected void onNewIntent(Intent intent) { Log.d("MainActivity", "onNewIntent: Wee"); diff --git a/app/src/main/java/org/jak_linux/dns66/vpn/DnsPacketProxy.java b/app/src/main/java/org/jak_linux/dns66/vpn/DnsPacketProxy.java index 57f720e9..a00cc5fa 100644 --- a/app/src/main/java/org/jak_linux/dns66/vpn/DnsPacketProxy.java +++ b/app/src/main/java/org/jak_linux/dns66/vpn/DnsPacketProxy.java @@ -46,6 +46,7 @@ */ public class DnsPacketProxy { + public static final String DNS_REQUESTS_FILTER_MESSAGE = "handleDnsRequest: DNS Name "; private static final String TAG = "DnsPacketProxy"; // Choose a value that is smaller than the time needed to unblock a host. private static final int NEGATIVE_CACHE_TTL_SECONDS = 5; @@ -201,11 +202,11 @@ void handleDnsRequest(byte[] packetData) throws AdVpnThread.VpnNetworkException } String dnsQueryName = dnsMsg.getQuestion().getName().toString(true); if (!ruleDatabase.isBlocked(dnsQueryName.toLowerCase(Locale.ENGLISH))) { - Log.i(TAG, "handleDnsRequest: DNS Name " + dnsQueryName + " Allowed, sending to " + destAddr); + Log.i(TAG, DNS_REQUESTS_FILTER_MESSAGE + dnsQueryName + " Allowed, sending to " + destAddr); DatagramPacket outPacket = new DatagramPacket(dnsRawData, 0, dnsRawData.length, destAddr, parsedUdp.getHeader().getDstPort().valueAsInt()); eventLoop.forwardPacket(outPacket, parsedPacket); } else { - Log.i(TAG, "handleDnsRequest: DNS Name " + dnsQueryName + " Blocked!"); + Log.i(TAG, DNS_REQUESTS_FILTER_MESSAGE + dnsQueryName + " Blocked!"); dnsMsg.getHeader().setFlag(Flags.QR); dnsMsg.getHeader().setRcode(Rcode.NOERROR); dnsMsg.addRecord(NEGATIVE_CACHE_SOA_RECORD, Section.AUTHORITY); diff --git a/app/src/main/res/layout/activity_logs.xml b/app/src/main/res/layout/activity_logs.xml new file mode 100644 index 00000000..68c41a82 --- /dev/null +++ b/app/src/main/res/layout/activity_logs.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/app/src/main/res/menu/logcat.xml b/app/src/main/res/menu/logcat.xml new file mode 100644 index 00000000..68ce1faf --- /dev/null +++ b/app/src/main/res/menu/logcat.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1e01f25a..2bd75789 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -37,7 +37,7 @@ Ignore - + Version: %s Some of your configured (non-ignored) hosts files are missing.\n\nUse the ‘Refresh’ action to download hosts files.\n\nDo you still want to continue? Missing hosts file @@ -112,9 +112,32 @@ Watching the connection may cause reconnects and the connection to get stuck Cancel Continue + No logcat output found + Send + Refresh + Filter DNS requests No apps bypass by default All apps bypass by default System apps bypass by default + +04-28 05:57:44.570 131 131 I chatty : uid=1000(system) /system/bin/gatekeeperd expire 3 lines +04-28 05:57:44.624 132 132 I chatty : uid=0(root) /system/xbin/perfprofd expire 5 lines +04-28 05:57:45.008 144 144 I chatty : uid=0(root) /system/bin/dhcptool expire 61 lines +04-28 05:57:46.338 270 270 I chatty : uid=0(root) /system/bin/lmkd expire 4 lines +04-28 05:57:47.547 274 274 D local_opengl: Starting local_opengl +04-28 05:57:47.554 274 274 D local_opengl: Getting player version +04-28 05:57:48.535 283 283 I chatty : uid=0(root) /system/bin/debuggerd expire 3 lines +04-28 05:57:48.577 287 287 I chatty : uid=0(root) /system/bin/installd expire 9 lines +04-28 05:57:48.911 279 279 E network_profile_handler: init_all_network_profile_state: wlan: eth1 phone:rmnet0 +04-28 05:57:48.911 279 279 I network_profile: Redis connect +04-28 05:57:48.911 279 279 I network_profile: Redis PUB: network_profile status ready +04-28 05:57:48.912 279 292 I network_profile: Redis read thread +04-28 05:57:48.913 279 292 I network_profile: Redis read wait +04-28 05:57:48.918 273 273 D vinput : Starting Vinput Daemon +04-28 05:57:48.918 273 273 D vinput : send_status_async +04-28 05:57:48.918 273 273 D vinput : send_status +04-28 05:57:48.919 273 273 W vinput : Empty command, we ignore it +