diff --git a/app/src/main/java/com/emanuelef/remote_capture/Log.java b/app/src/main/java/com/emanuelef/remote_capture/Log.java
index c93459ee..53e1f3f7 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/Log.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/Log.java
@@ -24,18 +24,20 @@ import androidx.annotation.Nullable;
public class Log {
public static final int LOG_LEVEL_INFO = 4;
+ public static final String DEFAULT_LOGGER_PATH = "pcapdroid.log";
+ public static final String ROOT_LOGGER_PATH = "pcapd.log";
+ public static final String MITM_LOGGER_PATH = "mitmaddon.log";
public static int DEFAULT_LOGGER;
public static int MITMADDON_LOGGER;
- public static void init(String basedir) {
- DEFAULT_LOGGER = CaptureService.initLogger(basedir + "/pcapdroid.log", LOG_LEVEL_INFO);
- MITMADDON_LOGGER = CaptureService.initLogger(basedir + "/mitmaddon.log", LOG_LEVEL_INFO);
- android.util.Log.e("tag", basedir);
+ public static void init(String cachedir) {
+ DEFAULT_LOGGER = CaptureService.initLogger(cachedir + "/" + DEFAULT_LOGGER_PATH, LOG_LEVEL_INFO);
+ MITMADDON_LOGGER = CaptureService.initLogger(cachedir + "/" + MITM_LOGGER_PATH, LOG_LEVEL_INFO);
}
public static void writeLog(int logger, int level, @Nullable String tag, @NonNull String message) {
if(!PCAPdroid.isUnderTest())
- CaptureService.writeLog(logger, level, "[" + tag + "] " + message);
+ CaptureService.writeLog(logger, level, ((tag != null) ? ("[" + tag + "] ") : "") + message);
}
public static void d(@Nullable String tag, @NonNull String message) {
@@ -47,18 +49,44 @@ public class Log {
writeLog(DEFAULT_LOGGER, android.util.Log.INFO, tag, message);
}
+ public static void i(int logger, @NonNull String message) {
+ writeLog(logger, android.util.Log.INFO, null, message);
+ }
+
public static void w(@Nullable String tag, @NonNull String message) {
android.util.Log.w(tag, message);
writeLog(DEFAULT_LOGGER, android.util.Log.WARN, tag, message);
}
+ public static void w(int logger, @NonNull String message) {
+ writeLog(logger, android.util.Log.WARN, null, message);
+ }
+
public static void e(@Nullable String tag, @NonNull String message) {
android.util.Log.e(tag, message);
writeLog(DEFAULT_LOGGER, android.util.Log.ERROR, tag, message);
}
+ public static void e(int logger, @NonNull String message) {
+ writeLog(logger, android.util.Log.ERROR, null, message);
+ }
+
public static void wtf(@Nullable String tag, @NonNull String message) {
android.util.Log.wtf(tag, message);
writeLog(DEFAULT_LOGGER, android.util.Log.ASSERT, tag, message); // ANDROID_LOG_FATAL
}
+
+ public static void level(int logger, int level, @NonNull String message) {
+ switch (level) {
+ case android.util.Log.INFO:
+ Log.i(logger, message);
+ break;
+ case android.util.Log.WARN:
+ Log.w(logger, message);
+ break;
+ case android.util.Log.ERROR:
+ Log.e(logger, message);
+ break;
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java b/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java
index e05f6490..0ddba0ca 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java
@@ -48,8 +48,8 @@ import java.io.IOException;
import java.lang.ref.WeakReference;
public class MitmAddon {
- public static final long PACKAGE_VERSION_CODE = 9;
- public static final String PACKAGE_VERSION_NAME = "v0.9";
+ public static final long PACKAGE_VERSION_CODE = 10;
+ public static final String PACKAGE_VERSION_NAME = "v0.10";
public static final String REPOSITORY = "https://github.com/emanuele-f/PCAPdroid-mitm";
private static final String TAG = "MitmAddon";
private final Context mContext;
diff --git a/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java b/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java
index 7be64528..ace5e1c8 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java
@@ -91,6 +91,7 @@ public class MitmReceiver implements Runnable, ConnectionsListener, MitmListener
WEBSOCKET_CLIENT_MSG,
WEBSOCKET_SERVER_MSG,
MASTER_SECRET,
+ LOG,
}
private static class PendingMessage {
@@ -234,7 +235,9 @@ public class MitmReceiver implements Runnable, ConnectionsListener, MitmListener
if(type == MsgType.MASTER_SECRET)
logMasterSecret(msg);
- else if(type == MsgType.RUNNING) {
+ else if(type == MsgType.LOG) {
+ handleLog(msg);
+ } else if(type == MsgType.RUNNING) {
Log.i(TAG, "MITM proxy is running");
proxyRunning.postValue(true);
} else {
@@ -347,6 +350,8 @@ public class MitmReceiver implements Runnable, ConnectionsListener, MitmListener
return MsgType.WEBSOCKET_SERVER_MSG;
case "secret":
return MsgType.MASTER_SECRET;
+ case "log":
+ return MsgType.LOG;
default:
return MsgType.UNKNOWN;
}
@@ -362,6 +367,19 @@ public class MitmReceiver implements Runnable, ConnectionsListener, MitmListener
mKeylog.write(0xa);
}
+ private void handleLog(byte[] message) {
+ try {
+ String msg = new String(message, StandardCharsets.US_ASCII);
+
+ // format: 1:message
+ if (msg.length() < 3)
+ return;
+
+ int lvl = Integer.parseInt(msg.substring(0, 1));
+ Log.level(Log.MITMADDON_LOGGER, lvl, msg.substring(2));
+ } catch (NumberFormatException ignored) {}
+ }
+
public boolean isProxyRunning() {
return Boolean.TRUE.equals(proxyRunning.getValue());
}
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/BaseActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/BaseActivity.java
index b20a61e7..49c8bc18 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/BaseActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/BaseActivity.java
@@ -41,6 +41,10 @@ class BaseActivity extends AppCompatActivity {
return null;
}
+ protected Fragment getFragmentAtPos(int pos) {
+ return getSupportFragmentManager().findFragmentByTag("f" + pos);
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mBackAction && (item.getItemId() == android.R.id.home)) {
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java
index f3c02ffb..34705e9d 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java
@@ -73,7 +73,7 @@ public class ConnectionDetailsActivity extends BaseActivity implements Connectio
super.onCreate(savedInstanceState);
setTitle(R.string.connection_details);
displayBackAction();
- setContentView(R.layout.activity_connection_details);
+ setContentView(R.layout.tabs_activity_fixed);
int incr_id = getIntent().getIntExtra(CONN_ID_KEY, -1);
if(incr_id != -1) {
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/LogviewActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/LogviewActivity.java
index 1b953acf..6488d991 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/LogviewActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/LogviewActivity.java
@@ -23,70 +23,112 @@ import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.view.MenuProvider;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+import androidx.viewpager2.widget.ViewPager2;
+import com.emanuelef.remote_capture.Log;
import com.emanuelef.remote_capture.R;
import com.emanuelef.remote_capture.Utils;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
+import com.emanuelef.remote_capture.fragments.LogviewFragment;
+import com.google.android.material.tabs.TabLayoutMediator;
public class LogviewActivity extends BaseActivity implements MenuProvider {
private static final String TAG = "LogviewActivity";
- private String mLogText;
+ private ViewPager2 mPager;
+ private StateAdapter mPagerAdapter;
+
+ private static final int POS_APP_LOG = 0;
+ private static final int POS_ROOT_LOG = 1;
+ private static final int POS_MITM_LOG = 2;
+ private static final int NUM_POS = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setTitle(R.string.root_log);
- setContentView(R.layout.logview_activity);
+ setTitle(R.string.app_log);
+ setContentView(R.layout.tabs_activity_fixed);
addMenuProvider(this);
- TextView logView = findViewById(R.id.log);
- mLogText = readLog();
-
- logView.setText(!mLogText.isEmpty() ? mLogText : getString(R.string.error));
+ mPager = findViewById(R.id.pager);
+ setupTabs();
}
- private String readLog() {
- try {
- String logpath = getCacheDir().getPath() + "/pcapd.log";
- BufferedReader reader = new BufferedReader(new FileReader(logpath));
+ private void setupTabs() {
+ mPagerAdapter = new StateAdapter(this);
+ mPager.setAdapter(mPagerAdapter);
- StringBuilder builder = new StringBuilder();
- String line;
+ new TabLayoutMediator(findViewById(R.id.tablayout), mPager, (tab, position) ->
+ tab.setText(getString(mPagerAdapter.getPageTitle(position)))
+ ).attach();
+ }
- while((line = reader.readLine()) != null) {
- builder.append(line);
- builder.append("\n");
- }
+ private static class StateAdapter extends FragmentStateAdapter {
+ final String mCacheDir;
- return builder.toString();
- } catch (IOException e) {
- e.printStackTrace();
+ StateAdapter(final FragmentActivity fa) {
+ super(fa);
+ mCacheDir = fa.getCacheDir().getAbsolutePath();
}
- return "";
+ @NonNull
+ @Override
+ public Fragment createFragment(int pos) {
+ switch (pos) {
+ case POS_APP_LOG:
+ return LogviewFragment.newInstance(mCacheDir + "/" + Log.DEFAULT_LOGGER_PATH);
+ case POS_ROOT_LOG:
+ return LogviewFragment.newInstance(mCacheDir + "/" + Log.ROOT_LOGGER_PATH);
+ case POS_MITM_LOG:
+ default:
+ return LogviewFragment.newInstance(mCacheDir + "/" + Log.MITM_LOGGER_PATH);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return NUM_POS;
+ }
+
+ public int getPageTitle(final int pos) {
+ switch (pos) {
+ case POS_APP_LOG:
+ return R.string.app;
+ case POS_ROOT_LOG:
+ return R.string.root;
+ case POS_MITM_LOG:
+ default:
+ return R.string.mitm_addon;
+ }
+ }
}
@Override
public void onCreateMenu(@NonNull Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.copy_share_menu, menu);
+ inflater.inflate(R.menu.log_menu, menu);
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
+ LogviewFragment fragment = (LogviewFragment) getFragmentAtPos(mPager.getCurrentItem());
+ if(fragment == null)
+ return false;
- if(id == R.id.copy_to_clipboard) {
- Utils.copyToClipboard(this, mLogText);
+ String logText = fragment.getLog();
+
+ if(id == R.id.reload) {
+ fragment.reloadLog();
+ return true;
+ } else if(id == R.id.copy_to_clipboard) {
+ Utils.copyToClipboard(this, logText);
return true;
} else if(id == R.id.share) {
- Utils.shareText(this, getString(R.string.root_log), mLogText);
+ Utils.shareText(this, getString(R.string.app_log), logText);
return true;
}
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 646e2c3f..d9352d6b 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
@@ -211,8 +211,6 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
protected void onResume() {
super.onResume();
- Menu navMenu = mNavView.getMenu();
- navMenu.findItem(R.id.open_root_log).setVisible(Prefs.isRootCaptureEnabled(mPrefs));
checkPaidDrawerEntries();
}
@@ -483,7 +481,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
} else if(id == R.id.firewall) {
Intent intent = new Intent(MainActivity.this, FirewallActivity.class);
startActivity(intent);
- } else if(id == R.id.open_root_log) {
+ } else if(id == R.id.open_log) {
Intent intent = new Intent(MainActivity.this, LogviewActivity.class);
startActivity(intent);
} else if (id == R.id.action_donate) {
diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/LogviewFragment.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/LogviewFragment.java
new file mode 100644
index 00000000..7258e3be
--- /dev/null
+++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/LogviewFragment.java
@@ -0,0 +1,93 @@
+/*
+ * 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