[tor-commits] [orbot/master] re-enable traffic notification info and improve debug output
n8fr8 at torproject.org
n8fr8 at torproject.org
Tue Apr 28 21:05:01 UTC 2020
commit 7cd5a2884d3d2980c92b323ad3191afe48736c38
Author: n8fr8 <nathan at guardianproject.info>
Date: Mon Dec 9 15:45:12 2019 -0500
re-enable traffic notification info and improve debug output
- tor entrance IP now displayed in logs if you enable debug option
---
.../android/service/TorEventHandler.java | 161 +++++++--------------
.../org/torproject/android/service/TorService.java | 37 ++---
.../android/service/util/ExternalIPFetcher.java | 95 ++++++++++++
.../android/service/vpn/OrbotVpnManager.java | 24 ++-
.../android/service/vpn/TorVpnService.java | 4 +-
orbotservice/src/main/res/drawable/ic_onion.xml | 9 ++
.../src/main/res/drawable/ic_stat_tor_xfer.png | Bin 0 -> 990 bytes
orbotservice/src/main/res/drawable/ic_transfer.xml | 9 ++
8 files changed, 194 insertions(+), 145 deletions(-)
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
index c67afff4..8635eb7b 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorEventHandler.java
@@ -4,6 +4,7 @@ import android.text.TextUtils;
import net.freehaven.tor.control.EventHandler;
+import org.torproject.android.service.util.ExternalIPFetcher;
import org.torproject.android.service.util.Prefs;
import java.text.NumberFormat;
@@ -32,12 +33,14 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
public class Node
{
- String status;
- String id;
- String name;
- String ipAddress;
- String country;
- String organization;
+ public String status;
+ public String id;
+ public String name;
+ public String ipAddress;
+ public String country;
+ public String organization;
+
+ public boolean isFetchingInfo = false;
}
public HashMap<String,Node> getNodes ()
@@ -102,7 +105,6 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
if (read != lastRead || written != lastWritten)
{
- /**
StringBuilder sb = new StringBuilder();
sb.append(formatCount(read));
sb.append(" \u2193");
@@ -116,7 +118,6 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
iconId = R.drawable.ic_stat_tor_xfer;
mService.showToolbarNotification(sb.toString(), mService.getNotifyId(), iconId);
- **/
mTotalTrafficWritten += written;
mTotalTrafficRead += read;
@@ -161,9 +162,12 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
StringTokenizer st = new StringTokenizer(path, ",");
Node node = null;
+ boolean isFirstNode = true;
+ int nodeCount = st.countTokens();
+
while (st.hasMoreTokens()) {
String nodePath = st.nextToken();
- node = new Node();
+ String nodeId = null, nodeName = null;
String[] nodeParts;
@@ -173,129 +177,70 @@ public class TorEventHandler implements EventHandler, TorServiceConstants {
nodeParts = nodePath.split("~");
if (nodeParts.length == 1) {
- node.id = nodeParts[0].substring(1);
- node.name = node.id;
+ nodeId = nodeParts[0].substring(1);
+ nodeName = node.id;
} else if (nodeParts.length == 2) {
- node.id = nodeParts[0].substring(1);
- node.name = nodeParts[1];
+ nodeId = nodeParts[0].substring(1);
+ nodeName = nodeParts[1];
+ }
+
+ if (nodeId == null)
+ continue;
+
+ node = hmBuiltNodes.get(nodeId);
+
+ if (node == null)
+ {
+ node = new Node();
+ node.id = nodeId;
+ node.name = nodeName;
}
node.status = status;
sb.append(node.name);
+ if (!TextUtils.isEmpty(node.ipAddress))
+ sb.append("(").append(node.ipAddress).append(")");
+
if (st.hasMoreTokens())
sb.append(" > ");
- }
- if (Prefs.useDebugLogging())
- mService.debug(sb.toString());
- else if (status.equals("BUILT"))
- mService.logNotice(sb.toString());
- else if (status.equals("CLOSED"))
- mService.logNotice(sb.toString());
+ if (status.equals("EXTENDED"))
+ {
- if (Prefs.expandedNotifications()) {
- //get IP from last nodename
- if (status.equals("BUILT")) {
+ if (isFirstNode)
+ {
+ hmBuiltNodes.put(node.id, node);
- // if (node.ipAddress == null)
- // mService.exec(new ExternalIPFetcher(node));
+ if (node.ipAddress == null && (!node.isFetchingInfo) && Prefs.useDebugLogging()) {
+ node.isFetchingInfo = true;
+ mService.exec(new ExternalIPFetcher(mService, node, TorService.mPortHTTP));
+ }
- hmBuiltNodes.put(circID, node);
+ isFirstNode = false;
+ }
}
+ else if (status.equals("BUILT")) {
+ // mService.logNotice(sb.toString());
- if (status.equals("CLOSED")) {
- hmBuiltNodes.remove(circID);
-
+ if (Prefs.useDebugLogging() && nodeCount > 3)
+ mService.debug(sb.toString());
+ }
+ else if (status.equals("CLOSED")) {
+ // mService.logNotice(sb.toString());
+ hmBuiltNodes.remove(node.id);
}
- }
- }
-
- }
- /**
- private class ExternalIPFetcher implements Runnable {
+ }
- private Node mNode;
- private int MAX_ATTEMPTS = 3;
- private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addresses&lookup=";
- public ExternalIPFetcher (Node node)
- {
- mNode = node;
}
- public void run ()
- {
-
- for (int i = 0; i < MAX_ATTEMPTS; i++)
- {
- if (mService.getControlConnection() != null)
- {
- try {
-
- URLConnection conn = null;
-
- Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
- conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
-
- conn.setRequestProperty("Connection","Close");
- conn.setConnectTimeout(60000);
- conn.setReadTimeout(60000);
- InputStream is = conn.getInputStream();
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-
- // getting JSON string from URL
-
- StringBuffer json = new StringBuffer();
- String line = null;
-
- while ((line = reader.readLine())!=null)
- json.append(line);
-
- JSONObject jsonNodeInfo = new org.json.JSONObject(json.toString());
-
- JSONArray jsonRelays = jsonNodeInfo.getJSONArray("relays");
-
- if (jsonRelays.length() > 0)
- {
- mNode.ipAddress = jsonRelays.getJSONObject(0).getJSONArray("or_addresses").getString(0).split(":")[0];
- mNode.country = jsonRelays.getJSONObject(0).getString("country_name");
- mNode.organization = jsonRelays.getJSONObject(0).getString("as_name");
-
- StringBuffer sbInfo = new StringBuffer();
- sbInfo.append(mNode.ipAddress);
-
- if (mNode.country != null)
- sbInfo.append(' ').append(mNode.country);
-
- if (mNode.organization != null)
- sbInfo.append(" (").append(mNode.organization).append(')');
-
- mService.logNotice(sbInfo.toString());
-
- }
-
- reader.close();
- is.close();
-
- break;
-
- } catch (Exception e) {
-
- mService.debug ("Error getting node details from onionoo: " + e.getMessage());
-
-
- }
- }
- }
- }
+ }
- }**/
private String parseNodeName(String node)
{
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index ea807be4..110b562f 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -37,6 +37,8 @@ import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
+import android.widget.RemoteViews;
+
import com.jaredrummler.android.shell.CommandResult;
import net.freehaven.tor.control.ConfigEntry;
@@ -75,6 +77,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -402,7 +405,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try {
- unregisterReceiver(mNetworkStateReceiver);
+ // unregisterReceiver(mNetworkStateReceiver);
unregisterReceiver(mActionBroadcastReceiver);
}
catch (IllegalArgumentException iae)
@@ -536,8 +539,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
- IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
+ // IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ // registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);
IntentFilter filter = new IntentFilter();
filter.addAction(CMD_NEWNYM);
@@ -1472,6 +1475,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
* BroadcastReciever in the Android manifest.
*/
+ /**
private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1504,33 +1508,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
if (newConnectivityState != mConnectivity) {
mConnectivity = newConnectivityState;
- if (mConnectivity)
- newIdentity();
+ //if (mConnectivity)
+ // newIdentity();
}
- /**
- if (doNetworKSleep && mCurrentStatus != STATUS_OFF)
- {
- setTorNetworkEnabled (mConnectivity);
-
- if (!mConnectivity)
- {
- logNotice(context.getString(R.string.no_network_connectivity_putting_tor_to_sleep_));
- showToolbarNotification(getString(R.string.no_internet_connection_tor),NOTIFY_ID,R.drawable.ic_stat_tor_off);
-
- }
- else
- {
- logNotice(context.getString(R.string.network_connectivity_is_good_waking_tor_up_));
- showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor);
-
- }
-
- }**/
-
-
}
- };
+ };**/
private StringBuffer processSettingsImpl (StringBuffer extraLines) throws IOException
{
diff --git a/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
new file mode 100644
index 00000000..ae99e7de
--- /dev/null
+++ b/orbotservice/src/main/java/org/torproject/android/service/util/ExternalIPFetcher.java
@@ -0,0 +1,95 @@
+package org.torproject.android.service.util;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.torproject.android.service.TorEventHandler;
+import org.torproject.android.service.TorService;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+
+public class ExternalIPFetcher implements Runnable {
+
+ private TorService mService;
+ private TorEventHandler.Node mNode;
+ private final static String ONIONOO_BASE_URL = "https://onionoo.torproject.org/details?fields=country_name,as_name,or_addresses&lookup=";
+ private int mLocalHttpProxyPort = 8118;
+
+ public ExternalIPFetcher (TorService service, TorEventHandler.Node node, int localProxyPort )
+ {
+ mService = service;
+ mNode = node;
+ mLocalHttpProxyPort = localProxyPort;
+ }
+
+ public void run ()
+ {
+ try {
+
+ URLConnection conn = null;
+
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", mLocalHttpProxyPort));
+ conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
+
+ conn.setRequestProperty("Connection","Close");
+ conn.setConnectTimeout(60000);
+ conn.setReadTimeout(60000);
+
+ InputStream is = conn.getInputStream();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+
+ // getting JSON string from URL
+
+ StringBuffer json = new StringBuffer();
+ String line = null;
+
+ while ((line = reader.readLine())!=null)
+ json.append(line);
+
+ JSONObject jsonNodeInfo = new org.json.JSONObject(json.toString());
+
+ JSONArray jsonRelays = jsonNodeInfo.getJSONArray("relays");
+
+ if (jsonRelays.length() > 0)
+ {
+ mNode.ipAddress = jsonRelays.getJSONObject(0).getJSONArray("or_addresses").getString(0).split(":")[0];
+ mNode.country = jsonRelays.getJSONObject(0).getString("country_name");
+ mNode.organization = jsonRelays.getJSONObject(0).getString("as_name");
+
+ StringBuffer sbInfo = new StringBuffer();
+ sbInfo.append(mNode.name).append("(");
+ sbInfo.append(mNode.ipAddress).append(")");
+
+ if (mNode.country != null)
+ sbInfo.append(' ').append(mNode.country);
+
+ if (mNode.organization != null)
+ sbInfo.append(" (").append(mNode.organization).append(')');
+
+ mService.debug(sbInfo.toString());
+
+ }
+
+ reader.close();
+ is.close();
+
+
+
+ } catch (Exception e) {
+
+ // mService.debug ("Error getting node details from onionoo: " + e.getMessage());
+
+
+ }
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
index b78c7a4f..c747eb59 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
@@ -51,6 +51,7 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.TimeoutException;
+import static org.torproject.android.service.TorServiceConstants.ACTION_START;
import static org.torproject.android.service.vpn.VpnUtils.getSharedPrefs;
import static org.torproject.android.service.vpn.VpnUtils.killProcess;
@@ -101,6 +102,8 @@ public class OrbotVpnManager implements Handler.Callback {
}
+
+ boolean isStarted = false;
//public int onStartCommand(Intent intent, int flags, int startId) {
public int handleIntent(Builder builder, Intent intent) {
@@ -109,8 +112,10 @@ public class OrbotVpnManager implements Handler.Callback {
{
String action = intent.getAction();
- if (action.equals("start"))
+ if (action.equals(TorVpnService.ACTION_START))
{
+ isStarted = true;
+
// Stop the previous session by interrupting the thread.
if (mThreadVPN != null && mThreadVPN.isAlive())
stopVPN();
@@ -129,8 +134,10 @@ public class OrbotVpnManager implements Handler.Callback {
}
- else if (action.equals("stop"))
+ else if (action.equals(TorVpnService.ACTION_STOP))
{
+ isStarted = false;
+
Log.d(TAG,"stop OrbotVPNService service!");
stopVPN();
@@ -335,12 +342,13 @@ public class OrbotVpnManager implements Handler.Callback {
isRestart = false;
//start PDNSD daemon pointing to actual DNS
- int pdnsdPort = 8091;
- startDNS(filePdnsd.getCanonicalPath(), localhost,mTorDns, virtualGateway, pdnsdPort);
- final boolean localDnsTransparentProxy = true;
-
- Tun2Socks.Start(mService, mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , virtualGateway + ":" + pdnsdPort , localDnsTransparentProxy);
+ if (filePdnsd != null) {
+ int pdnsdPort = 8091;
+ startDNS(filePdnsd.getCanonicalPath(), localhost, mTorDns, virtualGateway, pdnsdPort);
+ final boolean localDnsTransparentProxy = true;
+ Tun2Socks.Start(mService, mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks, virtualGateway + ":" + pdnsdPort, localDnsTransparentProxy);
+ }
}
catch (Exception e)
@@ -409,7 +417,7 @@ public class OrbotVpnManager implements Handler.Callback {
File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort);
- String[] cmdString = {pdnsPath,"-c",fileConf.toString()};
+ String[] cmdString = {pdnsPath,"-c",fileConf.toString(),"-g","-v2"};
ProcessBuilder pb = new ProcessBuilder(cmdString);
pb.redirectErrorStream(true);
Process proc = pb.start();
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
index d394b5c8..cedd2528 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
@@ -22,8 +22,8 @@ public class TorVpnService extends VpnService {
public static final String TAG = "TorVpnService";
- private static final String ACTION_START = "start";
- private static final String ACTION_STOP = "stop";
+ public static final String ACTION_START = "start";
+ public static final String ACTION_STOP = "stop";
public static void start(Context context) {
Intent intent = new Intent(context, TorVpnService.class);
diff --git a/orbotservice/src/main/res/drawable/ic_onion.xml b/orbotservice/src/main/res/drawable/ic_onion.xml
new file mode 100644
index 00000000..3047a149
--- /dev/null
+++ b/orbotservice/src/main/res/drawable/ic_onion.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="69.9dp"
+ android:height="107.3dp"
+ android:viewportWidth="69.9"
+ android:viewportHeight="107.3">
+ <path
+ android:pathData="M59.9,54.5c-3.4,-3.1 -7.7,-5.6 -12.1,-8.1c-2,-1.1 -8.1,-5.9 -6,-12.7l-3.8,-1.6c6,-9.3 13.8,-18.5 23.4,-27.1c-7.7,2.6 -14.5,6.6 -19.6,13.7c3,-6.3 7.9,-12.5 13.3,-18.8c-7.4,5.3 -13.8,11.3 -17.8,19.3L40.1,8c-4,7.2 -6.8,14.5 -7.9,21.8l-5.9,-2.4l-1,0.8c5.2,9.3 2.5,14.2 -0.1,15.9C20,47.6 12.5,52.1 8.7,56c-7.2,7.4 -9.3,14.4 -8.6,23.7c0.7,11.9 9.4,21.8 20.9,25.7c5.1,1.7 9.8,1.9 15,1.9c8.4,0 17,-2.2 23.3,-7.5c6.7,-5.5 10.6,-13.9 10.6,-22.5C69.9,68.6 66.3,60.3 59.9,54.5zM18.6,101.8C9.3,97.3 3.1,87.6 2.7,79.7C1.9,63.6 9.6,58.9 16.8,53c4,-3.3 9.6,-4.9 12.8,-10.8c0.6,-1.3 1,-4.1 0.2,-7.1c-0.3,-1 -1.8,-4.6 -2.4,-5.4l8.9,3.9l0,0l0,0c-0.2,4.2 -0.3,7.6 0.5,10.7c0.9,3.4 5.3,8.3 7.1,14c3.5,10.8 2.6,24.9 0.1,35.9c-0.4,1.8 -1.7,4 -3.3,6c0.6,-1.1 1.1,-2.2 1.4,-3.4c2.5,-8.9 3.6,-13 2.4,-22.8c-0.2,-1 -0.6,-4.2 -2.1,-7.7C40.3,61 37.1,56 36.7,54.9c-0.7,-1.7 -1.7,-8.9 -1.8,-13.8C35,45.3 35.3,53 36.4,56c0.3,1 3.2,5.5 5.3,11c1.4,3.8 1.7,7.3 2,8.3c1,4.5 -0.2,12.1 -1.8,19.3c-0.5,2.6 -1.9,5
.6 -3.7,7.9c1,-1.4 1.8,-3.2 2.4,-5.3c1.2,-4.2 1.7,-9.6 1.6,-13c-0.1,-2 -1,-6.3 -2.5,-10.2c-0.9,-2.1 -2.2,-4.3 -3.1,-5.8c-1,-1.5 -1,-4.8 -1.4,-8.6c0.1,4.1 -0.3,6.2 0.7,9.1c0.6,1.7 2.8,4.1 3.4,6.4c0.9,3.1 1.8,6.5 1.7,8.6c0,2.4 -0.1,6.8 -1.2,11.6c-0.7,3.6 -2.3,6.7 -4.9,8.7c1.1,-1.4 1.7,-2.8 2,-4.2c0.4,-2.1 0.5,-4.1 0.7,-6.6c0.2,-2.1 0.1,-4.8 -0.5,-7.7c-0.8,-3.6 -2.1,-7.2 -2.7,-9.7c0.1,2.8 1.2,6.3 1.7,10c0.4,2.7 0.2,5.4 0.1,7.8c-0.1,2.8 -1,7.7 -2.2,10.1c-1.2,-0.5 -1.6,-1.2 -2.4,-2.2c-1,-1.3 -1.6,-2.7 -2.2,-4.3c-0.5,-1.2 -1,-2.6 -1.3,-4.1c-0.3,-2.4 -0.2,-6.1 2.5,-9.9c2.1,-3 2.5,-3.2 3.2,-6.7c-1,3.1 -1.7,3.4 -3.9,6c-2.5,2.9 -2.9,7.1 -2.9,10.5c0,1.4 0.6,3 1.1,4.5c0.6,1.6 1.2,3.2 2,4.4c0.6,1 1.4,1.7 2.1,2.2c-2.6,-0.7 -5.3,-1.7 -7,-3.1c-4.2,-3.6 -7.9,-9.7 -8.4,-15.1c-0.4,-4.4 3.6,-10.8 9.3,-14c4.8,-2.8 5.9,-5.9 6.9,-11c-1.4,4.4 -2.8,8.2 -7.4,10.5C19,75 15.6,80.8 15.9,86.4c0.5,7.1 3.3,12 9,15.9c1.3,0.9 3.1,1.8 5,2.5c-7.1,-1.7 -8,-2.7 -10.4,-5.5c0,-0.2 -0.6,-0.6 -0.6,-0.7c-3.2,-3.6 -7.2,-9.8 -
8.6,-15.5c-0.5,-2 -1,-4.1 -0.4,-6.1c2.6,-9.4 8.3,-13 14,-16.9c1.4,-1 2.8,-1.9 4.1,-2.9c3.2,-2.5 4,-9 4.7,-12.7c-1.3,4.5 -2.7,10.1 -5.2,11.9c-1.3,1 -2.9,1.8 -4.2,2.7c-5.9,4 -11.8,7.8 -14.5,17.5c-0.6,2.5 -0.2,4.3 0.4,6.7c1.5,5.9 5.5,12.3 8.9,16.1c0,0 0.6,0.6 0.6,0.6c1.5,1.7 3.4,3 5.7,3.9C22.3,103.4 20.4,102.7 18.6,101.8z"
+ android:fillColor="#010101"/>
+</vector>
diff --git a/orbotservice/src/main/res/drawable/ic_stat_tor_xfer.png b/orbotservice/src/main/res/drawable/ic_stat_tor_xfer.png
new file mode 100644
index 00000000..d222fb67
Binary files /dev/null and b/orbotservice/src/main/res/drawable/ic_stat_tor_xfer.png differ
diff --git a/orbotservice/src/main/res/drawable/ic_transfer.xml b/orbotservice/src/main/res/drawable/ic_transfer.xml
new file mode 100644
index 00000000..a2d1fa99
--- /dev/null
+++ b/orbotservice/src/main/res/drawable/ic_transfer.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9,3L5,6.99h3L8,14h2L10,6.99h3L9,3zM16,17.01L16,10h-2v7.01h-3L15,21l4,-3.99h-3z"/>
+</vector>
More information about the tor-commits
mailing list