Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to view full and filtered logcat output #473

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/build-debug.yml
Original file line number Diff line number Diff line change
@@ -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
19 changes: 13 additions & 6 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher"
android:banner="@drawable/banner"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
Expand All @@ -32,7 +32,7 @@
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>

Expand All @@ -41,11 +41,17 @@
android:label="@string/action_about"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme" />
<activity
android:name=".LogsActivity"
android:label="@string/action_logcat"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme" />
<activity
android:name=".ItemActivity"
android:label="@string/activity_edit"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme" />

<service
android:name=".vpn.AdVpnService"
android:permission="android.permission.BIND_VPN_SERVICE">
Expand All @@ -55,8 +61,9 @@
</service>
<service
android:name=".db.RuleDatabaseUpdateJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"/>
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />

<receiver
android:name=".vpn.BootComplete"
android:enabled="true"
Expand All @@ -68,4 +75,4 @@

</application>

</manifest>
</manifest>
129 changes: 129 additions & 0 deletions app/src/main/java/org/jak_linux/dns66/LogsActivity.java
Original file line number Diff line number Diff line change
@@ -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<String> 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<String> 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[]{"[email protected]"});
eMailIntent.putExtra(Intent.EXTRA_SUBJECT, "DNS66 Logcat");
eMailIntent.putExtra(Intent.EXTRA_TEXT, logsString);
eMailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(eMailIntent);
}
}
32 changes: 2 additions & 30 deletions app/src/main/java/org/jak_linux/dns66/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -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[]{"[email protected]"});
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");
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/java/org/jak_linux/dns66/vpn/DnsPacketProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 22 additions & 0 deletions app/src/main/res/layout/activity_logs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="org.jak_linux.dns66.LogsActivity">

<TextView
android:id="@+id/logs_output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="horizontal|vertical"
android:scrollHorizontally="true"
android:textIsSelectable="true"
tools:text="@string/sample_logs" />

</ScrollView>
25 changes: 25 additions & 0 deletions app/src/main/res/menu/logcat.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item
android:id="@+id/action_refresh_logcat"
android:icon="@drawable/ic_refresh"
android:orderInCategory="100"
android:title="@string/action_refresh_logcat"
app:showAsAction="ifRoom" />

<item
android:id="@+id/action_send_logcat"
android:orderInCategory="100"
android:title="@string/action_send_logcat"
app:showAsAction="ifRoom|withText" />

<item
android:id="@+id/option_only_show_dns_requests"
android:checkable="true"
android:orderInCategory="100"
android:title="@string/option_only_show_dns_requests"
app:showAsAction="ifRoom|withText" />

</menu>
25 changes: 24 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<item>Ignore</item>
</string-array>
<!-- Translate with something like <Language> Translation: Your Name -->
<string name="translator_credits"/>
<string name="translator_credits" />
<string name="app_version_info">Version: %s</string>
<string name="missing_hosts_files_message">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?</string>
<string name="missing_hosts_files_title">Missing hosts file</string>
Expand Down Expand Up @@ -112,9 +112,32 @@
<string name="unstable_watchdog_message">Watching the connection may cause reconnects and the connection to get stuck</string>
<string name="button_cancel">Cancel</string>
<string name="button_continue">Continue</string>
<string name="logcat_empty">No logcat output found</string>
<string name="action_send_logcat">Send</string>
<string name="action_refresh_logcat">Refresh</string>
<string name="option_only_show_dns_requests">Filter DNS requests</string>
<string-array name="allowlist_defaults">
<item>No apps bypass by default</item>
<item>All apps bypass by default</item>
<item>System apps bypass by default</item>
</string-array>
<string name="sample_logs">
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
</string>
</resources>