diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index df4269f2..c6293b2f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,6 +10,7 @@
+
@@ -95,6 +96,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/emanuelef/remote_capture/BootReceiver.java b/app/src/main/java/com/emanuelef/remote_capture/BootReceiver.java
new file mode 100644
index 00000000..6a565f82
--- /dev/null
+++ b/app/src/main/java/com/emanuelef/remote_capture/BootReceiver.java
@@ -0,0 +1,67 @@
+/*
+ * This file is part of PCAPdroid.
+ *
+ * PCAPdroid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PCAPdroid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PCAPdroid. If not, see .
+ *
+ * Copyright 2020-21 - Emanuele Faranda
+ */
+
+package com.emanuelef.remote_capture;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.VpnService;
+import android.util.Log;
+
+import androidx.core.content.ContextCompat;
+import androidx.preference.PreferenceManager;
+
+import com.emanuelef.remote_capture.model.CaptureSettings;
+import com.emanuelef.remote_capture.model.Prefs;
+
+public class BootReceiver extends BroadcastReceiver {
+ private static final String TAG = "BootReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ String action = intent.getAction();
+ Log.d(TAG, "onReceive: " + action);
+
+ if(!action.equals(Intent.ACTION_BOOT_COMPLETED) && !action.equals("android.intent.action.QUICKBOOT_POWERON")) {
+ Log.w(TAG, "Unexpected action: " + action);
+ return;
+ }
+
+ if(Prefs.startAtBoot(prefs)) {
+ CaptureSettings settings = new CaptureSettings(prefs);
+
+ if(!settings.root_capture) {
+ Intent vpnPrepareIntent = VpnService.prepare(context);
+ if(vpnPrepareIntent != null) {
+ // Cannot perform the VPN setup without an Activity
+ Utils.showToastLong(context, R.string.vpn_setup_failed);
+ return;
+ }
+ }
+
+ Log.i(TAG, "Starting capture service");
+ Intent capIntent = new Intent(context, CaptureService.class);
+ capIntent.putExtra("settings", settings);
+ ContextCompat.startForegroundService(context, capIntent);
+ }
+ }
+}
diff --git a/app/src/main/java/com/emanuelef/remote_capture/Geolocation.java b/app/src/main/java/com/emanuelef/remote_capture/Geolocation.java
index 262123e9..d98ecdb3 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/Geolocation.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/Geolocation.java
@@ -65,13 +65,12 @@ public class Geolocation {
InputStream is = mContext.getResources().openRawResource(R.raw.dbip_country_lite_2021_11_mmdb_gz);
GZIPInputStream gis = new GZIPInputStream(is);
mCountryReader = new Reader(gis, cache);
- Metadata meta = mCountryReader.getMetadata();
- Log.d(TAG, "Country DB loaded: " + meta.toString());
+ Log.d(TAG, "Country DB loaded: " + mCountryReader.getMetadata());
is = mContext.getResources().openRawResource(R.raw.dbip_asn_lite_2021_11_mmdb_gz);
gis = new GZIPInputStream(is);
mAsnReader = new Reader(gis, cache);
- Log.d(TAG, "ASN DB loaded: " + meta.toString());
+ Log.d(TAG, "ASN DB loaded: " + mAsnReader.getMetadata());
} catch (IOException e) {
e.printStackTrace();
throw new IllegalStateException();
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
index 84ae0ef4..ed4db112 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
@@ -477,10 +477,14 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
}
/* Request a persistent permission to write this URI without invoking the system picker.
- * This is needed to write to the URI when invoking PCAPdroid from other apps via Intents. */
+ * This is needed to write to the URI when invoking PCAPdroid from other apps via Intents
+ * or when starting the capture at boot. */
if(!hasPermission)
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ // Save the URI as a preference
+ mPrefs.edit().putString(Prefs.PREF_PCAP_URI, mPcapUri.toString()).apply();
+
Log.d(TAG, "PCAP URI to write: " + mPcapUri.toString());
toggleService();
}
@@ -496,9 +500,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
private void startCaptureService() {
appStateStarting();
-
- String pcap_uri = ((mPcapUri != null) && (Prefs.getDumpMode(mPrefs) == Prefs.DumpMode.PCAP_FILE)) ? mPcapUri.toString() : "";
- mCapHelper.startCapture(new CaptureSettings(mPrefs, pcap_uri));
+ mCapHelper.startCapture(new CaptureSettings(mPrefs));
}
public void toggleService() {
diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java
index 2b19f6ae..30f20ddb 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java
@@ -21,7 +21,7 @@ public class CaptureSettings implements Serializable {
public final String capture_interface;
public final String pcap_uri;
- public CaptureSettings(SharedPreferences prefs, String _pcap_uri) {
+ public CaptureSettings(SharedPreferences prefs) {
dump_mode = Prefs.getDumpMode(prefs);
app_filter = Prefs.getAppFilter(prefs);
collector_address = Prefs.getCollectorIp(prefs);
@@ -34,7 +34,7 @@ public class CaptureSettings implements Serializable {
root_capture = Prefs.isRootCaptureEnabled(prefs);
pcapdroid_trailer = Prefs.isPcapdroidTrailerEnabled(prefs);
capture_interface = Prefs.getCaptureInterface(prefs);
- pcap_uri = _pcap_uri;
+ pcap_uri = Prefs.getPCAPUri(prefs);
}
public CaptureSettings(Intent intent) {
diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
index 9d3ec5b2..41c7c49d 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
@@ -49,6 +49,7 @@ public class Prefs {
public static final String PREF_VISUALIZATION_MASK = "vis_mask";
public static final String PREF_MALWARE_WHITELIST = "maware_whitelist";
public static final String PREF_PCAPDROID_TRAILER = "pcapdroid_trailer";
+ public static final String PREF_START_AT_BOOT = "start_at_boot";
public enum DumpMode {
NONE,
@@ -86,4 +87,6 @@ public class Prefs {
return(PCAPdroid.getInstance().getBilling(ctx).isPurchased(Billing.MALWARE_DETECTION_SKU)
&& p.getBoolean(PREF_MALWARE_DETECTION, false));
}
+ public static boolean startAtBoot(SharedPreferences p) { return(p.getBoolean(PREF_START_AT_BOOT, false)); }
+ public static String getPCAPUri(SharedPreferences p) { return(p.getString(PREF_PCAP_URI, "")); }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a08b0367..e2e4193c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -212,5 +212,7 @@
ASN
Country: %1$s
Send Report
+ Start at boot
+ If enabled, the capture will start automatically when the device boots.
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index b1cf45d6..9474ca38 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -90,6 +90,13 @@
app:useSimpleSummaryProvider="true"
app:defaultValue="\@inet" />
+
+