NetGuard/app/src/main/java/eu/faircode/netguard/AdapterLog.java

369 lines
14 KiB
Java
Raw Normal View History

2016-01-05 12:40:02 +00:00
package eu.faircode.netguard;
2016-01-30 13:26:30 +00:00
/*
This file is part of NetGuard.
NetGuard 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.
NetGuard 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 NetGuard. If not, see <http://www.gnu.org/licenses/>.
2017-12-24 09:12:10 +00:00
Copyright 2015-2018 by Marcel Bokhorst (M66B)
2016-01-30 13:26:30 +00:00
*/
2016-01-05 12:40:02 +00:00
import android.content.Context;
2016-01-23 15:48:51 +00:00
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
2016-01-05 12:40:02 +00:00
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
2016-01-30 09:59:19 +00:00
import android.os.AsyncTask;
import android.os.Build;
2016-01-23 15:48:51 +00:00
import android.preference.PreferenceManager;
import android.text.TextUtils;
2016-01-23 15:48:51 +00:00
import android.util.Log;
import android.util.TypedValue;
2016-01-05 12:40:02 +00:00
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
2016-01-05 12:40:02 +00:00
import android.widget.TextView;
import java.net.InetAddress;
import java.net.UnknownHostException;
2016-01-05 12:40:02 +00:00
import java.text.SimpleDateFormat;
2016-11-11 17:21:29 +00:00
import java.util.List;
2016-01-05 12:40:02 +00:00
2018-11-17 16:32:36 +00:00
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.ViewCompat;
public class AdapterLog extends CursorAdapter {
2016-01-23 15:48:51 +00:00
private static String TAG = "NetGuard.Log";
private boolean resolve;
2016-02-23 08:12:25 +00:00
private boolean organization;
2016-01-05 12:40:02 +00:00
private int colTime;
private int colVersion;
private int colProtocol;
private int colFlags;
private int colSAddr;
private int colSPort;
private int colDAddr;
private int colDPort;
2016-01-30 09:59:19 +00:00
private int colDName;
private int colUid;
private int colData;
private int colAllowed;
private int colConnection;
private int colInteractive;
private int colorOn;
private int colorOff;
private int iconSize;
2016-10-12 12:59:39 +00:00
private InetAddress dns1 = null;
private InetAddress dns2 = null;
2016-01-23 15:48:51 +00:00
private InetAddress vpn4 = null;
private InetAddress vpn6 = null;
2016-01-05 12:40:02 +00:00
2016-02-23 08:12:25 +00:00
public AdapterLog(Context context, Cursor cursor, boolean resolve, boolean organization) {
2016-01-05 12:40:02 +00:00
super(context, cursor, 0);
this.resolve = resolve;
2016-02-23 08:12:25 +00:00
this.organization = organization;
2016-01-05 12:40:02 +00:00
colTime = cursor.getColumnIndex("time");
colVersion = cursor.getColumnIndex("version");
colProtocol = cursor.getColumnIndex("protocol");
colFlags = cursor.getColumnIndex("flags");
colSAddr = cursor.getColumnIndex("saddr");
colSPort = cursor.getColumnIndex("sport");
colDAddr = cursor.getColumnIndex("daddr");
colDPort = cursor.getColumnIndex("dport");
2016-01-30 09:59:19 +00:00
colDName = cursor.getColumnIndex("dname");
colUid = cursor.getColumnIndex("uid");
colData = cursor.getColumnIndex("data");
colAllowed = cursor.getColumnIndex("allowed");
colConnection = cursor.getColumnIndex("connection");
colInteractive = cursor.getColumnIndex("interactive");
2016-01-23 15:48:51 +00:00
TypedValue tv = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorOn, tv, true);
colorOn = tv.data;
context.getTheme().resolveAttribute(R.attr.colorOff, tv, true);
colorOff = tv.data;
iconSize = Util.dips2pixels(24, context);
2016-01-23 15:48:51 +00:00
try {
2016-11-11 17:21:29 +00:00
List<InetAddress> lstDns = ServiceSinkhole.getDns(context);
dns1 = (lstDns.size() > 0 ? lstDns.get(0) : null);
dns2 = (lstDns.size() > 1 ? lstDns.get(1) : null);
2016-01-23 15:48:51 +00:00
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
vpn4 = InetAddress.getByName(prefs.getString("vpn4", "10.1.10.1"));
vpn6 = InetAddress.getByName(prefs.getString("vpn6", "fd00:1:fd00:1:fd00:1:fd00:1"));
} catch (UnknownHostException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
2016-01-05 12:40:02 +00:00
}
2016-02-01 19:45:35 +00:00
public void setResolve(boolean resolve) {
this.resolve = resolve;
}
2016-02-23 08:12:25 +00:00
public void setOrganization(boolean organization) {
this.organization = organization;
}
2016-01-05 12:40:02 +00:00
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.log, parent, false);
}
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
// Get values
2016-01-06 10:12:37 +00:00
long time = cursor.getLong(colTime);
int version = (cursor.isNull(colVersion) ? -1 : cursor.getInt(colVersion));
int protocol = (cursor.isNull(colProtocol) ? -1 : cursor.getInt(colProtocol));
String flags = cursor.getString(colFlags);
String saddr = cursor.getString(colSAddr);
int sport = (cursor.isNull(colSPort) ? -1 : cursor.getInt(colSPort));
String daddr = cursor.getString(colDAddr);
int dport = (cursor.isNull(colDPort) ? -1 : cursor.getInt(colDPort));
2016-01-30 09:59:19 +00:00
String dname = (cursor.isNull(colDName) ? null : cursor.getString(colDName));
2016-01-10 13:26:37 +00:00
int uid = (cursor.isNull(colUid) ? -1 : cursor.getInt(colUid));
String data = cursor.getString(colData);
int allowed = (cursor.isNull(colAllowed) ? -1 : cursor.getInt(colAllowed));
int connection = (cursor.isNull(colConnection) ? -1 : cursor.getInt(colConnection));
int interactive = (cursor.isNull(colInteractive) ? -1 : cursor.getInt(colInteractive));
2016-01-05 12:40:02 +00:00
// Get views
2017-08-05 08:27:27 +00:00
TextView tvTime = view.findViewById(R.id.tvTime);
TextView tvProtocol = view.findViewById(R.id.tvProtocol);
TextView tvFlags = view.findViewById(R.id.tvFlags);
TextView tvSAddr = view.findViewById(R.id.tvSAddr);
TextView tvSPort = view.findViewById(R.id.tvSPort);
final TextView tvDaddr = view.findViewById(R.id.tvDAddr);
TextView tvDPort = view.findViewById(R.id.tvDPort);
final TextView tvOrganization = view.findViewById(R.id.tvOrganization);
final ImageView ivIcon = view.findViewById(R.id.ivIcon);
TextView tvUid = view.findViewById(R.id.tvUid);
TextView tvData = view.findViewById(R.id.tvData);
ImageView ivConnection = view.findViewById(R.id.ivConnection);
ImageView ivInteractive = view.findViewById(R.id.ivInteractive);
2016-01-08 16:21:50 +00:00
2016-02-23 08:12:25 +00:00
// Show time
tvTime.setText(new SimpleDateFormat("HH:mm:ss").format(time));
2016-02-23 08:12:25 +00:00
// Show connection type
if (connection <= 0)
ivConnection.setImageResource(allowed > 0 ? R.drawable.host_allowed : R.drawable.host_blocked);
2016-01-19 19:58:51 +00:00
else {
if (allowed > 0)
ivConnection.setImageResource(connection == 1 ? R.drawable.wifi_on : R.drawable.other_on);
else
ivConnection.setImageResource(connection == 1 ? R.drawable.wifi_off : R.drawable.other_off);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Drawable wrap = DrawableCompat.wrap(ivConnection.getDrawable());
DrawableCompat.setTint(wrap, allowed > 0 ? colorOn : colorOff);
2016-01-19 19:58:51 +00:00
}
2016-02-23 08:12:25 +00:00
// Show if screen on
if (interactive <= 0)
ivInteractive.setImageDrawable(null);
else {
ivInteractive.setImageResource(R.drawable.screen_on);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Drawable wrap = DrawableCompat.wrap(ivInteractive.getDrawable());
DrawableCompat.setTint(wrap, colorOn);
}
}
2016-01-08 16:21:50 +00:00
2016-02-23 08:12:25 +00:00
// Show protocol name
tvProtocol.setText(Util.getProtocolName(protocol, version, false));
2016-01-08 16:21:50 +00:00
2016-02-23 08:12:25 +00:00
// SHow TCP flags
2016-01-26 08:09:00 +00:00
tvFlags.setText(flags);
2016-02-23 08:12:25 +00:00
tvFlags.setVisibility(TextUtils.isEmpty(flags) ? View.GONE : View.VISIBLE);
2016-01-05 12:40:02 +00:00
2016-02-23 08:12:25 +00:00
// Show source and destination port
2016-02-04 12:00:33 +00:00
if (protocol == 6 || protocol == 17) {
tvSPort.setText(sport < 0 ? "" : getKnownPort(sport));
tvDPort.setText(dport < 0 ? "" : getKnownPort(dport));
} else {
tvSPort.setText(sport < 0 ? "" : Integer.toString(sport));
tvDPort.setText(dport < 0 ? "" : Integer.toString(dport));
}
// Application icon
ApplicationInfo info = null;
PackageManager pm = context.getPackageManager();
String[] pkg = pm.getPackagesForUid(uid);
if (pkg != null && pkg.length > 0)
try {
info = pm.getApplicationInfo(pkg[0], 0);
} catch (PackageManager.NameNotFoundException ignored) {
}
2017-08-04 06:23:43 +00:00
2016-03-10 09:07:32 +00:00
if (info == null)
2016-03-09 17:15:02 +00:00
ivIcon.setImageDrawable(null);
else {
if (info.icon <= 0)
ivIcon.setImageResource(android.R.drawable.sym_def_app_icon);
else {
Uri uri = Uri.parse("android.resource://" + info.packageName + "/" + info.icon);
GlideApp.with(context)
.load(uri)
2018-03-23 06:22:17 +00:00
//.diskCacheStrategy(DiskCacheStrategy.NONE)
//.skipMemoryCache(true)
.override(iconSize, iconSize)
.into(ivIcon);
2017-08-04 06:23:43 +00:00
}
}
2017-06-16 20:39:21 +00:00
boolean we = (android.os.Process.myUid() == uid);
2016-01-10 13:26:37 +00:00
// https://android.googlesource.com/platform/system/core/+/master/include/private/android_filesystem_config.h
uid = uid % 100000; // strip off user ID
if (uid == -1)
tvUid.setText("");
else if (uid == 0)
tvUid.setText(context.getString(R.string.title_root));
2016-01-10 13:26:37 +00:00
else if (uid == 9999)
tvUid.setText("-"); // nobody
else
tvUid.setText(Integer.toString(uid));
2016-02-23 08:12:25 +00:00
// Show source address
tvSAddr.setText(getKnownAddress(saddr));
2016-02-23 08:12:25 +00:00
// Show destination address
2017-06-16 20:39:21 +00:00
if (!we && resolve && !isKnownAddress(daddr))
2016-01-30 09:59:19 +00:00
if (dname == null) {
2016-08-01 17:28:18 +00:00
tvDaddr.setText(daddr);
new AsyncTask<String, Object, String>() {
@Override
protected void onPreExecute() {
ViewCompat.setHasTransientState(tvDaddr, true);
}
2016-02-14 09:16:44 +00:00
2016-08-01 17:28:18 +00:00
@Override
protected String doInBackground(String... args) {
try {
return InetAddress.getByName(args[0]).getHostName();
} catch (UnknownHostException ignored) {
return args[0];
2016-02-14 09:16:44 +00:00
}
2016-08-01 17:28:18 +00:00
}
2016-02-14 09:16:44 +00:00
2016-08-01 17:28:18 +00:00
@Override
protected void onPostExecute(String name) {
tvDaddr.setText(">" + name);
ViewCompat.setHasTransientState(tvDaddr, false);
}
}.execute(daddr);
2016-01-30 09:59:19 +00:00
} else
tvDaddr.setText(dname);
else
tvDaddr.setText(getKnownAddress(daddr));
2016-02-23 08:12:25 +00:00
// Show organization
tvOrganization.setVisibility(View.GONE);
2017-06-16 20:39:21 +00:00
if (!we && organization) {
2016-08-01 17:28:18 +00:00
if (!isKnownAddress(daddr))
2016-02-23 08:12:25 +00:00
new AsyncTask<String, Object, String>() {
@Override
protected void onPreExecute() {
2016-08-01 17:28:18 +00:00
ViewCompat.setHasTransientState(tvOrganization, true);
2016-02-23 08:12:25 +00:00
}
@Override
protected String doInBackground(String... args) {
try {
return Util.getOrganization(args[0]);
} catch (Throwable ex) {
Log.w(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
return null;
}
}
@Override
protected void onPostExecute(String organization) {
2016-08-01 17:28:18 +00:00
if (organization != null) {
2016-02-23 08:12:25 +00:00
tvOrganization.setText(organization);
tvOrganization.setVisibility(View.VISIBLE);
}
2016-08-01 17:28:18 +00:00
ViewCompat.setHasTransientState(tvOrganization, false);
2016-02-23 08:12:25 +00:00
}
}.execute(daddr);
2016-02-23 08:12:25 +00:00
}
// Show extra data
if (TextUtils.isEmpty(data)) {
tvData.setText("");
tvData.setVisibility(View.GONE);
} else {
tvData.setText(data);
tvData.setVisibility(View.VISIBLE);
}
2016-01-23 15:48:51 +00:00
}
2016-01-26 09:10:01 +00:00
public boolean isKnownAddress(String addr) {
2016-01-23 15:48:51 +00:00
try {
InetAddress a = InetAddress.getByName(addr);
2016-10-12 12:59:39 +00:00
if (a.equals(dns1) || a.equals(dns2) || a.equals(vpn4) || a.equals(vpn6))
2016-01-23 15:48:51 +00:00
return true;
} catch (UnknownHostException ignored) {
}
return false;
}
private String getKnownAddress(String addr) {
try {
InetAddress a = InetAddress.getByName(addr);
2016-10-12 12:59:39 +00:00
if (a.equals(dns1) || a.equals(dns2))
2016-01-30 09:59:19 +00:00
return "dns";
2016-01-23 15:48:51 +00:00
if (a.equals(vpn4) || a.equals(vpn6))
return "vpn";
} catch (UnknownHostException ignored) {
}
return addr;
2016-01-05 12:40:02 +00:00
}
2016-01-26 09:10:01 +00:00
private String getKnownPort(int port) {
2016-02-03 08:04:07 +00:00
// https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports
switch (port) {
case 7:
return "echo";
case 25:
return "smtp";
case 53:
return "dns";
case 80:
return "http";
case 110:
return "pop3";
case 143:
return "imap";
case 443:
return "https";
case 465:
return "smtps";
case 993:
return "imaps";
case 995:
return "pop3s";
default:
return Integer.toString(port);
}
2016-01-26 09:10:01 +00:00
}
2016-01-05 12:40:02 +00:00
}