[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [orbot/master] added tethering support
commit ddb4793b0a051afc9cb9f7dd5d7e7c6589ef861e
Author: Nathan Freitas <nathan@xxxxxxxxxxx>
Date: Thu Jun 2 16:21:50 2011 -0400
added tethering support
---
src/org/torproject/android/Orbot.java | 1303 +++++++++++---------
.../android/boot/OnbootBroadcastReceiver.java | 37 -
src/org/torproject/android/service/TorService.java | 15 +-
.../torproject/android/service/TorTransProxy.java | 43 +-
4 files changed, 737 insertions(+), 661 deletions(-)
diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java
index 4bc5695..690ce10 100644
--- a/src/org/torproject/android/Orbot.java
+++ b/src/org/torproject/android/Orbot.java
@@ -1,9 +1,8 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
+/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
/* See LICENSE for licensing information */
package org.torproject.android;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -45,43 +44,56 @@ import android.widget.TextView;
public class Orbot extends Activity implements OnLongClickListener, TorConstants
{
-
- /* 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;
-
- /* Some tracking bits */
- private int torStatus = STATUS_READY; //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;
-
- /** Called when the activity is first created. */
+
+ /* 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 = STATUS_READY; //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
+
+ 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
+ */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//if Tor binary is not running, then start the service up
- startService(new Intent(INTENT_TOR_SERVICE));
-
-
- setTheme(android.R.style.Theme_Black_NoTitleBar);
-
- 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);
-
-
+ //might want to look at whether we need to call this every time
+ //or whether binding to the service is enough
+ startService(new Intent(INTENT_TOR_SERVICE));
+
+ //something to play with on the UI branch
+ setTheme(android.R.style.Theme_Black_NoTitleBar);
+
+ prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+ //same here - layout_main has been cleaned up since 1.0.5.2 a bit (removed table as you recmnd)
+ //but ther eis more to be done
+ setContentView(R.layout.layout_main);
+
+ //obvious? -yep got everything so far
+ lblStatus = (TextView)findViewById(R.id.lblStatus);
+ lblStatus.setOnLongClickListener(this);
+ imgStatus = (ImageView)findViewById(R.id.imgStatus);
+ imgStatus.setOnLongClickListener(this);
+
+
}
@@ -119,562 +131,636 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
private void showAbout ()
- {
-
- LayoutInflater li = LayoutInflater.from(this);
+ {
+
+ LayoutInflater li = LayoutInflater.from(this);
View view = li.inflate(R.layout.layout_about, null);
TextView versionName = (TextView)view.findViewById(R.id.versionName);
versionName.setText(R.string.app_version);
- new AlertDialog.Builder(this)
+ new AlertDialog.Builder(this)
.setTitle(getString(R.string.button_about))
.setView(view)
.show();
- }
+ }
/* When a menu item is selected launch the appropriate view or activity
* (non-Javadoc)
- * @see android.app.Activity#onMenuItemSelected(int, android.view.MenuItem)
- */
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
-
- super.onMenuItemSelected(featureId, item);
-
- if (item.getItemId() == 1)
- {
-
- try
- {
-
- if (mService == null)
- {
-
- }
- else if (mService.getStatus() == STATUS_READY)
- {
- if (mItemOnOff != null)
- mItemOnOff.setTitle(R.string.menu_stop);
- startTor();
-
- }
- else
- {
- if (mItemOnOff != null)
- mItemOnOff.setTitle(R.string.menu_start);
- stopTor();
-
- }
-
- }
- catch (RemoteException re)
- {
- Log.w(TAG, "Unable to start/top Tor from menu UI", re);
- }
- }
- else if (item.getItemId() == 4)
- {
- showSettings();
- }
- else if (item.getItemId() == 3)
- {
- showHelp();
- }
- else if (item.getItemId() == 7)
- {
- doTorCheck();
- }
- else if (item.getItemId() == 8)
- {
- //exit app
- doExit();
-
-
- }
- else if (item.getItemId() == 6)
- {
- showAbout();
-
-
- }
-
+ * @see android.app.Activity#onMenuItemSelected(int, android.view.MenuItem)
+ */
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+
+ super.onMenuItemSelected(featureId, item);
+
+ if (item.getItemId() == 1)
+ {
+
+ try
+ {
+
+ if (mService == null)
+ {
+
+ }
+ else if (mService.getStatus() == STATUS_READY)
+ {
+ if (mItemOnOff != null)
+ mItemOnOff.setTitle(R.string.menu_stop);
+ startTor();
+
+ }
+ else
+ {
+ if (mItemOnOff != null)
+ mItemOnOff.setTitle(R.string.menu_start);
+ stopTor();
+
+ }
+
+ }
+ catch (RemoteException re)
+ {
+ Log.w(TAG, "Unable to start/top Tor from menu UI", re);
+ }
+ }
+ else if (item.getItemId() == 4)
+ {
+ showSettings();
+ }
+ else if (item.getItemId() == 3)
+ {
+ showHelp();
+ }
+ else if (item.getItemId() == 7)
+ {
+ doTorCheck();
+ }
+ else if (item.getItemId() == 8)
+ {
+ //exit app
+ doExit();
+
+
+ }
+ else if (item.getItemId() == 6)
+ {
+ showAbout();
+
+
+ }
+
return true;
- }
-
- private void doExit ()
- {
- try {
-
- stopTor();
-
- stopService(new Intent(ITorService.class.getName()));
-
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.cancelAll();
-
-
- } catch (RemoteException e) {
- Log.w(TAG, e);
- }
-
- finish();
-
- }
-
- /* Return to the main view when the back key is pressed
- * (non-Javadoc)
- * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
- */
- /*
- public boolean onKeyDown(int keyCode, KeyEvent event){
-
- if(keyCode==KeyEvent.KEYCODE_BACK){
-
- if(currentView != R.layout.layout_main){
-
- showMain ();
- return true;
- }
- else{
- return super.onKeyDown(keyCode, event);
- }
- }
-
- return super.onKeyDown(keyCode, event);
-
- }*/
+ }
+
+ /**
+ * This is our attempt to REALLY exit Orbot, and stop the background service
+ * However, Android doesn't like people "quitting" apps, and/or our code may not
+ * be quite right b/c no matter what we do, it seems like the TorService still exists
+ **/
+ private void doExit ()
+ {
+ try {
+
+ //one of the confusing things about all of this code is the multiple
+ //places where things like "stopTor" are called, both in the Activity and the Service
+ //not something to tackle in your first iteration, but i thin we can talk about fixing
+ //terminology but also making sure there are clear distinctions in control
+ stopTor();
+
+ //perhaps this should be referenced as INTENT_TOR_SERVICE as in startService
+ stopService(new Intent(ITorService.class.getName()));
+
+ //clears all notifications from the status bar
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ mNotificationManager.cancelAll();
+
+
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ }
+
+ finish();
+
+ }
+
+ /* Return to the main view when the back key is pressed
+ * (non-Javadoc)
+ * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
+ */
+ /*
+ public boolean onKeyDown(int keyCode, KeyEvent event){
+
+ //yeah this should probably go away now :) - or not
+ if(keyCode==KeyEvent.KEYCODE_BACK){
+
+ if(currentView != R.layout.layout_main){
+
+ showMain ();
+ return true;
+ }
+ else{
+ return super.onKeyDown(keyCode, event);
+ }
+ }
+
+ return super.onKeyDown(keyCode, event);
+
+ }*/
/* (non-Javadoc)
- * @see android.app.Activity#onPause()
- */
- protected void onPause() {
- super.onPause();
-
- hideProgressDialog();
-
- if (aDialog != null)
- aDialog.dismiss();
- }
-
- public void onSaveInstanceState(Bundle savedInstanceState) {
- // Save UI state changes to the savedInstanceState.
- // This bundle will be passed to onCreate if the process is
- // killed and restarted.
- // etc.
- super.onSaveInstanceState(savedInstanceState);
- }
-
- public void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- // Restore UI state from the savedInstanceState.
- // This bundle has also been passed to onCreate.
-
- }
-
- private void doTorCheck ()
- {
-
- DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- switch (which){
- case DialogInterface.BUTTON_POSITIVE:
-
- openBrowser(URL_TOR_CHECK);
-
-
-
- break;
-
- case DialogInterface.BUTTON_NEGATIVE:
-
- //do nothing
- break;
- }
- }
- };
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(R.string.tor_check).setPositiveButton(R.string.btn_okay, dialogClickListener)
- .setNegativeButton(R.string.btn_cancel, dialogClickListener).show();
-
- }
-
- private void enableHiddenServicePort (int hsPort)
- {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- Editor pEdit = prefs.edit();
-
- String hsPortString = prefs.getString("pref_hs_ports", "");
-
- if (hsPortString.length() > 0 && hsPortString.indexOf(hsPort+"")==-1)
- hsPortString += ',' + hsPort;
- else
- hsPortString = hsPort + "";
-
- pEdit.putString("pref_hs_ports", hsPortString);
- pEdit.putBoolean("pref_hs_enable", true);
-
- pEdit.commit();
-
- String onionHostname = prefs.getString("pref_hs_hostname","");
-
- Intent nResult = new Intent();
- nResult.putExtra("hs_host", onionHostname);
- setResult(RESULT_OK, nResult);
-
- }
-
- /* (non-Javadoc)
- * @see android.app.Activity#onResume()
- */
- protected void onResume() {
- super.onResume();
-
- bindService();
-
- updateStatus("");
-
- if (getIntent() == null)
- return;
-
- String action = getIntent().getAction();
-
- if (action == null)
- return;
-
- if (action.equals("org.torproject.android.REQUEST_HS_PORT"))
- {
-
- DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- switch (which){
- case DialogInterface.BUTTON_POSITIVE:
-
- int hsPort = getIntent().getIntExtra("hs_port", -1);
-
- enableHiddenServicePort (hsPort);
-
- finish();
-
-
- break;
-
- case DialogInterface.BUTTON_NEGATIVE:
- //No button clicked
- finish();
- break;
- }
- }
- };
-
- int hsPort = getIntent().getIntExtra("hs_port", -1);
-
- String requestMsg = "An app wants to open a server port (" + hsPort + ") to the Tor network. This is safe if you trust the app.";
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(requestMsg).setPositiveButton("Allow", dialogClickListener)
- .setNegativeButton("Deny", dialogClickListener).show();
-
-
- }
- else if (action.equals("org.torproject.android.START_TOR"))
- {
- autoStartOnBind = true;
-
- if (mService == null)
- bindService();
-
- }
- else
- {
-
- //setTitle(getString(R.string.app_name) + ' ' + getString(R.string.app_version));
-
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.cancelAll();
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-
- boolean showWizard = prefs.getBoolean("show_wizard",true);
-
- if (showWizard)
- {
-
- Editor pEdit = prefs.edit();
-
- pEdit.putBoolean("show_wizard",false);
-
- pEdit.commit();
-
- new WizardHelper(this).showWizard();
-
- }
-
- }
- }
-
- /* (non-Javadoc)
- * @see android.app.Activity#onStart()
- */
- protected void onStart() {
- super.onStart();
-
-
- updateStatus ("");
-
- }
-
- /* (non-Javadoc)
- * @see android.app.Activity#onStop()
- */
- protected void onStop() {
- super.onStop();
-
- //unbindService();
- }
-
-
-
- /*
- * Launch the system activity for Uri viewing with the provided url
- */
- private void openBrowser(String url)
- {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
- }
-
-
-
- /*
- * Show the help view - a popup dialog
- */
- private void showHelp ()
- {
-
+ * @see android.app.Activity#onPause()
+ */
+ protected void onPause() {
+ super.onPause();
+
+ hideProgressDialog();
+
+ if (aDialog != null)
+ aDialog.dismiss();
+ }
+
+/**
+* i think we need to suport this onSave/Restore code more b/c i think
+* when someone rotates the screen, and the state is lost during setup
+* etc it causes problems. this might be the place to solve that in the wizard - hmm this prob coz android restarts the activity when the screen is rotated. this will prob be fixed(?) when
+we redesign the wizard into a view not just a dialogbox
+cool
+**/
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ // Save UI state changes to the savedInstanceState.
+ // This bundle will be passed to onCreate if the process is
+ // killed and restarted.
+ // etc.
+ super.onSaveInstanceState(savedInstanceState);
+ }
+
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ // Restore UI state from the savedInstanceState.
+ // This bundle has also been passed to onCreate.
+
+ //we do nothing here
+ }
+
+ /**
+ * confirm with the user that they want to open a browser to connect to https://check.torproject.org
+ and then launch the URL.
+ this may be where the TorCheck API code/UI is added, though always offering the web-based confirm
+ should be an option, since users know it
+
+ **/
+ private void doTorCheck ()
+ {
+
+ DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which){
+ case DialogInterface.BUTTON_POSITIVE:
+
+ openBrowser(URL_TOR_CHECK);
+
+
+
+ break;
+
+ case DialogInterface.BUTTON_NEGATIVE:
+
+ //do nothing
+ break;
+ }
+ }
+ };
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(R.string.tor_check).setPositiveButton(R.string.btn_okay, dialogClickListener)
+ .setNegativeButton(R.string.btn_cancel, dialogClickListener).show();
+
+ }
+
+ /**
+ * this adds a port to the list of hidden service ports
+ * we might want to add remove/disable port too
+ * this is used by external apps that launch an intent
+ * to request a hidden service on a specific port
+ * currently, we haven't promoted this intent API or capability
+ * that much, but we hope to
+ **/
+ private void enableHiddenServicePort (int hsPort)
+ {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ Editor pEdit = prefs.edit();
+
+ String hsPortString = prefs.getString("pref_hs_ports", "");
+
+ if (hsPortString.length() > 0 && hsPortString.indexOf(hsPort+"")==-1)
+ hsPortString += ',' + hsPort;
+ else
+ hsPortString = hsPort + "";
+
+ pEdit.putString("pref_hs_ports", hsPortString);
+ pEdit.putBoolean("pref_hs_enable", true);
+
+ pEdit.commit();
+
+ String onionHostname = prefs.getString("pref_hs_hostname","");
+
+ Intent nResult = new Intent();
+ nResult.putExtra("hs_host", onionHostname);
+ setResult(RESULT_OK, nResult);
+
+ }
+
+ /* (non-Javadoc)
+ * @see android.app.Activity#onResume()
+ */
+ protected void onResume() {
+ super.onResume();
+
+ //this is where we make sure we have a handle to ITorService
+ bindService();
+
+ //this is a hack which basically pings the ITorService to update our status for the UI
+ // - the dialogbox/progressbar ?
+ // right, this was for when the label displayed the status, and not the progress, so it may
+ // not make as much sense now; there is a bunch of loose ends like this that should be
+ // cleaned up with the transition to the progressdialog - ok
+ updateStatus("");
+
+ //this checks if we were launched via an Intent call from another app or activity
+ //- how does this matter? if Orbot has been launched via an Intent or not ?
+ //we want to know if this is a launch by the user from the home screen, or via back, or some
+ // standard interaction, or if it is another app launching Orbot for a programmatic/API request
+ // this is how we can add more functionality into ORlib, for instance via Intent launching - hmm ok
+ if (getIntent() == null)
+ return;
+
+ String action = getIntent().getAction();
+
+ if (action == null)
+ return;
+
+ //this relates to the previously discussed hidden port capability
+ if (action.equals("org.torproject.android.REQUEST_HS_PORT"))
+ {
+
+ //tell the user an app is trying to open a hidden port and ask for permission
+ DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which){
+ case DialogInterface.BUTTON_POSITIVE:
+
+ int hsPort = getIntent().getIntExtra("hs_port", -1);
+
+ enableHiddenServicePort (hsPort);
+
+ finish();
+
+
+ break;
+
+ case DialogInterface.BUTTON_NEGATIVE:
+ //No button clicked
+ finish();
+ break;
+ }
+ }
+ };
+
+ int hsPort = getIntent().getIntExtra("hs_port", -1);
+
+ String requestMsg = "An app wants to open a server port (" + hsPort + ") to the Tor network. This is safe if you trust the app.";
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(requestMsg).setPositiveButton("Allow", dialogClickListener)
+ .setNegativeButton("Deny", dialogClickListener).show();
+
+
+ }
+ else if (action.equals("org.torproject.android.START_TOR")) //this is the intent used to start Tor from another app, again meant for ORlib functionality
+ {
+ autoStartOnBind = true;
+
+ if (mService == null)
+ bindService();
+
+ }
+ else
+ {
+ //hmm not sure when this is ever reached honestly ;P
+ //but it looks like a general UI reset
+
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ mNotificationManager.cancelAll();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+ boolean showWizard = prefs.getBoolean("show_wizard",true);
+
+ if (showWizard)
+ {
+
+ Editor pEdit = prefs.edit();
+
+ pEdit.putBoolean("show_wizard",false);
+
+ pEdit.commit();
+
+ new WizardHelper(this).showWizard();
+
+ }
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see android.app.Activity#onStart()
+ */
+ protected void onStart() {
+ super.onStart();
+
+
+ updateStatus ("");
+
+ }
+
+ /* (non-Javadoc)
+ * @see android.app.Activity#onStop()
+ */
+ protected void onStop() {
+ super.onStop();
+
+ //unbindService();
+ }
+
+
+
+ /*
+ * Launch the system activity for Uri viewing with the provided url
+ */
+ private void openBrowser(String url)
+ {
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+ }
+
+
+
+ /*
+ * Show the help view - a popup dialog
+ */
+ private void showHelp ()
+ {
+
new WizardHelper(this).showWizard();
- }
-
-
+ }
+
+
/*
* Load the basic settings application to display torrc
*/
- private void showSettings ()
- {
-
- startActivityForResult(new Intent(this, SettingsPreferences.class), 1);
- }
-
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode == 1 && resultCode == 1010 && mService != null)
- {
- new ProcessSettingsAsyncTask().execute(mService);
- }
- }
-
- AlertDialog aDialog = null;
-
- private void showAlert(String title, String msg, boolean button)
- {
- try
- {
- if (aDialog != null && aDialog.isShowing())
- aDialog.dismiss();
- }
- catch (Exception e){} //swallow any errors
-
- if (button)
- {
- aDialog = new AlertDialog.Builder(this)
- .setIcon(R.drawable.icon)
- .setTitle(title)
- .setMessage(msg)
- .setPositiveButton(android.R.string.ok, null)
- .show();
- }
- else
- {
- aDialog = new AlertDialog.Builder(this)
- .setIcon(R.drawable.icon)
- .setTitle(title)
- .setMessage(msg)
- .show();
- }
-
- aDialog.setCanceledOnTouchOutside(true);
- }
+ private void showSettings ()
+ {
+
+ startActivityForResult(new Intent(this, SettingsPreferences.class), 1);
+ }
+
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ //if we get a response from an activity we launched (like from line 527 where we launch the Settings/Prefs screen)
+ //and the resultCode matches our arbitrary 1010 value, AND Tor is running
+ //then update the preferences in an async background task
+ if (requestCode == 1 && resultCode == 1010 && mService != null)
+ {
+ new ProcessSettingsAsyncTask().execute(mService);
+ }
+ }
+
+ AlertDialog aDialog = null;
+
+ //general alert dialog for mostly Tor warning messages
+ //sometimes this can go haywire or crazy with too many error
+ //messages from Tor, and the user cannot stop or exit Orbot
+ //so need to ensure repeated error messages are not spamming this method
+ private void showAlert(String title, String msg, boolean button)
+ {
+ try
+ {
+ if (aDialog != null && aDialog.isShowing())
+ aDialog.dismiss();
+ }
+ catch (Exception e){} //swallow any errors
+
+ if (button)
+ {
+ aDialog = new AlertDialog.Builder(this)
+ .setIcon(R.drawable.icon)
+ .setTitle(title)
+ .setMessage(msg)
+ .setPositiveButton(android.R.string.ok, null)
+ .show();
+ }
+ else
+ {
+ aDialog = new AlertDialog.Builder(this)
+ .setIcon(R.drawable.icon)
+ .setTitle(title)
+ .setMessage(msg)
+ .show();
+ }
+
+ aDialog.setCanceledOnTouchOutside(true);
+ }
/*
* Set the state of the running/not running graphic and label
+ * this all needs to be looked at w/ the shift to progressDialog
*/
public void updateStatus (String torServiceMsg)
{
- try
- {
-
- if (mService != null)
- torStatus = mService.getStatus();
-
- if (imgStatus != null)
- {
-
- if (torStatus == STATUS_ON)
- {
- imgStatus.setImageResource(R.drawable.toron);
-
- hideProgressDialog();
-
- String lblMsg = getString(R.string.status_activated);
- //+ "\n" + torServiceMsg;
-
- lblStatus.setText(lblMsg);
-
- if (torServiceMsg.length() > 0)
- showAlert("Update", torServiceMsg, false);
-
- boolean showFirstTime = prefs.getBoolean("connect_first_time",true);
-
- if (showFirstTime)
- {
-
- Editor pEdit = prefs.edit();
-
- pEdit.putBoolean("connect_first_time",false);
-
- pEdit.commit();
-
- showAlert(getString(R.string.status_activated),getString(R.string.connect_first_time),true);
-
- }
-
- if (mItemOnOff != null)
- mItemOnOff.setTitle(R.string.menu_stop);
-
-
- }
- else if (torStatus == STATUS_CONNECTING)
- {
-
- imgStatus.setImageResource(R.drawable.torstarting);
-
- if (progressDialog != null)
- progressDialog.setMessage(torServiceMsg);
-
- if (mItemOnOff != null)
- mItemOnOff.setTitle(R.string.menu_stop);
-
- }
- else if (torStatus == STATUS_OFF)
- {
- imgStatus.setImageResource(R.drawable.toroff);
-
-
- hideProgressDialog();
-
- lblStatus.setText(getString(R.string.status_shutting_down));
-
- if (mItemOnOff != null)
- mItemOnOff.setTitle(R.string.menu_start);
- }
- else
- {
-
-
- hideProgressDialog();
-
- imgStatus.setImageResource(R.drawable.toroff);
- lblStatus.setText(getString(R.string.status_disabled) + "\n" + getString(R.string.press_to_start));
-
- if (mItemOnOff != null)
- mItemOnOff.setTitle(R.string.menu_start);
-
- }
- }
-
- }
- catch (RemoteException e)
- {
- Log.e(TAG,"remote exception updating status",e);
- }
-
+ try
+ {
+ //if the serivce is bound, query it for the curren status value (int)
+ if (mService != null)
+ torStatus = mService.getStatus();
+
+ //now update the layout_main UI based on the status
+ if (imgStatus != null)
+ {
+
+ if (torStatus == STATUS_ON)
+ {
+ imgStatus.setImageResource(R.drawable.toron);
+
+ hideProgressDialog();
+
+ String lblMsg = getString(R.string.status_activated);
+ //+ "\n" + torServiceMsg;
+
+ lblStatus.setText(lblMsg);
+
+ if (torServiceMsg.length() > 0)
+ showAlert("Update", torServiceMsg, false);
+
+ boolean showFirstTime = prefs.getBoolean("connect_first_time",true);
+
+ if (showFirstTime)
+ {
+
+ Editor pEdit = prefs.edit();
+
+ pEdit.putBoolean("connect_first_time",false);
+
+ pEdit.commit();
+
+ showAlert(getString(R.string.status_activated),getString(R.string.connect_first_time),true);
+
+ }
+
+ if (mItemOnOff != null)
+ mItemOnOff.setTitle(R.string.menu_stop);
+
+
+ }
+ else if (torStatus == STATUS_CONNECTING)
+ {
+
+ imgStatus.setImageResource(R.drawable.torstarting);
+
+ if (progressDialog != null)
+ progressDialog.setMessage(torServiceMsg);
+
+ if (mItemOnOff != null)
+ mItemOnOff.setTitle(R.string.menu_stop);
+
+ }
+ else if (torStatus == STATUS_OFF)
+ {
+ imgStatus.setImageResource(R.drawable.toroff);
+
+
+ hideProgressDialog();
+
+ lblStatus.setText(getString(R.string.status_shutting_down));
+
+ if (mItemOnOff != null)
+ mItemOnOff.setTitle(R.string.menu_start);
+ }
+ else
+ {
+
+
+ hideProgressDialog();
+
+ imgStatus.setImageResource(R.drawable.toroff);
+ lblStatus.setText(getString(R.string.status_disabled) + "\n" + getString(R.string.press_to_start));
+
+ if (mItemOnOff != null)
+ mItemOnOff.setTitle(R.string.menu_start);
+
+ }
+ }
+
+ }
+ catch (RemoteException e)
+ {
+ Log.e(TAG,"remote exception updating status",e);
+ }
+
}
+ // guess what? this start's Tor! actually no it just requests via the local ITorService to the remote TorService instance
+ // to start Tor
private void startTor () throws RemoteException
{
-
- bindService();
-
- mService.setProfile(TorServiceConstants.PROFILE_ON); //this means turn on
-
- imgStatus.setImageResource(R.drawable.torstarting);
- lblStatus.setText(getString(R.string.status_starting_up));
-
- Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
- mHandler.sendMessage(msg);
-
-
-
+ // here we bind AGAIN - at some point i think we had to bind multiple times just in case
+ // but i would love to clarify, clean this up
+ bindService();
+
+ // this is a bit of a strange/old/borrowed code/design i used to change the service state
+ // not sure it really makes sense when what we want to say is just "startTor"
+ mService.setProfile(TorServiceConstants.PROFILE_ON); //this means turn on
+
+ //here we update the UI which is a bit sloppy and mixed up code wise
+ //might be best to just call updateStatus() instead of directly manipulating UI in this method - yep makes sense
+ imgStatus.setImageResource(R.drawable.torstarting);
+ lblStatus.setText(getString(R.string.status_starting_up));
+
+
+ //we send a message here to the progressDialog i believe, but we can clarify that shortly
+ Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
+ mHandler.sendMessage(msg);
+
+
+
}
+ //now we stop Tor! amazing!
private void stopTor () throws RemoteException
{
- if (mService != null)
- {
- mService.setProfile(TorServiceConstants.PROFILE_OFF);
- Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG);
- mHandler.sendMessage(msg);
- }
-
+ //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);
+ }
+
}
- /*
+ /*
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
- public boolean onLongClick(View view) {
-
-
- try
- {
-
- if (mService == null)
- {
-
- }
- else if (mService.getStatus() == STATUS_READY)
- {
-
- createProgressDialog(getString(R.string.status_starting_up));
-
- startTor();
- }
- else
- {
-
- stopTor();
-
- }
-
- }
- catch (Exception e)
- {
- Log.d(TAG,"error onclick",e);
- }
-
- return true;
- }
-
+ public boolean onLongClick(View view) {
+
+
+ try
+ {
+
+ if (mService == null)
+ {
+
+ }
+ else if (mService.getStatus() == STATUS_READY)
+ {
+
+ createProgressDialog(getString(R.string.status_starting_up));
+
+ startTor();
+ }
+ else
+ {
+
+ stopTor();
+
+ }
+
+ }
+ catch (Exception e)
+ {
+ Log.d(TAG,"error onclick",e);
+ }
+
+ return true;
+ }
+
/**
* This implementation is used to receive callbacks from the remote
- * service.
+ * service.
+ *
+ * If we have this setup probably, we shouldn't have to poll or query status
+ * to the service, as it should send it as it changes or when we bind/unbind to it
+ * from this activity
*/
private ITorServiceCallback mCallback = new ITorServiceCallback.Stub() {
/**
@@ -684,50 +770,55 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
* NOT be running in our main thread like most other things -- so,
* to update the UI, we need to use a Handler to hop over there.
*/
+
+ //receive a new string vaule end-user displayable message from the ITorService
public void statusChanged(String value) {
- Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG);
- msg.getData().putString(HANDLER_TOR_MSG, value);
- mHandler.sendMessage(msg);
+ //pass it off to the progressDialog
+ Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_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 //this was when we displayed the log in the main Activity; can prob take this out now
+ public void logMessage(String value) throws RemoteException {
+
+ Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG);
+ msg.getData().putString(HANDLER_TOR_MSG, value);
+ mHandler.sendMessage(msg);
+
+ }
};
+// this is what takes messages or values from the callback threads or other non-mainUI threads
+//and passes them back into the main UI thread for display to the user
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case TorServiceConstants.STATUS_MSG:
- String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
-
- updateStatus(torServiceMsg);
-
+ String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
+
+ updateStatus(torServiceMsg);
+
break;
case TorServiceConstants.LOG_MSG:
-
-
+
+
break;
case TorServiceConstants.ENABLE_TOR_MSG:
-
-
- updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
-
- break;
+
+
+ updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
+
+ break;
case TorServiceConstants.DISABLE_TOR_MSG:
-
- updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
-
- break;
-
+
+ updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
+
+ break;
+
default:
super.handleMessage(msg);
}
@@ -741,6 +832,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
/**
* Class for interacting with the main interface of the service.
*/
+ // this is the connection that gets called back when a successfull bind occurs
+ // we should use this to activity monitor unbind so that we don't have to call
+ // bindService() a million times
+
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
@@ -756,14 +851,15 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
try {
mService.registerCallback(mCallback);
+ //again with the update status?!? :P
updateStatus("");
if (autoStartOnBind)
{
- autoStartOnBind = false;
-
- startTor();
-
+ autoStartOnBind = false;
+
+ startTor();
+
}
} catch (RemoteException e) {
@@ -771,7 +867,7 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
- Log.d(TAG,"error registering callback to service",e);
+ Log.d(TAG,"error registering callback to service",e);
}
@@ -789,20 +885,26 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
}
};
+ //should move this up with all the other class variables
boolean mIsBound = false;
+ //this is where we bind!
private void bindService ()
{
- bindService(new Intent(ITorService.class.getName()),
+ //since its auto create, we prob don't ever need to call startService
+ //also we should again be consistent with using either iTorService.class.getName()
+ //or the variable constant
+ bindService(new Intent(ITorService.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
-
- mIsBound = true;
+
+ mIsBound = true;
}
+ //unbind removes the callback, and unbinds the service
private void unbindService ()
{
- if (mIsBound) {
+ if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mService != null) {
@@ -813,7 +915,10 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
// There is nothing special we need to do if the service
// has crashed.
}
- }
+ }
+
+ //maybe needs this?
+ mService = null;
// Detach our existing connection.
unbindService(mConnection);
@@ -821,26 +926,26 @@ public class Orbot extends Activity implements OnLongClickListener, TorConstants
}
}
-
+
private void createProgressDialog (String msg)
{
- if (progressDialog != null && progressDialog.isShowing())
- return;
-
- progressDialog = ProgressDialog.show(Orbot.this, "", msg);
- progressDialog.setCancelable(true);
+ if (progressDialog != null && progressDialog.isShowing())
+ return;
+
+ progressDialog = ProgressDialog.show(Orbot.this, "", msg);
+ progressDialog.setCancelable(true);
}
private void hideProgressDialog ()
{
- if (progressDialog != null && progressDialog.isShowing())
- {
- progressDialog.dismiss();
+ if (progressDialog != null && progressDialog.isShowing())
+ {
+ progressDialog.dismiss();
- }
-
-
+ }
+
+
}
}
diff --git a/src/org/torproject/android/boot/OnbootBroadcastReceiver.java b/src/org/torproject/android/boot/OnbootBroadcastReceiver.java
deleted file mode 100644
index 163e708..0000000
--- a/src/org/torproject/android/boot/OnbootBroadcastReceiver.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.torproject.android.boot;
-
-import org.torproject.android.service.ITorService;
-import org.torproject.android.service.TorService;
-import org.torproject.android.service.TorServiceConstants;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-public class OnbootBroadcastReceiver extends BroadcastReceiver implements TorServiceConstants {
- @Override
- public void onReceive(Context context, Intent intent) {
-
- Log.d(TAG, "received on boot notification");
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-
- boolean startOnBoot = prefs.getBoolean("pref_start_boot",true);
-
- Log.d(TAG, "startOnBoot:" + startOnBoot);
-
- if (startOnBoot)
- {
- Intent serviceIntent = new Intent(context,TorService.class);
- serviceIntent.setAction("onboot");
- context.startService(serviceIntent);
- }
-
- //bindService(new Intent(ITorService.class.getName()),
- // mConnection, Context.BIND_AUTO_CREATE);
- }
-
-}
\ No newline at end of file
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index 4be1eee..1b11492 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
+/* Copyright (c) 2009-2011, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
/* See LICENSE for licensing information */
package org.torproject.android.service;
@@ -545,6 +545,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
boolean enableTransparentProxy = prefs.getBoolean("pref_transparent", false);
boolean transProxyAll = prefs.getBoolean("pref_transparent_all", false);
boolean transProxyPortFallback = prefs.getBoolean("pref_transparent_port_fallback", false);
+ boolean transProxyTethering = prefs.getBoolean("pref_transparent_tethering", false);
TorService.logMessage ("Transparent Proxying: " + enableTransparentProxy);
@@ -581,6 +582,7 @@ public class TorService extends Service implements TorServiceConstants, Runnable
showAlert("Status", "Setting up app-based transparent proxying...");
code = TorTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this));
}
+
}
TorService.logMessage ("TorTransProxy resp code: " + code);
@@ -588,11 +590,22 @@ public class TorService extends Service implements TorServiceConstants, Runnable
if (code == 0)
{
showAlert("Status", "Transparent proxying ENABLED");
+
+
+
+ if (transProxyTethering)
+ {
+ showAlert("Status", "TransProxy enabled for Tethering!");
+
+ TorTransProxy.enableTetheringRules(this);
+ }
}
else
{
showAlert("Status", "WARNING: error starting transparent proxying!");
}
+
+
return true;
diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java
index 548dda6..de8ea83 100644
--- a/src/org/torproject/android/service/TorTransProxy.java
+++ b/src/org/torproject/android/service/TorTransProxy.java
@@ -313,14 +313,12 @@ public class TorTransProxy implements TorServiceConstants {
return code;
}
- public static int enableWifiHotspotRules (Context context) throws Exception
+ public static int enableTetheringRules (Context context) throws Exception
{
boolean runRoot = true;
boolean waitFor = true;
- //redirectDNSResolvConf(); //not working yet
-
String ipTablesPath = new File(context.getDir("bin", 0),"iptables").getAbsolutePath();
StringBuilder script = new StringBuilder();
@@ -328,25 +326,24 @@ public class TorTransProxy implements TorServiceConstants {
StringBuilder res = new StringBuilder();
int code = -1;
- script.append(ipTablesPath);
- script.append(" -I FORWARD");
- script.append(" -m state --state ESTABLISHED,RELATED -j ACCEPT");
- script.append(" || exit\n");
-
- script.append(ipTablesPath);
- script.append(" -I FORWARD");
- script.append(" -j ACCEPT");
- script.append(" || exit\n");
-
- /*
- script.append(ipTablesPath);
- script.append(" -P FORWARD DROP");
- script.append(" || exit\n");
- */
-
- script.append(ipTablesPath);
- script.append(" -t nat -I POSTROUTING -j MASQUERADE");
- script.append(" || exit\n");
+ String[] hwinterfaces = {"usb0","wl0.1"};
+
+ for (int i = 0; i < hwinterfaces.length; i++)
+ {
+ script.append(ipTablesPath);
+ script.append(" -t nat -A PREROUTING -i ");
+ script.append(hwinterfaces[i]);
+ script.append(" -p udp --dport 53 -j REDIRECT --to-ports ");
+ script.append(TOR_DNS_PORT);
+ script.append(" || exit\n");
+
+ script.append(ipTablesPath);
+ script.append(" -t nat -A PREROUTING -i ");
+ script.append(hwinterfaces[i]);
+ script.append(" -p tcp -j REDIRECT --to-ports ");
+ script.append(TOR_TRANSPROXY_PORT);
+ script.append(" || exit\n");
+ }
String[] cmdAdd = {script.toString()};
@@ -374,8 +371,6 @@ public class TorTransProxy implements TorServiceConstants {
purgeIptables(context);
- enableWifiHotspotRules(context);
-
int torUid = context.getApplicationInfo().uid;
// Set up port redirection
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits