From 8399e30fabd5fa1058c0b18f77a47a84b24cefbf Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Sat, 6 Nov 2021 19:30:43 +0100 Subject: [PATCH] Add ability to start at boot Closes #100 --- app/src/main/AndroidManifest.xml | 10 +++ .../remote_capture/BootReceiver.java | 67 +++++++++++++++++++ .../emanuelef/remote_capture/Geolocation.java | 5 +- .../activities/MainActivity.java | 10 +-- .../remote_capture/model/CaptureSettings.java | 4 +- .../emanuelef/remote_capture/model/Prefs.java | 3 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/root_preferences.xml | 7 ++ 8 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/emanuelef/remote_capture/BootReceiver.java 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" /> + +