diff --git a/res/layout/layout_main.xml b/res/layout/layout_main.xml
index db167e33..a9444e1f 100644
--- a/res/layout/layout_main.xml
+++ b/res/layout/layout_main.xml
@@ -57,6 +57,54 @@
android:textColor="#ffffff"
/>
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8cc6207e..9fa461d8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -31,6 +31,8 @@
About
Wizard
+Download
+Upload
Help
Close
diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java
index 1a09ac73..c51b1047 100644
--- a/src/org/torproject/android/Orbot.java
+++ b/src/org/torproject/android/Orbot.java
@@ -42,57 +42,62 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.ImageView;
+import android.widget.RelativeLayout;
import android.widget.TextView;
public class Orbot extends Activity implements TorConstants, OnLongClickListener
{
-
-
- /* Useful UI bits */
- // so this is probably pretty obvious, here, but also an area
- // which we might see quite a bit of change+complexity was the main screen
- // UI gets new features
- private TextView lblStatus = null; //the main text display widget
- private ImageView imgStatus = null; //the main touchable image for activating Orbot
- private ProgressDialog progressDialog; //the spinning progress dialog that shows up now and then
- private MenuItem mItemOnOff = null; //the menu item which we toggle based on Orbot state
-
- /* Some tracking bits */
- private int torStatus = TorServiceConstants.STATUS_OFF; //latest status reported from the tor service
- // this is a value we get passed back from the TorService
-
- /* Tor Service interaction */
- /* The primary interface we will be calling on the service. */
- ITorService mService = null; //interface to remote TorService
- private boolean autoStartOnBind = false; //controls whether service starts when class binds to it
+ /* Useful UI bits */
+ private TextView lblStatus = null; //the main text display widget
+ private ImageView imgStatus = null; //the main touchable image for activating Orbot
+ private ProgressDialog progressDialog;
+ private MenuItem mItemOnOff = null;
+ private RelativeLayout trafficRow = null; // the row showing the traffic
+ private TextView downloadText = null;
+ private TextView uploadText = null;
- SharedPreferences prefs; //what the user really wants!
-
- /**
- * When the Orbot activity is created, we call startService
- * to ensure the Tor remote service is running. However, it may
- * already be running, and this should not create more than one instnace
- */
+ /* Some tracking bits */
+ private int torStatus = TorServiceConstants.STATUS_OFF; //latest status reported from the tor service
+
+ /* Tor Service interaction */
+ /* The primary interface we will be calling on the service. */
+ ITorService mService = null;
+ private boolean autoStartOnBind = false;
+
+ SharedPreferences prefs;
+
+ public static Orbot currentInstance = null;
+
+ private static void setCurrent(Orbot current){
+ Orbot.currentInstance = current;
+ }
+
+ /** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Orbot.setCurrent(this);
+
//if Tor binary is not running, then start the service up
//might want to look at whether we need to call this every time
//or whether binding to the service is enough
- setLocale();
+ setLocale();
+
+ startService(new Intent(INTENT_TOR_SERVICE));
+
+ prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+ setContentView(R.layout.layout_main);
+
+ lblStatus = (TextView)findViewById(R.id.lblStatus);
+ lblStatus.setOnLongClickListener(this);
+ imgStatus = (ImageView)findViewById(R.id.imgStatus);
+ imgStatus.setOnLongClickListener(this);
+ trafficRow = (RelativeLayout)findViewById(R.id.trafficRow);
+ downloadText = (TextView)findViewById(R.id.trafficDown);
+ uploadText = (TextView)findViewById(R.id.trafficUp);
- prefs = PreferenceManager.getDefaultSharedPreferences(this);
-
- setContentView(R.layout.layout_main);
-
- //obvious? -yep got everything so far
- lblStatus = (TextView)findViewById(R.id.lblStatus);
-
- imgStatus = (ImageView)findViewById(R.id.imgStatus);
- imgStatus.setOnLongClickListener(this);
-
- startService(new Intent(INTENT_TOR_SERVICE));
}
@@ -608,21 +613,21 @@ public class Orbot extends Activity implements TorConstants, OnLongClickListener
msg.getData().putString(HANDLER_TOR_MSG, getString(R.string.status_starting_up));
mHandler.sendMessage(msg);
+
}
//now we stop Tor! amazing!
private void stopTor () throws RemoteException
{
- //if the service is bound, then turn it off, using the same "PROFILE_" technique
- if (mService != null)
- {
- mService.setProfile(TorServiceConstants.PROFILE_OFF);
-
- //again this is related to the progress dialog or some other threaded UI object
- Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
- mHandler.sendMessage(msg);
- }
-
+ if (mService != null)
+ {
+ mService.setProfile(TorServiceConstants.PROFILE_OFF);
+ Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
+ mHandler.sendMessage(msg);
+ trafficRow.setVisibility(RelativeLayout.GONE);
+
+ }
+
}
@@ -689,14 +694,31 @@ public class Orbot extends Activity implements TorConstants, OnLongClickListener
mHandler.sendMessage(msg);
}
-
- public void logMessage(String value) throws RemoteException {
-
- Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
- msg.getData().putString(HANDLER_TOR_MSG, value);
- mHandler.sendMessage(msg);
-
- }
+ @Override
+ public void logMessage(String value) throws RemoteException {
+
+ Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
+ msg.getData().putString(HANDLER_TOR_MSG, value);
+ mHandler.sendMessage(msg);
+
+ }
+
+ @Override
+ public void updateBandwidth(long upload, long download)
+ throws RemoteException {
+
+ Message msg = Message.obtain();
+ msg.what = TorServiceConstants.MESSAGE_TRAFFIC_COUNT;
+
+
+ Bundle data = new Bundle();
+ data.putLong("upload", upload);
+ data.putLong("download", download);
+
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+
+ }
};
@@ -731,11 +753,35 @@ public class Orbot extends Activity implements TorConstants, OnLongClickListener
break;
case TorServiceConstants.DISABLE_TOR_MSG:
-
- updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
-
- break;
-
+
+ updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
+
+ break;
+
+
+ case TorServiceConstants.MESSAGE_TRAFFIC_COUNT :
+
+ trafficRow.setVisibility(RelativeLayout.VISIBLE);
+ Bundle data = msg.getData();
+ DataCount datacount = new DataCount(data.getLong("upload"),data.getLong("download"));
+ downloadText.setText(formatCount(datacount.Download));
+ uploadText.setText(formatCount(datacount.Upload));
+ downloadText.invalidate();
+ uploadText.invalidate();
+
+ try {
+ String TotalUpload = mService.getInfo("traffic/written");
+ String TotalDownload = mService.getInfo("traffic/read");
+ StringBuilder sb = new StringBuilder();
+ sb.append("Total Upload " + TotalUpload);
+ sb.append("Total Download" + TotalDownload);
+ Log.d(TAG,sb.toString());
+ } catch (RemoteException e) {
+ Log.d(TAG,"Total bandwidth error"+e.getMessage());
+ }
+
+ break;
+
default:
super.handleMessage(msg);
}
@@ -885,5 +931,28 @@ public class Orbot extends Activity implements TorConstants, OnLongClickListener
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
}
}
-
+
+ public class DataCount {
+ // data uploaded
+ public long Upload;
+ // data downloaded
+ public long Download;
+
+ DataCount(long Upload, long Download){
+ this.Upload = Upload;
+ this.Download = Download;
+ }
+ }
+
+ private String formatCount(long count) {
+ // Converts the supplied argument into a string.
+ // Under 2Mb, returns "xxx.xKb"
+ // Over 2Mb, returns "xxx.xxMb"
+ if (count < 1e6 * 2)
+ return ((float)((int)(count*10/1024))/10 + " kbps");
+ return ((float)((int)(count*100/1024/1024))/100 + " mbps");
+
+ //return count+" kB";
+ }
+
}
diff --git a/src/org/torproject/android/service/ITorService.aidl b/src/org/torproject/android/service/ITorService.aidl
index e643b4db..07fa8089 100644
--- a/src/org/torproject/android/service/ITorService.aidl
+++ b/src/org/torproject/android/service/ITorService.aidl
@@ -48,4 +48,9 @@ interface ITorService {
*/
String getConfiguration (String name);
+ /**
+ * Get information
+ */
+ String getInfo (String args);
+
}
diff --git a/src/org/torproject/android/service/ITorServiceCallback.aidl b/src/org/torproject/android/service/ITorServiceCallback.aidl
index 86fe28f7..2492206f 100644
--- a/src/org/torproject/android/service/ITorServiceCallback.aidl
+++ b/src/org/torproject/android/service/ITorServiceCallback.aidl
@@ -11,6 +11,11 @@ oneway interface ITorServiceCallback {
*/
void statusChanged(String value);
+ /**
+ * Called when the service returns the bandwidth user to display to the user
+ */
+ void updateBandwidth(long value, long value2);
+
/**
* Called when the service has something to add to the log
*/
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index 3ffa4609..23921a98 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.StringTokenizer;
import net.freehaven.tor.control.ConfigEntry;
@@ -41,7 +42,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcelable;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.preference.PreferenceManager;
@@ -50,7 +55,7 @@ import android.util.Log;
public class TorService extends Service implements TorServiceConstants, TorConstants, Runnable, EventHandler
{
- public static boolean ENABLE_DEBUG_LOG = false;
+ public static boolean ENABLE_DEBUG_LOG = true;
private static int currentStatus = STATUS_OFF;
@@ -944,7 +949,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
conn.setEventHandler(this);
conn.setEvents(Arrays.asList(new String[]{
- "ORCONN", "CIRC", "NOTICE", "WARN", "ERR"}));
+ "ORCONN", "CIRC", "NOTICE", "WARN", "ERR","BW"}));
// conn.setEvents(Arrays.asList(new String[]{
// "DEBUG", "INFO", "NOTICE", "WARN", "ERR"}));
@@ -1105,7 +1110,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
}
}
-
+
public void bandwidthUsed(long read, long written) {
if (ENABLE_DEBUG_LOG)
@@ -1116,12 +1121,17 @@ public class TorService extends Service implements TorServiceConstants, TorConst
sb.append("kb read / ");
sb.append(written/1000);
sb.append("kb written");
-
+
logNotice(sb.toString());
}
+
+ sendCallbackStatusMessage(written, read);
+
+
}
-
+
+
public void circuitStatus(String status, String circID, String path) {
if (ENABLE_DEBUG_LOG)
@@ -1258,8 +1268,25 @@ public class TorService extends Service implements TorServiceConstants, TorConst
}
}
-
-
+
+
+ public String getInfo (String key) {
+ try
+ {
+ if(conn !=null)
+ {
+ String m = conn.getInfo(key);
+ return m;
+
+ }
+ }
+ catch(IOException ioe)
+ {
+ Log.e(TAG,"Unable to get Tor information",ioe);
+ logNotice("Unable to get Tor information"+ioe.getMessage());
+ }
+ return null;
+ }
public String getConfiguration (String name)
{
@@ -1390,6 +1417,36 @@ public class TorService extends Service implements TorServiceConstants, TorConst
mCallbacks.finishBroadcast();
inCallback = false;
}
+
+ private synchronized void sendCallbackStatusMessage (long upload, long download)
+ {
+
+ if (mCallbacks == null)
+ return;
+
+ // Broadcast to all clients the new value.
+ final int N = mCallbacks.beginBroadcast();
+
+ inCallback = true;
+
+ if (N > 0)
+ {
+ for (int i=0; i