Refresh connection details activity

This commit is contained in:
emanuele-f 2021-03-24 00:52:21 +01:00
parent ab3d684fe7
commit 429215400e
4 changed files with 147 additions and 28 deletions

View File

@ -182,10 +182,14 @@ public class ConnectionsRegister {
// Send the first update to sync it
listener.connectionsChanges(num_items);
Log.d(TAG, "(add) new connections listeners size: " + mListeners.size());
}
public synchronized void removeListener(ConnectionsListener listener) {
mListeners.remove(listener);
Log.d(TAG, "(remove) new connections listeners size: " + mListeners.size());
}
public int getConnCount() {
@ -224,6 +228,21 @@ public class ConnectionsRegister {
return null;
}
public synchronized int getConnPositionByIncrId(int incr_id) {
int first = firstPos();
for(int i = 0; i < num_items; i++) {
int pos = (first + i) % size;
ConnectionDescriptor item = items_ring[pos];
if((item != null) && (item.incr_id == incr_id)) {
return pos;
}
}
return -1;
}
public synchronized List<AppStats> getAppsStats() {
ArrayList<AppStats> rv = new ArrayList<>(mAppsStats.size());

View File

@ -25,6 +25,9 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -32,11 +35,14 @@ import android.view.View;
import android.widget.TableLayout;
import android.widget.TextView;
import com.emanuelef.remote_capture.CaptureService;
import com.emanuelef.remote_capture.ConnectionsRegister;
import com.emanuelef.remote_capture.R;
import com.emanuelef.remote_capture.Utils;
import com.emanuelef.remote_capture.interfaces.ConnectionsListener;
import com.emanuelef.remote_capture.model.ConnectionDescriptor;
public class ConnectionDetailsActivity extends BaseActivity {
public class ConnectionDetailsActivity extends BaseActivity implements ConnectionsListener {
private static final String TAG = "ConnectionDetails";
public static final String CONN_EXTRA_KEY = "conn_descriptor";
public static final String APP_NAME_EXTRA_KEY = "app_name";
@ -44,10 +50,13 @@ public class ConnectionDetailsActivity extends BaseActivity {
private TextView mBytesView;
private TextView mPacketsView;
private TextView mDurationView;
private ConnectionDescriptor conn;
private ConnectionDescriptor mConn;
private TextView mStatus;
private TextView mFirstSeen;
private TextView mLastSeen;
private Handler mHandler;
private int mConnPos;
private boolean mListenerSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -55,7 +64,9 @@ public class ConnectionDetailsActivity extends BaseActivity {
setTitle(R.string.connection_details);
setContentView(R.layout.activity_connection_details);
conn = (ConnectionDescriptor) getIntent().getSerializableExtra(CONN_EXTRA_KEY);
mConn = (ConnectionDescriptor) getIntent().getSerializableExtra(CONN_EXTRA_KEY);
mHandler = new Handler(Looper.getMainLooper());
mConnPos = -1;
String app_name = getIntent().getStringExtra(APP_NAME_EXTRA_KEY);
TextView app = findViewById(R.id.detail_app);
@ -75,41 +86,95 @@ public class ConnectionDetailsActivity extends BaseActivity {
mFirstSeen = findViewById(R.id.first_seen);
mLastSeen = findViewById(R.id.last_seen);
String l4proto = Utils.proto2str(conn.ipproto);
String l4proto = Utils.proto2str(mConn.ipproto);
if(conn != null) {
if(!conn.l7proto.equals(l4proto))
proto.setText(String.format(getResources().getString(R.string.app_and_proto), conn.l7proto, l4proto));
if(mConn != null) {
if(!mConn.l7proto.equals(l4proto))
proto.setText(String.format(getResources().getString(R.string.app_and_proto), mConn.l7proto, l4proto));
else
proto.setText(conn.l7proto);
proto.setText(mConn.l7proto);
source.setText(String.format(getResources().getString(R.string.ip_and_port), conn.src_ip, conn.src_port));
destination.setText(String.format(getResources().getString(R.string.ip_and_port), conn.dst_ip, conn.dst_port));
source.setText(String.format(getResources().getString(R.string.ip_and_port), mConn.src_ip, mConn.src_port));
destination.setText(String.format(getResources().getString(R.string.ip_and_port), mConn.dst_ip, mConn.dst_port));
if((conn.info != null) && (!conn.info.isEmpty())) {
if(conn.l7proto.equals("DNS"))
if((mConn.info != null) && (!mConn.info.isEmpty())) {
if(mConn.l7proto.equals("DNS"))
info_label.setText(R.string.query);
else if(conn.l7proto.equals("HTTP"))
else if(mConn.l7proto.equals("HTTP"))
info_label.setText(R.string.host);
info.setText(conn.info);
info.setText(mConn.info);
} else
info_row.setVisibility(View.GONE);
updateStats();
if(app_name != null)
app.setText(String.format(getResources().getString(R.string.app_and_proto), app_name, Integer.toString(mConn.uid)));
else
app.setText(Integer.toString(mConn.uid));
if(!mConn.url.isEmpty())
url.setText(mConn.url);
else
url_row.setVisibility(View.GONE);
updateStats(mConn);
}
if(app_name != null)
app.setText(String.format(getResources().getString(R.string.app_and_proto), app_name, Integer.toString(conn.uid)));
else
app.setText(Integer.toString(conn.uid));
if(!conn.url.isEmpty())
url.setText(conn.url);
else
url_row.setVisibility(View.GONE);
}
private void updateStats() {
@Override
public void onResume() {
super.onResume();
mConnPos = -1;
// Closed connections won't be updated
if(mConn.status < ConnectionDescriptor.CONN_STATUS_CLOSED)
registerConnsListener();
}
@Override
public void onPause() {
super.onPause();
unregisterConnsListener();
}
private void registerConnsListener() {
ConnectionsRegister reg = CaptureService.getConnsRegister();
if((reg != null) && !mListenerSet) {
mConnPos = reg.getConnPositionByIncrId(mConn.incr_id);
if(mConnPos != -1) {
ConnectionDescriptor conn = reg.getConn(mConnPos);
if(conn != null) {
if(conn.status < ConnectionDescriptor.CONN_STATUS_CLOSED) {
Log.d(TAG, "Adding connections listener");
reg.addListener(this);
mListenerSet = true;
}
updateStats(conn);
}
}
}
}
private void unregisterConnsListener() {
if(mListenerSet) {
ConnectionsRegister reg = CaptureService.getConnsRegister();
if(reg != null) {
Log.d(TAG, "Removing connections listener");
reg.removeListener(this);
}
mListenerSet = false;
}
mConnPos = -1;
}
private void updateStats(ConnectionDescriptor conn) {
if(conn != null) {
mBytesView.setText(String.format(getResources().getString(R.string.up_and_down), Utils.formatBytes(conn.rcvd_bytes), Utils.formatBytes(conn.sent_bytes)));
mPacketsView.setText(String.format(getResources().getString(R.string.up_and_down), Utils.formatPkts(conn.rcvd_pkts), Utils.formatPkts(conn.sent_pkts)));
@ -117,6 +182,9 @@ public class ConnectionDetailsActivity extends BaseActivity {
mFirstSeen.setText(Utils.formatEpochFull(this, conn.first_seen));
mLastSeen.setText(Utils.formatEpochFull(this, conn.last_seen));
mStatus.setText(conn.getStatusLabel(this));
if(conn.status >= ConnectionDescriptor.CONN_STATUS_CLOSED)
unregisterConnsListener();
}
}
@ -156,4 +224,35 @@ public class ConnectionDetailsActivity extends BaseActivity {
return super.onOptionsItemSelected(item);
}
@Override
public void connectionsChanges(int num_connetions) {}
@Override
public void connectionsAdded(int start, int count) {}
@Override
public void connectionsRemoved(int start, int count) {}
@Override
public void connectionsUpdated(int[] positions) {
ConnectionsRegister reg = CaptureService.getConnsRegister();
if((reg == null) || (mConnPos < 0))
return;
for(int pos : positions) {
if(pos == mConnPos) {
ConnectionDescriptor conn = reg.getConn(pos);
// Double check the incr_id
if((conn != null) && (conn.incr_id == mConn.incr_id))
mHandler.post(() -> updateStats(conn));
else
unregisterConnsListener();
break;
}
}
}
}

View File

@ -97,6 +97,7 @@ public class ConnectionDescriptor implements Serializable {
if(status >= CONN_STATUS_CLOSED) {
switch(status) {
case CONN_STATUS_CLOSED:
case CONN_STATUS_RESET:
resid = R.string.conn_status_closed;
break;
case CONN_STATUS_UNREACHABLE:

View File

@ -81,10 +81,10 @@
<string name="notification_msg">%1$s catturati, %2$s connessioni</string>
<string name="no_app_filter">Nessun filtro app impostato</string>
<string name="proto_and_port">%1$s, %2$d</string>
<string name="conn_status_open">Aperta</string>
<string name="conn_status_open">Attiva</string>
<string name="first_seen">Inizio</string>
<string name="last_seen">Fine</string>
<string name="conn_status_closed">Chiusa</string>
<string name="conn_status_closed">Terminata</string>
<string name="copy_to_clipboard">Copia negli appunti</string>
<string name="copied_to_clipboard">Copiato negli appunti!</string>
<string name="connections_csv_fields_v1">IPProto,SrcIP,SrcPort,DstIp,DstPort,Uid,App,Proto,Status,Info,BytesSent,BytesRcvd,PktsSent,PktsRcvd,FirstSeen,LastSeen</string>