[tor-commits] [orbot/master] added tethering support

n8fr8 at torproject.org n8fr8 at torproject.org
Fri Oct 28 15:28:25 UTC 2011


commit ddb4793b0a051afc9cb9f7dd5d7e7c6589ef861e
Author: Nathan Freitas <nathan at freitas.net>
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





More information about the tor-commits mailing list