[tor-commits] [orbot/master] refactoring into cleaner packages

n8fr8 at torproject.org n8fr8 at torproject.org
Fri Apr 3 17:04:04 UTC 2015


commit 7c303f1589656c2e6de44b96e710a14aae3ec8f5
Author: Nathan Freitas <nathan at freitas.net>
Date:   Mon Feb 2 11:04:32 2015 -0500

    refactoring into cleaner packages
---
 AndroidManifest.xml                                |   23 +-
 .../torproject/android/HiddenServiceManager.java   |   25 -
 src/org/torproject/android/ImageProgressView.java  |   78 --
 src/org/torproject/android/OnBootReceiver.java     |   41 -
 src/org/torproject/android/Orbot.java              | 1234 --------------------
 .../android/OrbotDiagnosticsActivity.java          |  332 ------
 src/org/torproject/android/OrbotMainActivity.java  | 1196 +++++++++++++++++++
 .../torproject/android/RandomColorCircleView.java  |  134 ---
 src/org/torproject/android/Rotate3dAnimation.java  |   76 --
 src/org/torproject/android/Utils.java              |  100 --
 src/org/torproject/android/pluto/PlutoFactory.java |   14 +
 .../torproject/android/pluto/PlutoInstaller.java   |  194 +++
 .../torproject/android/pluto/PlutoInstance.java    |    9 +
 .../android/service/HiddenServiceManager.java      |   25 +
 .../torproject/android/service/OnBootReceiver.java |   39 +
 src/org/torproject/android/service/TorService.java |    5 +-
 src/org/torproject/android/service/Utils.java      |  100 ++
 .../android/ui/ChooseLocaleWizardActivity.java     |  136 +++
 .../torproject/android/ui/ImageProgressView.java   |   78 ++
 src/org/torproject/android/ui/LotsaText.java       |  137 +++
 .../android/ui/OrbotDiagnosticsActivity.java       |  337 ++++++
 .../torproject/android/ui/OrbotLogActivity.java    |   75 ++
 .../torproject/android/ui/Rotate3dAnimation.java   |   76 ++
 src/org/torproject/android/ui/TipsAndTricks.java   |  248 ++++
 .../torproject/android/vpn/OrbotVpnService.java    |   19 +-
 .../android/wizard/ChooseLocaleWizardActivity.java |  136 ---
 src/org/torproject/android/wizard/LotsaText.java   |  137 ---
 .../torproject/android/wizard/TipsAndTricks.java   |  248 ----
 28 files changed, 2695 insertions(+), 2557 deletions(-)

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 416c9b6..6681cd4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="org.torproject.android" 
-      android:versionName="15.1.0" 
-      android:versionCode="1510"
+      android:versionName="15.0.0-alpha-1" 
+      android:versionCode="15001"
         android:installLocation="auto"      
       >
  	    
@@ -29,7 +29,7 @@
       android:largeHeap="false"
      >
       
-        <activity android:name=".Orbot" 
+        <activity android:name=".OrbotMainActivity" 
             android:configChanges="orientation|screenSize"
             android:excludeFromRecents="true"
             android:launchMode="singleTop"
@@ -63,6 +63,12 @@
             
         </activity>
         
+        
+        <activity android:name=".ui.OrbotLogActivity" 
+            android:configChanges="orientation|screenSize"
+            android:exported="false"
+            />
+        
         <!-- 
         This is for ensuring the background service still runs when/if the app is swiped away
          -->
@@ -77,14 +83,13 @@
 			android:stateNotNeeded="true"
 			android:clearTaskOnLaunch="true"
 			android:finishOnTaskLaunch="true"
+			
 			/> 
 			      	
 			      	
-      	<activity android:name=".wizard.LotsaText" android:exported="false"/>
-      	<activity android:name=".wizard.Permissions" android:exported="false"/>
-      	<activity android:name=".wizard.TipsAndTricks" android:exported="false"/>
-      	<activity android:name=".wizard.ConfigureTransProxy" android:exported="false"/>
-      	<activity android:name=".wizard.ChooseLocaleWizardActivity" android:exported="false"/>
+      	<activity android:name=".ui.LotsaText" android:exported="false"/>
+      	<activity android:name=".ui.TipsAndTricks" android:exported="false"/>
+      	<activity android:name=".ui.ChooseLocaleWizardActivitycaleWizardActivity" android:exported="false"/>
       	
       	<activity android:name=".settings.SettingsPreferences"  android:label="@string/app_name"/>
         <activity android:name=".settings.AppManager"  android:label="@string/app_name"/>       
@@ -143,7 +148,7 @@
             </intent-filter>
     	</service>
     	
-    	<receiver android:name=".OnBootReceiver">
+    	<receiver android:name="org.torproject.android.service.OnBootReceiver">
 			<intent-filter>
 				<action	android:name="android.intent.action.BOOT_COMPLETED" />
 				<action android:name="android.intent.action.QUICKBOOT_POWERON" />
diff --git a/src/org/torproject/android/HiddenServiceManager.java b/src/org/torproject/android/HiddenServiceManager.java
deleted file mode 100644
index ca8f7e5..0000000
--- a/src/org/torproject/android/HiddenServiceManager.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.torproject.android;
-
-
-//list view with add/remove hidden services - user is prompted for port
-
-public class HiddenServiceManager {
-
-}
-/*
- * 
- * ## Once you have configured a hidden service, you can look at the
-## contents of the file ".../hidden_service/hostname" for the address
-## to tell people.
-##
-## HiddenServicePort x y:z says to redirect requests on port x to the
-## address y:z.
-
-#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
-#HiddenServicePort 80 127.0.0.1:80
-
-#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
-#HiddenServicePort 80 127.0.0.1:80
-#HiddenServicePort 22 127.0.0.1:22
-*/
-
diff --git a/src/org/torproject/android/ImageProgressView.java b/src/org/torproject/android/ImageProgressView.java
deleted file mode 100644
index 6e813eb..0000000
--- a/src/org/torproject/android/ImageProgressView.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.torproject.android;
-
-import java.util.Random;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageView;
-
-public class ImageProgressView extends ImageView
-{
-
-	  private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
-	  private float progress = 0f; // 0 to 1
-	  
-	  private RectF circle;
-	  
-	public ImageProgressView(Context context) {
-	 super(context);
-	 // TODO Auto-generated constructor stub
-	 init();
-	 
-	}
-
-	public ImageProgressView(Context context, AttributeSet attrs) {
-	 super(context, attrs);
-	 init();
-	}
-
-	public ImageProgressView(Context context, AttributeSet attrs, int defStyle) {
-	 super(context, attrs, defStyle);
-	 
-	 init();
-	}
-
-	private void init(){
-	 paint.setStyle(Paint.Style.STROKE);
-	 paint.setColor(Color.GREEN);
-	 paint.setAntiAlias(true);
-	 paint.setStrokeWidth(20);
-	 
-	}
-
-	@Override
-	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-	   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-	   
-	   setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
-	   MeasureSpec.getSize(heightMeasureSpec));
-	 
-	}
-
-	@Override
-	protected void onDraw(Canvas canvas) {
-
-		super.onDraw(canvas);
-		
-		if (circle == null)
-		{
-		circle = new RectF(getWidth()/2,getHeight()/2+getHeight()/8, getWidth()/3,getHeight()/3);
-		}
-		
-		float sweepAngle = 360f * progress;
-		
-		canvas.drawArc(circle, 0, sweepAngle, true, paint);
-		
-	}
-	
-	
-
-	
-}
\ No newline at end of file
diff --git a/src/org/torproject/android/OnBootReceiver.java b/src/org/torproject/android/OnBootReceiver.java
deleted file mode 100644
index 0e34f50..0000000
--- a/src/org/torproject/android/OnBootReceiver.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.torproject.android;
-
-import org.torproject.android.service.TorService;
-import org.torproject.android.service.TorServiceUtils;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-
-public class OnBootReceiver extends BroadcastReceiver {
-	
-	@Override
-	public void onReceive(Context context, Intent intent) {
-		
-		SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context.getApplicationContext());
-		
-		boolean startOnBoot = prefs.getBoolean("pref_start_boot",true);
-		
-		if (startOnBoot)
-		{
-			startService("init",context);
-			startService("start",context);			
-		}
-
-	}
-	
-
-	private void startService (String action, Context context)
-	{
-		
-		Intent torService = new Intent(context, TorService.class);    
-		torService.setAction(action);
-		context.startService(torService);
-		
-        
-	}
-	
-	
-}
-
diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java
deleted file mode 100644
index edb3c09..0000000
--- a/src/org/torproject/android/Orbot.java
+++ /dev/null
@@ -1,1234 +0,0 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
-/* See LICENSE for licensing information */
-
-package org.torproject.android;
-
-import static org.torproject.android.TorConstants.TAG;
-import info.guardianproject.browser.Browser;
-
-import java.net.URLDecoder;
-import java.util.Locale;
-
-import org.torproject.android.service.TorService;
-import org.torproject.android.service.TorServiceConstants;
-import org.torproject.android.service.TorServiceUtils;
-import org.torproject.android.settings.SettingsPreferences;
-import org.torproject.android.wizard.ChooseLocaleWizardActivity;
-
-import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Configuration;
-import android.net.Uri;
-import android.net.VpnService;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v7.app.ActionBarActivity;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.view.View.OnTouchListener;
-import android.view.animation.AccelerateInterpolator;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.Toast;
-
-
-public class Orbot extends ActionBarActivity implements TorConstants, OnLongClickListener, OnTouchListener, OnSharedPreferenceChangeListener
-{
-	/* Useful UI bits */
-	//private TextView lblStatus = null; //the main text display widget
-	private ImageProgressView imgStatus = null; //the main touchable image for activating Orbot
-
-	private MenuItem mItemOnOff = null;
-    private TextView downloadText = null;
-    private TextView uploadText = null;
-    private boolean mDrawerOpen = false;
-  
-    private Button mBtnBrowser = null;
-    private Button mBtnVPN = null;
-
-	/* Some tracking bits */
-	private int torStatus = TorServiceConstants.STATUS_OFF; //latest status reported from the tor service
-	
-	private SharedPreferences mPrefs = null;
-
-	private boolean autoStartFromIntent = false;
-	
-	private final static long INIT_DELAY = 100;
-
-    /** Called when the activity is first created. */
-	public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        mPrefs = TorServiceUtils.getSharedPrefs(getApplicationContext());        
-        mPrefs.registerOnSharedPreferenceChangeListener(this);
-           	
-        setLocale();
-        
-    	doLayout();
-
-    //	appConflictChecker ();
-    	
-
-  	  // Register to receive messages.
-  	  // We are registering an observer (mMessageReceiver) to receive Intents
-  	  // with actions named "custom-event-name".
-  	  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
-  	      new IntentFilter("status"));
-  	  
-		LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
-			      new IntentFilter("log"));
-
-		mHandler.postDelayed(new Runnable ()
-		{
-		
-			public void run ()
-			{
-				startService(TorServiceConstants.CMD_INIT);
-			}
-		},INIT_DELAY);
-		
-	}
-	
-	// Our handler for received Intents. This will be called whenever an Intent
-	// with an action named "custom-event-name" is broadcasted.
-	private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
-		
-		
-		
-	  @Override
-	  public void onReceive(Context context, Intent intent) {
-	    // Get extra data included in the Intent
-		  
-		if (intent.hasExtra("log"))
-		{
-			String log = intent.getStringExtra("log");
-			updateStatus(log);
-		}
-		else if (intent.hasExtra("up"))
-		{
-			long upload = intent.getLongExtra("up",0);
-			long download = intent.getLongExtra("down",0);
-			long written = intent.getLongExtra("written",0);
-			long read = intent.getLongExtra("read",0);
-			
-			Message msg = mHandler.obtainMessage(TorServiceConstants.MESSAGE_TRAFFIC_COUNT);
-			msg.getData().putLong("download", download);
-			msg.getData().putLong("upload", upload);
-			msg.getData().putLong("readTotal", read);
-			msg.getData().putLong("writeTotal", written);
-			mHandler.sendMessage(msg);
-			
-		}
-		else if (intent.hasExtra("status"))
-		{
-			torStatus = intent.getIntExtra("status", TorServiceConstants.STATUS_OFF);
-			updateStatus("");
-		}
-		
-	  }
-	};
-
-	ProgressDialog mProgressDialog;
-	
-	private void startService (String action)
-	{
-		
-		Intent torService = new Intent(this, TorService.class);    
-		torService.setAction(action);
-		startService(torService);
-		
-	}
-	
-	private void stopService ()
-	{
-		
-		Intent torService = new Intent(this, TorService.class);
-		stopService(torService);
-		
-	}
-	
-	private void doLayout ()
-	{
-    	setContentView(R.layout.layout_main);
-    	
-    //	lblStatus = (TextView)findViewById(R.id.lblStatus);
-//		lblStatus.setOnLongClickListener(this);
-    	imgStatus = (ImageProgressView)findViewById(R.id.imgStatus);
-    	imgStatus.setOnLongClickListener(this);
-    	imgStatus.setOnTouchListener(this);
-    	
-  //  	lblStatus.setText("Initializing the application...");
-    	
-    	downloadText = (TextView)findViewById(R.id.trafficDown);
-        uploadText = (TextView)findViewById(R.id.trafficUp);
-      //  mTxtOrbotLog = (TextView)findViewById(R.id.orbotLog);
-        
-        /*
-        mDrawer = ((SlidingDrawer)findViewById(R.id.SlidingDrawer));
-    	Button slideButton = (Button)findViewById(R.id.slideButton);
-    	if (slideButton != null)
-    	{
-	    	slideButton.setOnTouchListener(new OnTouchListener (){
-	
-				@Override
-				public boolean onTouch(View v, MotionEvent event) {
-	
-					if (event.equals(MotionEvent.ACTION_DOWN))
-					{
-						mDrawerOpen = !mDrawerOpen;
-						mTxtOrbotLog.setEnabled(mDrawerOpen);				
-					}
-					return false;
-				}
-	    		
-	    	});
-    	}*/
-    	
-        /*
-    	ScrollingMovementMethod smm = new ScrollingMovementMethod();
-    	
-        mTxtOrbotLog.setMovementMethod(smm);
-        mTxtOrbotLog.setOnLongClickListener(new View.OnLongClickListener() {
-         
-
-			@Override
-			public boolean onLongClick(View v) {
-				  ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
-	                cm.setText(mTxtOrbotLog.getText());
-	                Toast.makeText(Orbot.this, "LOG COPIED TO CLIPBOARD", Toast.LENGTH_SHORT).show();
-	            return true;
-			}
-        });*/
-        
-		downloadText.setText(formatCount(0) + " / " + formatTotal(0));
-		uploadText.setText(formatCount(0) + " / " + formatTotal(0));
-	
-        // Gesture detection
-		mGestureDetector = new GestureDetector(this, new MyGestureDetector());
-		
-		mBtnBrowser = (Button)findViewById(R.id.btnBrowser);
-		mBtnBrowser.setOnClickListener(new View.OnClickListener ()
-		{
-
-			@Override
-			public void onClick(View v) {
-				doTorCheck();
-				
-			}
-
-			
-		});
-		
-		mBtnVPN = (Button)findViewById(R.id.btnVPN);
-		mBtnVPN.setOnClickListener(new View.OnClickListener ()
-		{
-
-			@Override
-			public void onClick(View v) {
-
-				startVpnService();
-				
-			}
-
-			
-		});
-		
-
-    }
-	
-	GestureDetector mGestureDetector;
-    
-
-	@Override
-	public boolean onTouch(View v, MotionEvent event) {
-	    return mGestureDetector.onTouchEvent(event);
-
-	}
-   	
-	/*
-    private void appendLogTextAndScroll(String text)
-    {
-    	
-        if(mTxtOrbotLog != null && text != null && text.length() > 0){
-        	
-        	if (mTxtOrbotLog.getText().length() > MAX_LOG_LENGTH)
-        		mTxtOrbotLog.setText("");
-        	
-        	mTxtOrbotLog.append(text + "\n");
-            final Layout layout = mTxtOrbotLog.getLayout();
-            if(layout != null){
-                int scrollDelta = layout.getLineBottom(mTxtOrbotLog.getLineCount() - 1) 
-                    - mTxtOrbotLog.getScrollY() - mTxtOrbotLog.getHeight();
-                if(scrollDelta > 0)
-                	mTxtOrbotLog.scrollBy(0, scrollDelta);
-            }
-        }
-    }*/
-    
-   /*
-    * Create the UI Options Menu (non-Javadoc)
-    * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
-    */
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.orbot_main, menu);
-       
-        mItemOnOff = menu.getItem(0);
-        
-        return true;
-    }
-    
-    /**
-    private void appConflictChecker ()
-    {
-    	SharedPreferences sprefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
-    	
-    	boolean showAppConflict = true;//sprefs.getBoolean("pref_show_conflict",true);
-    	
-    	String[] badApps = {"com.sec.msc.nts.android.proxy:com.sec.msc.nts.android.proxy","com.sec.pcw:Samsung Link"};
-    	
-    	for (String badApp : badApps)
-    	{
-    		String[] badAppParts = badApp.split(":");
-    		
-    		if (appInstalledOrNot(badAppParts[0]))
-    		{
-    			String msg = getString(R.string.please_disable_this_app_in_android_settings_apps_if_you_are_having_problems_with_orbot_) + badAppParts[1];
-    			
-    			if (showAppConflict)
-    				showAlert(getString(R.string.app_conflict),msg,true);
-	    	
-	    	//	appendLogTextAndScroll(msg);
-    		}
-    	}
-    	
-    	sprefs.edit().putBoolean("pref_show_conflict", false).commit();
-	
-    }*/
-    
-    
-    
-
-    private void showAbout ()
-        {
-                
-	        LayoutInflater li = LayoutInflater.from(this);
-	        View view = li.inflate(R.layout.layout_about, null); 
-	        
-	        String version = "";
-	        
-	        try {
-	        	version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName + " (Tor " + TorServiceConstants.BINARY_TOR_VERSION + ")";
-	        } catch (NameNotFoundException e) {
-	        	version = "Version Not Found";
-	        }
-	        
-	        TextView versionName = (TextView)view.findViewById(R.id.versionName);
-	        versionName.setText(version);    
-	        
-	                new AlertDialog.Builder(this)
-	        .setTitle(getString(R.string.button_about))
-	        .setView(view)
-	        .show();
-        }
-    
-    	@Override
-        public boolean onOptionsItemSelected(MenuItem item) {
-                
-                super.onOptionsItemSelected(item);
-                
-                if (item.getItemId() == R.id.menu_start)
-                {
-                        
-                        try
-                        {
-                                
-                                if (torStatus == TorServiceConstants.STATUS_OFF)
-                                {
-                                    if (mItemOnOff != null)
-                                            mItemOnOff.setTitle(R.string.menu_stop);
-                                        startTor();
-                                        
-                                }
-                                else
-                                {
-                                    if (mItemOnOff != null)
-                                            mItemOnOff.setTitle(R.string.menu_start);
-                                    
-                                        stopTor();
-                                        stopService ();
-                                        
-                                }
-                                
-                        }
-                        catch (RemoteException re)
-                        {
-                                Log.w(TAG, "Unable to start/top Tor from menu UI", re);
-                        }
-                }
-                else if (item.getItemId() == R.id.menu_settings)
-                {
-                        showSettings();
-                }
-                else if (item.getItemId() == R.id.menu_wizard)
-                {
-            		startActivity(new Intent(this, ChooseLocaleWizardActivity.class));
-
-                }
-                else if (item.getItemId() == R.id.menu_exit)
-                {
-                        //exit app
-                        doExit();
-                        
-                        
-                }
-                else if (item.getItemId() == R.id.menu_about)
-                {
-                        showAbout();
-                        
-                        
-                }
-
-                /**
-                else if (item.getItemId() == R.id.menu_verify)
-                {
-                        doTorCheck();
-                }
-                else if (item.getItemId() == R.id.menu_vpn)
-                {
-                		startVpnService();
-                }*/
-                
-                return true;
-        }
-      
-        /**
-        * 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();
-                        stopService ();
-                        
-                        
-                } catch (RemoteException e) {
-                        Log.w(TAG, e);
-                }
-                
-                //Kill all the wizard activities
-                setResult(RESULT_CLOSE_ALL);
-                finish();
-                
-        }
-        
-    /* (non-Javadoc)
-	 * @see android.app.Activity#onPause()
-	 */
-	protected void onPause() {
-		try
-		{
-			super.onPause();
-	
-			if (aDialog != null)
-				aDialog.dismiss();
-		}
-		catch (IllegalStateException ise)
-		{
-			//can happen on exit/shutdown
-		}
-	}
-	
-	private void doTorCheck ()
-	{
-		
-		openBrowser(URL_TOR_CHECK);
-		
-
-	}
-	
-	private void enableHiddenServicePort (int hsPort)
-	{
-		
-		Editor pEdit = mPrefs.edit();
-		
-		String hsPortString = mPrefs.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 = mPrefs.getString("pref_hs_hostname","");
-
-		while (onionHostname.length() == 0)
-		{
-			//we need to stop and start Tor
-			try {
-				stopTor();
-				
-				Thread.sleep(3000); //wait three seconds
-				
-				startTor();
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			 
-			 onionHostname = mPrefs.getString("pref_hs_hostname","");
-		}
-		
-		Intent nResult = new Intent();
-		nResult.putExtra("hs_host", onionHostname);
-		setResult(RESULT_OK, nResult);
-	
-	}
-
-
-	private synchronized void handleIntents ()
-	{
-		if (getIntent() == null)
-			return;
-		
-	    // Get intent, action and MIME type
-	    Intent intent = getIntent();
-	    String action = intent.getAction();
-	    String type = intent.getType();
-		
-		if (action == null)
-			return;
-		
-		if (action.equals("org.torproject.android.REQUEST_HS_PORT"))
-		{
-			
-			DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
-			    
-			    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 = getString(R.string.hidden_service_request, hsPort);
-			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"))
-		{
-			autoStartFromIntent = true;
-				
-				try {
-					startTor();
-
-					Intent nResult = new Intent();
-					
-					//nResult.putExtra("socks", ); //TODO respond with socks, transport, dns, etc
-					
-					setResult(RESULT_OK,nResult);
-					
-				} catch (RemoteException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			
-		}
-		else if (action.equals(Intent.ACTION_VIEW))
-		{
-			String urlString = intent.getDataString();
-			
-			if (urlString != null)
-			{
-				
-				if (urlString.toLowerCase().startsWith("bridge://"))
-
-				{
-					String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece
-					newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here
-		
-					showAlert("Bridges Updated","Restart Orbot to use this bridge: " + newBridgeValue,false);	
-					
-					String bridges = mPrefs.getString(TorConstants.PREF_BRIDGES_LIST, null);
-					
-					Editor pEdit = mPrefs.edit();
-					
-					if (bridges != null && bridges.trim().length() > 0)
-					{
-						if (bridges.indexOf('\n')!=-1)
-							bridges += '\n' + newBridgeValue;
-						else
-							bridges += ',' + newBridgeValue;
-					}
-					else
-						bridges = newBridgeValue;
-					
-					pEdit.putString(TorConstants.PREF_BRIDGES_LIST,bridges); //set the string to a preference
-					pEdit.putBoolean(TorConstants.PREF_BRIDGES_ENABLED,true);
-				
-					pEdit.commit();
-					
-					setResult(RESULT_OK);
-				}
-			}
-		}
-		else
-		{
-		
-			showWizard = mPrefs.getBoolean("show_wizard",showWizard);
-			
-			if (showWizard)
-			{
-				Editor pEdit = mPrefs.edit();
-				pEdit.putBoolean("show_wizard",false);
-				pEdit.commit();				
-				showWizard = false;
-
-				startActivity(new Intent(this, ChooseLocaleWizardActivity.class));
-
-			}
-			
-		}
-		
-		setIntent(null);
-		
-		updateStatus ("");
-		
-	}
-
-	private boolean showWizard = true;
-	
-	
-	@Override
-	public void onConfigurationChanged(Configuration newConfig) {
-		super.onConfigurationChanged(newConfig);
-		
-		doLayout();
-		updateStatus("");
-	}
-
-
-	/*
-	 * Launch the system activity for Uri viewing with the provided url
-	 */
-	private void openBrowser(final String browserLaunchUrl)
-	{
-		//startIntent("info.guardianproject.browser.Browser",Intent.ACTION_VIEW,Uri.parse(browserLaunchUrl));						
-
-		Intent intentBrowser = new Intent(this, Browser.class);
-		intentBrowser.setAction(Intent.ACTION_VIEW);
-		intentBrowser.setData(Uri.parse(browserLaunchUrl));
-		startActivity(intentBrowser);
-		
-		/**
-		boolean isOrwebInstalled = appInstalledOrNot("info.guardianproject.browser");
-		boolean isTransProxy =  mPrefs.getBoolean("pref_transparent", false);
-		
-		if (isOrwebInstalled)
-		{
-		}
-		else if (isTransProxy)
-		{
-			Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
-			intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
-			startActivity(intent);
-		}
-		else
-		{
-			AlertDialog aDialog = new AlertDialog.Builder(Orbot.this)
-              .setIcon(R.drawable.onion32)
-		      .setTitle(R.string.install_apps_)
-		      .setMessage(R.string.it_doesn_t_seem_like_you_have_orweb_installed_want_help_with_that_or_should_we_just_open_the_browser_)
-		      .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener ()
-		      {
-
-				@Override
-				public void onClick(DialogInterface dialog, int which) {
-
-					//prompt to install Orweb
-					Intent intent = new Intent(Orbot.this,TipsAndTricks.class);
-					startActivity(intent);
-					
-				}
-		    	  
-		      })
-		      .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener ()
-		      {
-
-				@Override
-				public void onClick(DialogInterface dialog, int which) {
-					Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
-					intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
-					startActivity(intent);
-					
-				}
-		    	  
-		      })
-		      .show();
-			  
-		}*/
-		
-	}
-	
-	private void startIntent (String pkg, String action, Uri data)
-	{
-		Intent i;
-		PackageManager manager = getPackageManager();
-		try {
-		    i = manager.getLaunchIntentForPackage(pkg);
-		    if (i == null)
-		        throw new PackageManager.NameNotFoundException();		    
-		    i.setAction(action);
-		    i.setData(data);
-		    startActivity(i);
-		} catch (PackageManager.NameNotFoundException e) {
-
-		}
-	}
-	
-	private boolean appInstalledOrNot(String uri)
-    {
-        PackageManager pm = getPackageManager();
-        try
-        {
-               PackageInfo pi = pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);               
-               return pi.applicationInfo.enabled;
-        }
-        catch (PackageManager.NameNotFoundException e)
-        {
-              return false;
-        }
-}
-	
-    /*
-     * Load the basic settings application to display torrc
-     */
-    private void showSettings ()
-    {
-            
-            startActivityForResult(new Intent(this, SettingsPreferences.class), 1);
-    }
-    
-    
-    @Override
-	protected void onActivityResult(int request, int response, Intent data) {
-		super.onActivityResult(request, response, data);
-		
-		
-		if (request == 1 && response == RESULT_OK)
-		{
-			if (data != null && data.getBooleanExtra("transproxywipe", false))
-			{
-					
-					boolean result = flushTransProxy();
-					
-					if (result)
-					{
-
-			    		Toast.makeText(this, R.string.transparent_proxy_rules_flushed_, Toast.LENGTH_SHORT).show();
-				 		
-					}
-					else
-					{
-
-			    		Toast.makeText(this, R.string.you_do_not_have_root_access_enabled, Toast.LENGTH_SHORT).show();
-				 		
-					}
-				
-			}
-			else if (torStatus == TorServiceConstants.STATUS_ON)
-			{
-				updateSettings();
-	    		Toast.makeText(this, R.string.you_may_need_to_stop_and_start_orbot_for_settings_change_to_be_enabled_, Toast.LENGTH_SHORT).show();
-
-			}
-		}
-		else if (request == REQUEST_VPN && response == RESULT_OK)
-		{
-			startService(TorServiceConstants.CMD_VPN);
-		}
-		
-	}
-    
-    private final static int REQUEST_VPN = 8888;
-    
-    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
-	public void startVpnService ()
-    {
-    	 Intent intent = VpnService.prepare(this);
-	        if (intent != null) {
-	            startActivityForResult(intent,REQUEST_VPN);
-	        } 
-	        else
-	        {
-				startService(TorServiceConstants.CMD_VPN);
-
-	        }
-    }
-
-    private boolean flushTransProxy ()
-    {
-    	startService(TorServiceConstants.CMD_FLUSH);
-    	return true;
-    }
-    
-    private boolean updateSettings ()
-    {
-    	//todo send service command
-    	startService(TorServiceConstants.CMD_UPDATE);
-    	return true;
-    }
-
-	@Override
-	protected void onResume() {
-		super.onResume();
-
-		mHandler.postDelayed(new Runnable ()
-		{
-			public void run ()
-			{
-
-				setLocale();
-		
-				handleIntents();
-
-			}
-		}
-		, 500);
-		
-		
-	}
-
-	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(Orbot.this)
-                     .setIcon(R.drawable.onion32)
-             .setTitle(title)
-             .setMessage(msg)
-             .setPositiveButton(android.R.string.ok, null)
-             .show();
-             }
-             else
-             {
-                     aDialog = new AlertDialog.Builder(Orbot.this)
-                     .setIcon(R.drawable.onion32)
-             .setTitle(title)
-             .setMessage(msg)
-             .show();
-             }
-    
-             aDialog.setCanceledOnTouchOutside(true);
-    }
-    
-	private void updateStatus (String torServiceMsg)
-    {
-        
-            //now update the layout_main UI based on the status
-            if (imgStatus != null)
-            {
-                    
-                    if (torStatus == TorServiceConstants.STATUS_ON)
-                    {
-                        	
-                            imgStatus.setImageResource(R.drawable.toron);
-                    		
-                            mBtnBrowser.setEnabled(true);
-                            mBtnVPN.setEnabled(true);
-                            
-                            String lblMsg = getString(R.string.status_activated);                                     
-                            //lblStatus.setText(lblMsg);
-
-                            if (mItemOnOff != null)
-                                    mItemOnOff.setTitle(R.string.menu_stop);
-                            
-                        
-                            if (torServiceMsg != null && torServiceMsg.length() > 0)
-                            {
-                            //	appendLogTextAndScroll(torServiceMsg);
-                            }
-                            
-                            boolean showFirstTime = mPrefs.getBoolean("connect_first_time",true);
-                            
-                            if (showFirstTime)
-                            {
-                            
-                                    Editor pEdit = mPrefs.edit();
-                                    
-                                    pEdit.putBoolean("connect_first_time",false);
-                                    
-                                    pEdit.commit();
-                                    
-                                    showAlert(getString(R.string.status_activated),getString(R.string.connect_first_time),true);
-                                    
-                            }
-                            
-                            
-                            if (autoStartFromIntent)
-                            {
-                            	setResult(RESULT_OK);
-                            	finish();
-                            }
-
-                    }
-                    else if (torStatus == TorServiceConstants.STATUS_CONNECTING)
-                    {
-                    	
-                        imgStatus.setImageResource(R.drawable.torstarting);
-                
-                        if (mItemOnOff != null)
-                                mItemOnOff.setTitle(R.string.menu_stop);
-                	
-                    	/**
-                        if (lblStatus != null && torServiceMsg != null)
-                        	if (torServiceMsg.indexOf('%')!=-1)
-                        		lblStatus.setText(torServiceMsg);
-                        		**/
-                        
-                        //appendLogTextAndScroll(torServiceMsg);
-                        
-                                    
-                    }
-                    else if (torStatus == TorServiceConstants.STATUS_OFF)
-                    {
-                        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);
-
-                        mBtnBrowser.setEnabled(false);
-                        mBtnVPN.setEnabled(false);
-                        
-                    }
-            }
-                
-           
-    }
-		
-         
-  
-  // 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
-    {
-            
-
-		startService (TorServiceConstants.CMD_START);
-		torStatus = TorServiceConstants.STATUS_CONNECTING;
-				
-//		mTxtOrbotLog.setText("");
-
-        //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);
-        msg.getData().putString(HANDLER_TOR_MSG, getString(R.string.status_starting_up));
-        mHandler.sendMessage(msg);
-      
-        
-    	
-    }
-    
-    //now we stop Tor! amazing!
-    private void stopTor () throws RemoteException
-    {
-    	
-    	startService (TorServiceConstants.CMD_STOP);
-		torStatus = TorServiceConstants.STATUS_OFF;
-
-    		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) {
-                
-        	if (!mDrawerOpen)
-        	{
-	            try
-	            {
-	                    
-	                if (torStatus == TorServiceConstants.STATUS_OFF)
-	                {
-	
-	                        startTor();
-	                }
-	                else
-	                {
-	                        
-	                        stopTor();
-	                        stopService ();
-	                        
-	                }
-	                
-	                return true;
-	                    
-	            }
-	            catch (Exception e)
-	            {
-	                    Log.d(TAG,"error onclick",e);
-	            }
-
-        	}
-        	
-            return false;
-                    
-        }
-
-    	
-        
-   
-
-// 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() {
-    	
-    	private String lastServiceMsg = null;
-    	
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case TorServiceConstants.STATUS_MSG:
-                case TorServiceConstants.LOG_MSG:
-
-                        String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
-                        
-                        if (lastServiceMsg == null || !lastServiceMsg.equals(torServiceMsg))
-                        {
-                        	updateStatus(torServiceMsg);
-                        
-                        	lastServiceMsg = torServiceMsg;
-                        }
-                        
-                    break;
-                case TorServiceConstants.ENABLE_TOR_MSG:
-                        
-                        
-                        updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
-                        
-                        break;
-                case TorServiceConstants.DISABLE_TOR_MSG:
-                	
-                	updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
-                	
-                	break;
-                	
-
-            	case TorServiceConstants.MESSAGE_TRAFFIC_COUNT :
-                    
-            		Bundle data = msg.getData();
-            		DataCount datacount =  new DataCount(data.getLong("upload"),data.getLong("download"));     
-            		
-            		long totalRead = data.getLong("readTotal");
-            		long totalWrite = data.getLong("writeTotal");
-            	
-        			downloadText.setText(formatCount(datacount.Download) + " / " + formatTotal(totalRead));
-            		uploadText.setText(formatCount(datacount.Upload) + " / " + formatTotal(totalWrite));
-            
-            		if (torStatus != TorServiceConstants.STATUS_ON)
-            		{
-            			updateStatus("");
-            		}
-                		
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-        
-        
-        
-    };
-
-    
-    /**
-     * 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 void setLocale ()
-    {
-    	
-
-        Configuration config = getResources().getConfiguration();
-        String lang = mPrefs.getString(PREF_DEFAULT_LOCALE, "");
-        
-        if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang))
-        {
-        	Locale locale = new Locale(lang);
-            Locale.setDefault(locale);
-            config.locale = locale;
-            getResources().updateConfiguration(config, getResources().getDisplayMetrics());
-        }
-    }
-
-   	@Override
-	protected void onDestroy() {
-		super.onDestroy();
-		  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
-
-	}
-
-	public class DataCount {
-   		// data uploaded
-   		public long Upload;
-   		// data downloaded
-   		public long Download;
-   		
-   		DataCount(long Upload, long Download){
-   			this.Upload = Upload;
-   			this.Download = Download;
-   		}
-   	}
-   	
-   	private String formatCount(long count) {
-		// Converts the supplied argument into a string.
-		// Under 2Mb, returns "xxx.xKb"
-		// Over 2Mb, returns "xxx.xxMb"
-		if (count < 1e6)
-			return ((float)((int)(count*10/1024))/10 + "kbps");
-		return ((float)((int)(count*100/1024/1024))/100 + "mbps");
-		
-   		//return count+" kB";
-	}
-   	
-   	private String formatTotal(long count) {
-		// Converts the supplied argument into a string.
-		// Under 2Mb, returns "xxx.xKb"
-		// Over 2Mb, returns "xxx.xxMb"
-		if (count < 1e6)
-			return ((float)((int)(count*10/1024))/10 + "KB");
-		return ((float)((int)(count*100/1024/1024))/100 + "MB");
-		
-   		//return count+" kB";
-	}
-
-	@Override
-	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
-			String key) {
-	
-		
-	}
-	
-	  private static final float ROTATE_FROM = 0.0f;
-	    private static final float ROTATE_TO = 360.0f*4f;// 3.141592654f * 32.0f;
-
-	public void spinOrbot (float direction)
-	{
-			startService (TorServiceConstants.CMD_NEWNYM);
-		
-		
-			Toast.makeText(this, R.string.newnym, Toast.LENGTH_SHORT).show();
-			
-		//	Rotate3dAnimation rotation = new Rotate3dAnimation(ROTATE_FROM, ROTATE_TO*direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
-			 Rotate3dAnimation rotation = new Rotate3dAnimation(ROTATE_FROM, ROTATE_TO*direction, imgStatus.getWidth()/2f,imgStatus.getWidth()/2f,20f,false);
-			 rotation.setFillAfter(true);
-			  rotation.setInterpolator(new AccelerateInterpolator());
-			  rotation.setDuration((long) 2*1000);
-			  rotation.setRepeatCount(0);
-			  imgStatus.startAnimation(rotation);
-			  
-		
-	}
-	
-	 class MyGestureDetector extends SimpleOnGestureListener {
-	        @Override
-	        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-	            try {	            	
-	            	if (torStatus == TorServiceConstants.STATUS_ON)
-	            	{
-	            		float direction = 1f;
-	            		if (velocityX < 0)
-	            			direction = -1f;
-	            		spinOrbot (direction);
-	            	}
-	            } catch (Exception e) {
-	                // nothing
-	            }
-	            return false;
-	        }
-
-	    }
-
-
-}
diff --git a/src/org/torproject/android/OrbotDiagnosticsActivity.java b/src/org/torproject/android/OrbotDiagnosticsActivity.java
deleted file mode 100644
index b639d82..0000000
--- a/src/org/torproject/android/OrbotDiagnosticsActivity.java
+++ /dev/null
@@ -1,332 +0,0 @@
-package org.torproject.android;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-import org.sufficientlysecure.rootcommands.Shell;
-import org.sufficientlysecure.rootcommands.command.SimpleCommand;
-import org.torproject.android.service.TorResourceInstaller;
-import org.torproject.android.service.TorServiceConstants;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.os.StatFs;
-import android.text.format.Formatter;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.TextView;
-
-
-public class OrbotDiagnosticsActivity extends Activity {
-
-	private TextView mTextView = null;
-	private final static String TAG = "OrbotDiag";
-	private StringBuffer log = new StringBuffer();
-	Process mProcess;
-	
-	@Override
-	protected void onCreate(Bundle savedInstanceState) { 
-		super.onCreate(savedInstanceState);
-		
-		setContentView(R.layout.layout_diag);
-		
-		mTextView = (TextView)findViewById(R.id.diaglog);
-		
-	}
-
-	private String getFreeStorage ()
-	{
-		File path = Environment.getDataDirectory();
-		StatFs stat = new StatFs(path.getPath());
-		long blockSize = stat.getBlockSize();
-		long availableBlocks = stat.getAvailableBlocks();
-		return Formatter.formatFileSize(this, availableBlocks * blockSize);
-	}
-	
-	@Override
-	protected void onPause() {
-		super.onPause();
-		
-		stopTor();
-	}
-
-	@Override
-	protected void onDestroy() {
-
-		super.onDestroy();
-		
-	}
-	
-	private void stopTor ()
-	{
-		File appBinHome = this.getDir("bin", Context.MODE_PRIVATE);
-
-		File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
-    	
-		if (mProcess != null)
-			mProcess.destroy();
-		
-		
-	}
-	
-	
-
-	@Override
-	protected void onResume() {
-		super.onResume();
-
-
-		log("Hello, Orbot!");
-		
-		try
-		{
-			log(android.os.Build.DEVICE);
-			log(android.os.Build.HARDWARE);
-			log(android.os.Build.MANUFACTURER);
-			log(android.os.Build.MODEL);
-			log(android.os.Build.VERSION.CODENAME);
-			log(android.os.Build.VERSION.RELEASE);
-		}
-		catch (Exception e)
-		{
-			log("error getting device info");
-		}
-		
-		showFileTree ();
-		
-		runTorTest();
-	}
-
-	private void runTorTest ()
-	{
-		try
-		{
-			File appBinHome = this.getDir("bin", Context.MODE_PRIVATE);
-			File appDataHome = this.getDir("data", Context.MODE_PRIVATE);
-	
-	    	File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
-	    	enableBinExec (fileTor, appBinHome);	    	
-	    	
-			InputStream is = getResources().openRawResource(R.raw.torrc);
-			File fileTorrc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY + "diag");
-			TorResourceInstaller.streamToFile(is,fileTorrc, false, false);
-		
-			/**
-			ArrayList<String> alEnv = new ArrayList<String>();
-			alEnv.add("HOME=" + appBinHome.getAbsolutePath());
-			Shell shell = Shell.startShell(alEnv,appBinHome.getAbsolutePath());
-			SimpleCommand cmdTor = new SimpleCommand(fileTor.getAbsolutePath() + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + fileTorrc.getAbsolutePath());			
-			shell.add(cmdTor);
-			**/
-			
-			String cmd = fileTor.getAbsolutePath() + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + fileTorrc.getAbsolutePath();
-			
-			log ("Executing command> " + cmd);
-			
-			mProcess = Runtime.getRuntime().exec(cmd);
-			
-			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
-			StreamGobbler sg = new StreamGobbler();
-			sg.reader = bufferedReader;
-			sg.process = mProcess;
-			new Thread(sg).start();
-			
-			if (mProcess.getErrorStream() != null)
-			{
-				bufferedReader = new BufferedReader(new InputStreamReader(mProcess.getErrorStream()));
-				sg = new StreamGobbler();
-				sg.reader = bufferedReader;
-				sg.process = mProcess;
-				new Thread(sg).start();
-			}
-			
-			
-		}
-		catch (Exception e)
-		{
-			Log.d(TAG,"runTorTest exception",e);
-		}
-        
-	}
-	
-	class StreamGobbler implements Runnable
-	{
-		BufferedReader reader;
-		Process process;
-		
-		public void run ()
-		{
-			String line = null;			
-			try {
-				while ( (line = reader.readLine()) != null)
-				{
-					Message msg = mHandler.obtainMessage(0);
-					msg.getData().putString("log", line);
-					mHandler.sendMessage(msg);
-				}
-				
-			} catch (IOException e) {
-				Log.d(TAG, "error reading line",e);
-			}
-			
-			//log("Tor exit code=" + process.exitValue() + ";");
-			
-		}
-	}
-	
-	 private boolean enableBinExec (File fileBin, File appBinHome) throws Exception
-	    {
-	    	
-	    	log(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute());
-	  
-	    	if (!fileBin.canExecute())
-	    	{
-	    		log("(re)Setting permission on binary: " + fileBin.getAbsolutePath());	
-				Shell shell = Shell.startShell(new ArrayList<String>(), appBinHome.getAbsolutePath());
-			
-				shell.add(new SimpleCommand("chmod " + TorServiceConstants.CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath())).waitForFinish();
-				
-				File fileTest = new File(fileBin.getAbsolutePath());
-				log(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute());
-				
-				shell.close();
-	    	}
-	    	
-			return fileBin.canExecute();
-	    }
-	
-	private void showFileTree ()
-	{
-		
-		File fileDir = this.getDir("bin", Context.MODE_PRIVATE);
-		
-		if (fileDir.exists())
-		{
-			log("checking file tree: " + fileDir.getAbsolutePath());
-			printDir (fileDir.getName(), fileDir);
-		}
-		else
-		{
-			log("app_bin does not exist");
-		}
-		
-		fileDir = this.getDir("data", Context.MODE_PRIVATE);
-		if (fileDir.exists())
-		{
-			log("checking file tree: " + fileDir.getAbsolutePath());
-			printDir (fileDir.getName(), fileDir);
-		}
-		else
-		{
-			log ("app_data does not exist");
-		}
-				
-
-	}
-	
-	private void printDir (String path, File fileDir)
-	{
-		File[] files = fileDir.listFiles();
-		
-		if (files != null && files.length > 0)
-		{
-			for (File file : files)
-			{
-
-				try
-				{
-					if (file.isDirectory())
-					{
-						printDir(path + '/' + file.getName(), file);
-					}
-					else
-					{
-						log(path + '/' + file.getName() + " len:" + file.length() + " exec:" + file.canExecute());
-						
-					}
-				}
-				catch (Exception e)
-				{
-					log("problem printing out file information");
-				}
-			
-			}
-		}
-	}
-	
-	Handler mHandler = new Handler ()
-	{
-
-		@Override
-		public void handleMessage(Message msg) {
-		
-			super.handleMessage(msg);
-			
-			String logMsg = msg.getData().getString("log");
-			log(logMsg);
-		}
-		
-	};
-	
-	private void log (String msg)
-	{
-		Log.d(TAG, msg);
-		mTextView.append(msg + '\n');
-		log.append(msg + '\n');
-	}
-	
-
-	@Override
-	public boolean onCreateOptionsMenu(Menu menu) {
-	    // Inflate menu resource file.
-	    getMenuInflater().inflate(R.menu.share_menu, menu);
-	
-	    // Locate MenuItem with ShareActionProvider
-	    MenuItem item = menu.findItem(R.id.menu_item_share);
-	
-	    return true;
-	}
-	
-	@Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-	    switch (item.getItemId()) {
-	
-	    case R.id.menu_item_share:
-	    	sendLog();
-	        return true;
-	
-	    default:
-	        return super.onOptionsItemSelected(item);
-	    }
-    }
-	
-	private void sendLog ()
-	{
-		int maxLength = 5000;
-		
-		String logShare = null;
-		
-		if (log.length() > maxLength)
-			logShare = log.substring(0,  maxLength);
-		else
-			logShare = log.toString();
-		
-		Intent sendIntent = new Intent();
-		sendIntent.setAction(Intent.ACTION_SEND);
-		sendIntent.putExtra(Intent.EXTRA_TEXT, logShare);
-		sendIntent.setType("text/plain");
-		startActivity(sendIntent);
-	}
-
-
-}
diff --git a/src/org/torproject/android/OrbotMainActivity.java b/src/org/torproject/android/OrbotMainActivity.java
new file mode 100644
index 0000000..b3583bc
--- /dev/null
+++ b/src/org/torproject/android/OrbotMainActivity.java
@@ -0,0 +1,1196 @@
+/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
+/* See LICENSE for licensing information */
+
+package org.torproject.android;
+
+import info.guardianproject.browser.Browser;
+
+import java.net.URLDecoder;
+import java.util.Locale;
+
+import org.torproject.android.service.TorService;
+import org.torproject.android.service.TorServiceConstants;
+import org.torproject.android.service.TorServiceUtils;
+import org.torproject.android.settings.SettingsPreferences;
+import org.torproject.android.ui.ChooseLocaleWizardActivity;
+import org.torproject.android.ui.ImageProgressView;
+import org.torproject.android.ui.Rotate3dAnimation;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.net.VpnService;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.GestureDetector.SimpleOnGestureListener;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+
+public class OrbotMainActivity extends Activity implements TorConstants, OnLongClickListener, OnTouchListener, OnSharedPreferenceChangeListener
+{
+	/* Useful UI bits */
+	private TextView lblStatus = null; //the main text display widget
+	private ImageProgressView imgStatus = null; //the main touchable image for activating Orbot
+
+	private MenuItem mItemOnOff = null;
+    private TextView downloadText = null;
+    private TextView uploadText = null;
+  
+    private Button mBtnBrowser = null;
+    private Button mBtnVPN = null;
+
+	/* Some tracking bits */
+	private int torStatus = TorServiceConstants.STATUS_OFF; //latest status reported from the tor service
+	
+	private SharedPreferences mPrefs = null;
+
+	private boolean autoStartFromIntent = false;
+	
+	private final static long INIT_DELAY = 100;
+
+    /** Called when the activity is first created. */
+	public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        mPrefs = TorServiceUtils.getSharedPrefs(getApplicationContext());        
+        mPrefs.registerOnSharedPreferenceChangeListener(this);
+           	
+        setLocale();
+        
+    	doLayout();
+
+    //	appConflictChecker ();
+    	
+
+  	  // Register to receive messages.
+  	  // We are registering an observer (mMessageReceiver) to receive Intents
+  	  // with actions named "custom-event-name".
+  	  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
+  	      new IntentFilter("status"));
+  	  
+		LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
+			      new IntentFilter("log"));
+
+		mHandler.postDelayed(new Runnable ()
+		{
+		
+			public void run ()
+			{
+				startService(TorServiceConstants.CMD_INIT);
+			}
+		},INIT_DELAY);
+		
+	}
+	
+	// Our handler for received Intents. This will be called whenever an Intent
+	// with an action named "custom-event-name" is broadcasted.
+	private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
+		
+		
+		
+	  @Override
+	  public void onReceive(Context context, Intent intent) {
+	    // Get extra data included in the Intent
+		  
+		if (intent.hasExtra("log"))
+		{
+			String log = intent.getStringExtra("log");
+			updateStatus(log);
+		}
+		else if (intent.hasExtra("up"))
+		{
+			long upload = intent.getLongExtra("up",0);
+			long download = intent.getLongExtra("down",0);
+			long written = intent.getLongExtra("written",0);
+			long read = intent.getLongExtra("read",0);
+			
+			Message msg = mHandler.obtainMessage(TorServiceConstants.MESSAGE_TRAFFIC_COUNT);
+			msg.getData().putLong("download", download);
+			msg.getData().putLong("upload", upload);
+			msg.getData().putLong("readTotal", read);
+			msg.getData().putLong("writeTotal", written);
+			mHandler.sendMessage(msg);
+			
+		}
+		else if (intent.hasExtra("status"))
+		{
+			torStatus = intent.getIntExtra("status", TorServiceConstants.STATUS_OFF);
+			updateStatus("");
+		}
+		
+	  }
+	};
+
+	private void startService (String action)
+	{
+		
+		Intent torService = new Intent(this, TorService.class);    
+		torService.setAction(action);
+		startService(torService);
+		
+	}
+	
+	private void stopService ()
+	{
+		
+		Intent torService = new Intent(this, TorService.class);
+		stopService(torService);
+		
+	}
+	
+	private DrawerLayout mDrawer;
+	private ActionBarDrawerToggle mDrawerToggle;
+	private Toolbar mToolbar;
+	
+	private void doLayout ()
+	{
+    	setContentView(R.layout.layout_main);
+    	
+        mToolbar = (Toolbar) findViewById(R.id.toolbar);
+        mToolbar.inflateMenu(R.menu.orbot_main);
+        mToolbar.setTitle(R.string.app_name);
+
+    	  mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+          mDrawerToggle = new ActionBarDrawerToggle(
+              this,  mDrawer, mToolbar,
+              android.R.string.ok, android.R.string.cancel
+          );
+          
+          mDrawer.setDrawerListener(mDrawerToggle);
+          mDrawerToggle.setDrawerIndicatorEnabled(true);
+          mDrawerToggle.syncState();
+          mDrawerToggle.setToolbarNavigationClickListener(new OnClickListener ()
+          {
+
+              @Override
+              public void onClick(View v) {
+
+                 
+
+              }
+
+
+          });
+
+    	
+    	lblStatus = (TextView)findViewById(R.id.lblStatus);
+    	imgStatus = (ImageProgressView)findViewById(R.id.imgStatus);
+    	imgStatus.setOnLongClickListener(this);
+    	
+    	downloadText = (TextView)findViewById(R.id.trafficDown);
+        uploadText = (TextView)findViewById(R.id.trafficUp);
+        
+		downloadText.setText(formatCount(0) + " / " + formatTotal(0));
+		uploadText.setText(formatCount(0) + " / " + formatTotal(0));
+	
+        // Gesture detection
+		mGestureDetector = new GestureDetector(this, new MyGestureDetector());
+		
+		mBtnBrowser = (Button)findViewById(R.id.btnBrowser);
+		mBtnBrowser.setOnClickListener(new View.OnClickListener ()
+		{
+
+			@Override
+			public void onClick(View v) {
+				doTorCheck();
+				
+			}
+
+			
+		});
+		
+		mBtnVPN = (Button)findViewById(R.id.btnVPN);
+		mBtnVPN.setOnClickListener(new View.OnClickListener ()
+		{
+
+			@Override
+			public void onClick(View v) {
+
+				startVpnService();
+				
+			}
+
+			
+		});
+		
+
+    }
+	
+	GestureDetector mGestureDetector;
+    
+
+	@Override
+	public boolean onTouch(View v, MotionEvent event) {
+	    return mGestureDetector.onTouchEvent(event);
+
+	}
+   	
+   /*
+    * Create the UI Options Menu (non-Javadoc)
+    * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
+    */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.orbot_main, menu);
+       
+        mItemOnOff = menu.getItem(0);
+        
+        return true;
+    }
+    
+    /**
+    private void appConflictChecker ()
+    {
+    	SharedPreferences sprefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+    	
+    	boolean showAppConflict = true;//sprefs.getBoolean("pref_show_conflict",true);
+    	
+    	String[] badApps = {"com.sec.msc.nts.android.proxy:com.sec.msc.nts.android.proxy","com.sec.pcw:Samsung Link"};
+    	
+    	for (String badApp : badApps)
+    	{
+    		String[] badAppParts = badApp.split(":");
+    		
+    		if (appInstalledOrNot(badAppParts[0]))
+    		{
+    			String msg = getString(R.string.please_disable_this_app_in_android_settings_apps_if_you_are_having_problems_with_orbot_) + badAppParts[1];
+    			
+    			if (showAppConflict)
+    				showAlert(getString(R.string.app_conflict),msg,true);
+	    	
+	    	//	appendLogTextAndScroll(msg);
+    		}
+    	}
+    	
+    	sprefs.edit().putBoolean("pref_show_conflict", false).commit();
+	
+    }*/
+    
+    
+    
+
+    private void showAbout ()
+        {
+                
+	        LayoutInflater li = LayoutInflater.from(this);
+	        View view = li.inflate(R.layout.layout_about, null); 
+	        
+	        String version = "";
+	        
+	        try {
+	        	version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName + " (Tor " + TorServiceConstants.BINARY_TOR_VERSION + ")";
+	        } catch (NameNotFoundException e) {
+	        	version = "Version Not Found";
+	        }
+	        
+	        TextView versionName = (TextView)view.findViewById(R.id.versionName);
+	        versionName.setText(version);    
+	        
+	                new AlertDialog.Builder(this)
+	        .setTitle(getString(R.string.button_about))
+	        .setView(view)
+	        .show();
+        }
+    
+    	@Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+                
+                super.onOptionsItemSelected(item);
+                
+                if (item.getItemId() == R.id.menu_start)
+                {
+                        
+                        try
+                        {
+                                
+                                if (torStatus == TorServiceConstants.STATUS_OFF)
+                                {
+                                    if (mItemOnOff != null)
+                                            mItemOnOff.setTitle(R.string.menu_stop);
+                                        startTor();
+                                        
+                                }
+                                else
+                                {
+                                    if (mItemOnOff != null)
+                                            mItemOnOff.setTitle(R.string.menu_start);
+                                    
+                                        stopTor();
+                                        stopService ();
+                                        
+                                }
+                                
+                        }
+                        catch (RemoteException re)
+                        {
+                                Log.w(TAG, "Unable to start/top Tor from menu UI", re);
+                        }
+                }
+                else if (item.getItemId() == R.id.menu_settings)
+                {
+                        showSettings();
+                }
+                else if (item.getItemId() == R.id.menu_wizard)
+                {
+            		startActivity(new Intent(this, ChooseLocaleWizardActivity.class));
+
+                }
+                else if (item.getItemId() == R.id.menu_exit)
+                {
+                        //exit app
+                        doExit();
+                        
+                        
+                }
+                else if (item.getItemId() == R.id.menu_about)
+                {
+                        showAbout();
+                        
+                        
+                }
+
+                /**
+                else if (item.getItemId() == R.id.menu_verify)
+                {
+                        doTorCheck();
+                }
+                else if (item.getItemId() == R.id.menu_vpn)
+                {
+                		startVpnService();
+                }*/
+                
+                return true;
+        }
+      
+        /**
+        * 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();
+                        stopService ();
+                        
+                        
+                } catch (RemoteException e) {
+                        Log.w(TAG, e);
+                }
+                
+                //Kill all the wizard activities
+                setResult(RESULT_CLOSE_ALL);
+                finish();
+                
+        }
+        
+    /* (non-Javadoc)
+	 * @see android.app.Activity#onPause()
+	 */
+	protected void onPause() {
+		try
+		{
+			super.onPause();
+	
+			if (aDialog != null)
+				aDialog.dismiss();
+		}
+		catch (IllegalStateException ise)
+		{
+			//can happen on exit/shutdown
+		}
+	}
+	
+	private void doTorCheck ()
+	{
+		
+		openBrowser(URL_TOR_CHECK);
+		
+
+	}
+	
+	private void enableHiddenServicePort (int hsPort)
+	{
+		
+		Editor pEdit = mPrefs.edit();
+		
+		String hsPortString = mPrefs.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 = mPrefs.getString("pref_hs_hostname","");
+
+		while (onionHostname.length() == 0)
+		{
+			//we need to stop and start Tor
+			try {
+				stopTor();
+				
+				Thread.sleep(3000); //wait three seconds
+				
+				startTor();
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			 
+			 onionHostname = mPrefs.getString("pref_hs_hostname","");
+		}
+		
+		Intent nResult = new Intent();
+		nResult.putExtra("hs_host", onionHostname);
+		setResult(RESULT_OK, nResult);
+	
+	}
+
+
+	private synchronized void handleIntents ()
+	{
+		if (getIntent() == null)
+			return;
+		
+	    // Get intent, action and MIME type
+	    Intent intent = getIntent();
+	    String action = intent.getAction();
+	    String type = intent.getType();
+		
+		if (action == null)
+			return;
+		
+		if (action.equals("org.torproject.android.REQUEST_HS_PORT"))
+		{
+			
+			DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
+			    
+			    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 = getString(R.string.hidden_service_request, hsPort);
+			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"))
+		{
+			autoStartFromIntent = true;
+				
+				try {
+					startTor();
+
+					Intent nResult = new Intent();
+					
+					//nResult.putExtra("socks", ); //TODO respond with socks, transport, dns, etc
+					
+					setResult(RESULT_OK,nResult);
+					
+				} catch (RemoteException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			
+		}
+		else if (action.equals(Intent.ACTION_VIEW))
+		{
+			String urlString = intent.getDataString();
+			
+			if (urlString != null)
+			{
+				
+				if (urlString.toLowerCase().startsWith("bridge://"))
+
+				{
+					String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece
+					newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here
+		
+					showAlert("Bridges Updated","Restart Orbot to use this bridge: " + newBridgeValue,false);	
+					
+					String bridges = mPrefs.getString(TorConstants.PREF_BRIDGES_LIST, null);
+					
+					Editor pEdit = mPrefs.edit();
+					
+					if (bridges != null && bridges.trim().length() > 0)
+					{
+						if (bridges.indexOf('\n')!=-1)
+							bridges += '\n' + newBridgeValue;
+						else
+							bridges += ',' + newBridgeValue;
+					}
+					else
+						bridges = newBridgeValue;
+					
+					pEdit.putString(TorConstants.PREF_BRIDGES_LIST,bridges); //set the string to a preference
+					pEdit.putBoolean(TorConstants.PREF_BRIDGES_ENABLED,true);
+				
+					pEdit.commit();
+					
+					setResult(RESULT_OK);
+				}
+			}
+		}
+		else
+		{
+		
+			showWizard = mPrefs.getBoolean("show_wizard",showWizard);
+			
+			if (showWizard)
+			{
+				Editor pEdit = mPrefs.edit();
+				pEdit.putBoolean("show_wizard",false);
+				pEdit.commit();				
+				showWizard = false;
+
+				startActivity(new Intent(this, ChooseLocaleWizardActivity.class));
+
+			}
+			
+		}
+		
+		setIntent(null);
+		
+		updateStatus ("");
+		
+	}
+
+	private boolean showWizard = true;
+	
+	
+	@Override
+	public void onConfigurationChanged(Configuration newConfig) {
+		super.onConfigurationChanged(newConfig);
+		
+		doLayout();
+		updateStatus("");
+	}
+
+
+	/*
+	 * Launch the system activity for Uri viewing with the provided url
+	 */
+	private void openBrowser(final String browserLaunchUrl)
+	{
+		//startIntent("info.guardianproject.browser.Browser",Intent.ACTION_VIEW,Uri.parse(browserLaunchUrl));						
+
+		Intent intentBrowser = new Intent(this, Browser.class);
+		intentBrowser.setAction(Intent.ACTION_VIEW);
+		intentBrowser.setData(Uri.parse(browserLaunchUrl));
+		startActivity(intentBrowser);
+		
+		/**
+		boolean isOrwebInstalled = appInstalledOrNot("info.guardianproject.browser");
+		boolean isTransProxy =  mPrefs.getBoolean("pref_transparent", false);
+		
+		if (isOrwebInstalled)
+		{
+		}
+		else if (isTransProxy)
+		{
+			Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
+			intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
+			startActivity(intent);
+		}
+		else
+		{
+			AlertDialog aDialog = new AlertDialog.Builder(Orbot.this)
+              .setIcon(R.drawable.onion32)
+		      .setTitle(R.string.install_apps_)
+		      .setMessage(R.string.it_doesn_t_seem_like_you_have_orweb_installed_want_help_with_that_or_should_we_just_open_the_browser_)
+		      .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener ()
+		      {
+
+				@Override
+				public void onClick(DialogInterface dialog, int which) {
+
+					//prompt to install Orweb
+					Intent intent = new Intent(Orbot.this,TipsAndTricks.class);
+					startActivity(intent);
+					
+				}
+		    	  
+		      })
+		      .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener ()
+		      {
+
+				@Override
+				public void onClick(DialogInterface dialog, int which) {
+					Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl));
+					intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
+					startActivity(intent);
+					
+				}
+		    	  
+		      })
+		      .show();
+			  
+		}*/
+		
+	}
+	
+	private void startIntent (String pkg, String action, Uri data)
+	{
+		Intent i;
+		PackageManager manager = getPackageManager();
+		try {
+		    i = manager.getLaunchIntentForPackage(pkg);
+		    if (i == null)
+		        throw new PackageManager.NameNotFoundException();		    
+		    i.setAction(action);
+		    i.setData(data);
+		    startActivity(i);
+		} catch (PackageManager.NameNotFoundException e) {
+
+		}
+	}
+	
+	private boolean appInstalledOrNot(String uri)
+    {
+        PackageManager pm = getPackageManager();
+        try
+        {
+               PackageInfo pi = pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);               
+               return pi.applicationInfo.enabled;
+        }
+        catch (PackageManager.NameNotFoundException e)
+        {
+              return false;
+        }
+}
+	
+    /*
+     * Load the basic settings application to display torrc
+     */
+    private void showSettings ()
+    {
+            
+            startActivityForResult(new Intent(this, SettingsPreferences.class), 1);
+    }
+    
+    
+    @Override
+	protected void onActivityResult(int request, int response, Intent data) {
+		super.onActivityResult(request, response, data);
+		
+		
+		if (request == 1 && response == RESULT_OK)
+		{
+			if (data != null && data.getBooleanExtra("transproxywipe", false))
+			{
+					
+					boolean result = flushTransProxy();
+					
+					if (result)
+					{
+
+			    		Toast.makeText(this, R.string.transparent_proxy_rules_flushed_, Toast.LENGTH_SHORT).show();
+				 		
+					}
+					else
+					{
+
+			    		Toast.makeText(this, R.string.you_do_not_have_root_access_enabled, Toast.LENGTH_SHORT).show();
+				 		
+					}
+				
+			}
+			else if (torStatus == TorServiceConstants.STATUS_ON)
+			{
+				updateSettings();
+	    		Toast.makeText(this, R.string.you_may_need_to_stop_and_start_orbot_for_settings_change_to_be_enabled_, Toast.LENGTH_SHORT).show();
+
+			}
+		}
+		else if (request == REQUEST_VPN && response == RESULT_OK)
+		{
+			startService(TorServiceConstants.CMD_VPN);
+		}
+		
+	}
+    
+    private final static int REQUEST_VPN = 8888;
+    
+    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+	public void startVpnService ()
+    {
+    	 Intent intent = VpnService.prepare(this);
+	        if (intent != null) {
+	            startActivityForResult(intent,REQUEST_VPN);
+	        } 
+	        else
+	        {
+				startService(TorServiceConstants.CMD_VPN);
+
+	        }
+    }
+
+    private boolean flushTransProxy ()
+    {
+    	startService(TorServiceConstants.CMD_FLUSH);
+    	return true;
+    }
+    
+    private boolean updateSettings ()
+    {
+    	//todo send service command
+    	startService(TorServiceConstants.CMD_UPDATE);
+    	return true;
+    }
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+
+		mHandler.postDelayed(new Runnable ()
+		{
+			public void run ()
+			{
+
+				setLocale();
+		
+				handleIntents();
+
+			}
+		}
+		, 500);
+		
+		
+	}
+
+	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(OrbotMainActivity.this)
+                     .setIcon(R.drawable.onion32)
+             .setTitle(title)
+             .setMessage(msg)
+             .setPositiveButton(android.R.string.ok, null)
+             .show();
+             }
+             else
+             {
+                     aDialog = new AlertDialog.Builder(OrbotMainActivity.this)
+                     .setIcon(R.drawable.onion32)
+             .setTitle(title)
+             .setMessage(msg)
+             .show();
+             }
+    
+             aDialog.setCanceledOnTouchOutside(true);
+    }
+    
+	private void updateStatus (String torServiceMsg)
+    {
+        
+            //now update the layout_main UI based on the status
+            if (imgStatus != null)
+            {
+                    
+                    if (torStatus == TorServiceConstants.STATUS_ON)
+                    {
+                        	
+                            imgStatus.setImageResource(R.drawable.toron);
+                    		
+                            mBtnBrowser.setEnabled(true);
+                            mBtnVPN.setEnabled(true);
+                            
+                            lblStatus.setText("");
+
+                            if (mItemOnOff != null)
+                                    mItemOnOff.setTitle(R.string.menu_stop);
+                            
+                        
+                            if (torServiceMsg != null && torServiceMsg.length() > 0)
+                            {
+                            //	appendLogTextAndScroll(torServiceMsg);
+                            }
+                            
+                            boolean showFirstTime = mPrefs.getBoolean("connect_first_time",true);
+                            
+                            if (showFirstTime)
+                            {
+                            
+                                    Editor pEdit = mPrefs.edit();
+                                    
+                                    pEdit.putBoolean("connect_first_time",false);
+                                    
+                                    pEdit.commit();
+                                    
+                                    showAlert(getString(R.string.status_activated),getString(R.string.connect_first_time),true);
+                                    
+                            }
+                            
+                            
+                            if (autoStartFromIntent)
+                            {
+                            	setResult(RESULT_OK);
+                            	finish();
+                            }
+
+                    }
+                    else if (torStatus == TorServiceConstants.STATUS_CONNECTING)
+                    {
+                    	
+                        imgStatus.setImageResource(R.drawable.torstarting);
+                
+                        if (mItemOnOff != null)
+                                mItemOnOff.setTitle(R.string.menu_stop);
+                	
+                        if (lblStatus != null && torServiceMsg != null)
+                        	if (torServiceMsg.indexOf('%')!=-1)
+                        		lblStatus.setText(torServiceMsg);
+                        	
+                        
+                        //appendLogTextAndScroll(torServiceMsg);
+                        
+                                    
+                    }
+                    else if (torStatus == TorServiceConstants.STATUS_OFF)
+                    {
+                        imgStatus.setImageResource(R.drawable.toroff);
+                        lblStatus.setText("");
+                        //lblStatus.setText(getString(R.string.status_disabled) + "\n" + getString(R.string.press_to_start));
+                        
+                        if (mItemOnOff != null)
+                                mItemOnOff.setTitle(R.string.menu_start);
+
+                        mBtnBrowser.setEnabled(false);
+                        mBtnVPN.setEnabled(false);
+                        
+                    }
+            }
+                
+           
+    }
+		
+         
+  
+  // 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
+    {
+            
+
+		startService (TorServiceConstants.CMD_START);
+		torStatus = TorServiceConstants.STATUS_CONNECTING;
+				
+//		mTxtOrbotLog.setText("");
+
+        //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);
+        msg.getData().putString(HANDLER_TOR_MSG, getString(R.string.status_starting_up));
+        mHandler.sendMessage(msg);
+      
+        
+    	
+    }
+    
+    //now we stop Tor! amazing!
+    private void stopTor () throws RemoteException
+    {
+    	
+    	startService (TorServiceConstants.CMD_STOP);
+		torStatus = TorServiceConstants.STATUS_OFF;
+    	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 (torStatus == TorServiceConstants.STATUS_OFF)
+                {
+
+                        startTor();
+                }
+                else
+                {
+                        
+                        stopTor();
+                        stopService ();
+                        
+                }
+                
+                return true;
+                    
+            }
+            catch (Exception e)
+            {
+                    Log.d(TAG,"error onclick",e);
+            }
+
+            return false;
+                    
+        }
+
+    	
+        
+   
+
+// 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() {
+    	
+    	private String lastServiceMsg = null;
+    	
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case TorServiceConstants.STATUS_MSG:
+                case TorServiceConstants.LOG_MSG:
+
+                        String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG);
+                        
+                        if (lastServiceMsg == null || !lastServiceMsg.equals(torServiceMsg))
+                        {
+                        	updateStatus(torServiceMsg);
+                        
+                        	lastServiceMsg = torServiceMsg;
+                        }
+                        
+                    break;
+                case TorServiceConstants.ENABLE_TOR_MSG:
+                        
+                        
+                        updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
+                        
+                        break;
+                case TorServiceConstants.DISABLE_TOR_MSG:
+                	
+                	updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG));
+                	
+                	break;
+                	
+
+            	case TorServiceConstants.MESSAGE_TRAFFIC_COUNT :
+                    
+            		Bundle data = msg.getData();
+            		DataCount datacount =  new DataCount(data.getLong("upload"),data.getLong("download"));     
+            		
+            		long totalRead = data.getLong("readTotal");
+            		long totalWrite = data.getLong("writeTotal");
+            	
+        			downloadText.setText(formatCount(datacount.Download) + " / " + formatTotal(totalRead));
+            		uploadText.setText(formatCount(datacount.Upload) + " / " + formatTotal(totalWrite));
+            
+            		if (torStatus != TorServiceConstants.STATUS_ON)
+            		{
+            			updateStatus("");
+            		}
+                		
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+        
+        
+        
+    };
+
+    
+    /**
+     * 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 void setLocale ()
+    {
+    	
+
+        Configuration config = getResources().getConfiguration();
+        String lang = mPrefs.getString(PREF_DEFAULT_LOCALE, "");
+        
+        if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang))
+        {
+        	Locale locale = new Locale(lang);
+            Locale.setDefault(locale);
+            config.locale = locale;
+            getResources().updateConfiguration(config, getResources().getDisplayMetrics());
+        }
+    }
+
+   	@Override
+	protected void onDestroy() {
+		super.onDestroy();
+		  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
+
+	}
+
+	public class DataCount {
+   		// data uploaded
+   		public long Upload;
+   		// data downloaded
+   		public long Download;
+   		
+   		DataCount(long Upload, long Download){
+   			this.Upload = Upload;
+   			this.Download = Download;
+   		}
+   	}
+   	
+   	private String formatCount(long count) {
+		// Converts the supplied argument into a string.
+		// Under 2Mb, returns "xxx.xKb"
+		// Over 2Mb, returns "xxx.xxMb"
+		if (count < 1e6)
+			return ((float)((int)(count*10/1024))/10 + "kbps");
+		return ((float)((int)(count*100/1024/1024))/100 + "mbps");
+		
+   		//return count+" kB";
+	}
+   	
+   	private String formatTotal(long count) {
+		// Converts the supplied argument into a string.
+		// Under 2Mb, returns "xxx.xKb"
+		// Over 2Mb, returns "xxx.xxMb"
+		if (count < 1e6)
+			return ((float)((int)(count*10/1024))/10 + "KB");
+		return ((float)((int)(count*100/1024/1024))/100 + "MB");
+		
+   		//return count+" kB";
+	}
+
+	@Override
+	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+			String key) {
+	
+		
+	}
+	
+	  private static final float ROTATE_FROM = 0.0f;
+	    private static final float ROTATE_TO = 360.0f*4f;// 3.141592654f * 32.0f;
+
+	public void spinOrbot (float direction)
+	{
+			startService (TorServiceConstants.CMD_NEWNYM);
+		
+		
+			Toast.makeText(this, R.string.newnym, Toast.LENGTH_SHORT).show();
+			
+		//	Rotate3dAnimation rotation = new Rotate3dAnimation(ROTATE_FROM, ROTATE_TO*direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+			 Rotate3dAnimation rotation = new Rotate3dAnimation(ROTATE_FROM, ROTATE_TO*direction, imgStatus.getWidth()/2f,imgStatus.getWidth()/2f,20f,false);
+			 rotation.setFillAfter(true);
+			  rotation.setInterpolator(new AccelerateInterpolator());
+			  rotation.setDuration((long) 2*1000);
+			  rotation.setRepeatCount(0);
+			  imgStatus.startAnimation(rotation);
+			  
+		
+	}
+	
+	 class MyGestureDetector extends SimpleOnGestureListener {
+	        @Override
+	        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+	            try {	            	
+	            	if (torStatus == TorServiceConstants.STATUS_ON)
+	            	{
+	            		float direction = 1f;
+	            		if (velocityX < 0)
+	            			direction = -1f;
+	            		spinOrbot (direction);
+	            	}
+	            } catch (Exception e) {
+	                // nothing
+	            }
+	            return false;
+	        }
+
+	    }
+
+
+}
diff --git a/src/org/torproject/android/RandomColorCircleView.java b/src/org/torproject/android/RandomColorCircleView.java
deleted file mode 100644
index 6e9a839..0000000
--- a/src/org/torproject/android/RandomColorCircleView.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.torproject.android;
-
-import java.util.Random;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-public class RandomColorCircleView extends View
-{
-
-	  private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
-	  private float initX, initY, radius;
-	  private boolean drawing = false;
-
-		Random rand = new Random();
-		
-
-	public RandomColorCircleView(Context context) {
-	 super(context);
-	 // TODO Auto-generated constructor stub
-	 init();
-	 
-	}
-
-	public RandomColorCircleView(Context context, AttributeSet attrs) {
-	 super(context, attrs);
-	 init();
-	}
-
-	public RandomColorCircleView(Context context, AttributeSet attrs, int defStyle) {
-	 super(context, attrs, defStyle);
-	 
-	 init();
-	}
-
-	private void init(){
-	 paint.setStyle(Paint.Style.STROKE);
-	 paint.setColor(Color.WHITE);
-	 paint.setAntiAlias(false);
-	 paint.setStrokeWidth(6);
-
-	}
-
-	@Override
-	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-	   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-	   
-	   setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
-	   MeasureSpec.getSize(heightMeasureSpec));
-	 
-	}
-
-	int a1 = 30;
-	int a2 = 255;
-	
-	@Override
-	protected void onDraw(Canvas canvas) {
-
-		super.onDraw(canvas);
-		
-		for (int i = 0; i < 20; i++)
-		{
-			float r = rand.nextFloat()*255f;
-			float g = rand.nextFloat()*255f;
-			float b = rand.nextFloat()*255f;
-	
-			paint.setARGB(a1,(int)r,(int)g,(int)b);
-		
-			float x = rand.nextFloat() * getWidth();
-			float y = rand.nextFloat() * getHeight();
-
-			float w = rand.nextFloat() * getWidth();
-			float h = rand.nextFloat() * getHeight();
-			
-			canvas.drawCircle(x, y, w/2, paint);
-			
-			
-		}
-		
-	}
-	
-	int a1mod = 1;
-	
-	public void updateAlpha ()
-	{
-		a1 += a1mod;
-		
-		if (a1 > 255 || a1 < 0)
-			a1mod *= -1;
-		
-
-	}
-
-	/*
-	@Override
-	public boolean onTouchEvent(MotionEvent event) {
-	 
-
-	 int action = event.getAction();
-	 if (action==MotionEvent.ACTION_MOVE){
-	  float x = event.getX();
-	  float y = event.getY();
-
-	 // radius = (float) Math.sqrt(Math.pow(x-initX, 2) + Math.pow(y-initY, 2));
-	  //updateAlpha();
-	  
-	     a1 = (int)(255*(y/((float)getHeight())));
-	  
-	 }
-	 else if (action==MotionEvent.ACTION_DOWN){
-	  initX = event.getX();
-	  initY = event.getY();
-	  radius = 1;
-	  drawing = true;
-	 
-	  
-	 }
-	 else if (action==MotionEvent.ACTION_UP){
-	  drawing = false;
-	 
-	  
-	 }
-	 
-	 return true;
-	 
-	}*/
-
-}
\ No newline at end of file
diff --git a/src/org/torproject/android/Rotate3dAnimation.java b/src/org/torproject/android/Rotate3dAnimation.java
deleted file mode 100644
index 10bb52e..0000000
--- a/src/org/torproject/android/Rotate3dAnimation.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.torproject.android;
-
-import android.graphics.Camera;
-import android.graphics.Matrix;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-
-/**
- * An animation that rotates the view on the Y axis between two specified angles.
- * This animation also adds a translation on the Z axis (depth) to improve the effect.
- */
-public class Rotate3dAnimation extends Animation {
-    private final float mFromDegrees;
-    private final float mToDegrees;
-    private final float mCenterX;
-    private final float mCenterY;
-    private final float mDepthZ;
-    private final boolean mReverse;
-    private Camera mCamera;
-
-    /**
-     * Creates a new 3D rotation on the Y axis. The rotation is defined by its
-     * start angle and its end angle. Both angles are in degrees. The rotation
-     * is performed around a center point on the 2D space, definied by a pair
-     * of X and Y coordinates, called centerX and centerY. When the animation
-     * starts, a translation on the Z axis (depth) is performed. The length
-     * of the translation can be specified, as well as whether the translation
-     * should be reversed in time.
-     *
-     * @param fromDegrees the start angle of the 3D rotation
-     * @param toDegrees the end angle of the 3D rotation
-     * @param centerX the X center of the 3D rotation
-     * @param centerY the Y center of the 3D rotation
-     * @param reverse true if the translation should be reversed, false otherwise
-     */
-    public Rotate3dAnimation(float fromDegrees, float toDegrees,
-            float centerX, float centerY, float depthZ, boolean reverse) {
-        mFromDegrees = fromDegrees;
-        mToDegrees = toDegrees;
-        mCenterX = centerX;
-        mCenterY = centerY;
-        mDepthZ = depthZ;
-        mReverse = reverse;
-    }
-
-    @Override
-    public void initialize(int width, int height, int parentWidth, int parentHeight) {
-        super.initialize(width, height, parentWidth, parentHeight);
-        mCamera = new Camera();
-    }
-
-    @Override
-    protected void applyTransformation(float interpolatedTime, Transformation t) {
-        final float fromDegrees = mFromDegrees;
-        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
-
-        final float centerX = mCenterX;
-        final float centerY = mCenterY;
-        final Camera camera = mCamera;
-
-        final Matrix matrix = t.getMatrix();
-
-        camera.save();
-        if (mReverse) {
-            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
-        } else {
-            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
-        }
-        camera.rotateY(degrees);
-        camera.getMatrix(matrix);
-        camera.restore();
-
-        matrix.preTranslate(-centerX, -centerY);
-        matrix.postTranslate(centerX, centerY);
-    }
-}
diff --git a/src/org/torproject/android/Utils.java b/src/org/torproject/android/Utils.java
deleted file mode 100644
index f5f2ea5..0000000
--- a/src/org/torproject/android/Utils.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
-/* See LICENSE for licensing information */
-
-
-package org.torproject.android;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-public class Utils {
-
-
-	 public static String readString (InputStream stream)
-	    {
-	    	String line = null;
-	    
-	    	StringBuffer out = new StringBuffer();
-	    	
-	    	try {
-		    	BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-
-				while ((line = reader.readLine()) != null)
-				{
-					out.append(line);
-					out.append('\n');
-					
-				}
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			
-			return out.toString();
-	    	
-	    }
-	/*
-	 * Load the log file text
-	 */
-	 public static String loadTextFile (String path)
-	    {
-	    	String line = null;
-	    
-	    	StringBuffer out = new StringBuffer();
-	    	
-	    	try {
-		    	BufferedReader reader = new BufferedReader((new FileReader(new File(path))));
-
-				while ((line = reader.readLine()) != null)
-				{
-					out.append(line);
-					out.append('\n');
-					
-				}
-				
-				reader.close();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			
-			return out.toString();
-	    	
-	    }
-	 
-
-		/*
-		 * Load the log file text
-		 */
-		 public static boolean saveTextFile (String path, String contents)
-		    {
-			 	
-		    	try {
-		    		
-		    		 FileWriter writer = new FileWriter( path, false );
-                     writer.write( contents );
-                     
-                     writer.close();
-
-                     
-		    		
-		    		return true;
-			    	
-				} catch (IOException e) {
-				//	Log.d(TAG, "error writing file: " + path, e);
-						e.printStackTrace();
-					return false;
-				}
-				
-				
-		    	
-		    }
-	
-
-
-}
diff --git a/src/org/torproject/android/pluto/PlutoFactory.java b/src/org/torproject/android/pluto/PlutoFactory.java
new file mode 100644
index 0000000..094bc5e
--- /dev/null
+++ b/src/org/torproject/android/pluto/PlutoFactory.java
@@ -0,0 +1,14 @@
+package org.torproject.android.pluto;
+
+public class PlutoFactory {
+
+	
+	//load pluto.properties from res/raw/pluto.properties
+	
+	//ensure the PT binaries are installed and exe
+	
+	//expose the installed PT's via a simple factory instance interface .getPlutoInstance("obfs3")
+	
+	//return instance with interface for getting exe path, directly starting/stopping, monitoring status, etc
+	
+}
diff --git a/src/org/torproject/android/pluto/PlutoInstaller.java b/src/org/torproject/android/pluto/PlutoInstaller.java
new file mode 100644
index 0000000..4c312c4
--- /dev/null
+++ b/src/org/torproject/android/pluto/PlutoInstaller.java
@@ -0,0 +1,194 @@
+/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
+/* See LICENSE for licensing information */
+
+package org.torproject.android.pluto;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringBufferInputStream;
+import java.util.ArrayList;
+import java.util.concurrent.TimeoutException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.sufficientlysecure.rootcommands.Shell;
+import org.sufficientlysecure.rootcommands.command.SimpleCommand;
+import org.torproject.android.R;
+import org.torproject.android.TorConstants;
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+
+public class PlutoInstaller {
+
+	
+	private File installFolder;
+	private Context context;
+
+	private final static int FILE_WRITE_BUFFER_SIZE = 1024;
+	private final static String CHMOD_EXE_VALUE = "770";
+	private final static String COMMAND_RM_FORCE = "rm -f ";
+	
+	public PlutoInstaller (Context context, File installFolder)
+	{
+		this.installFolder = installFolder;	
+		this.context = context;
+	}
+	
+	public boolean installBinaries () throws Exception
+	{
+		
+		InputStream is;
+        File outFile;
+        
+        installFolder.mkdirs();
+        
+        Shell shell = Shell.startShell(new ArrayList<String>(),installFolder.getAbsolutePath());
+        
+        String ptAsset = null;
+        
+		is = context.getResources().openRawResource(R.raw.obfsclient);
+		
+		outFile = new File(installFolder, ptAsset);
+		shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish();
+		streamToFile(is,outFile, false, true);
+		
+		enableBinExec (outFile);
+		
+		return true;
+	}
+	
+	private boolean enableBinExec (File fileBin) throws Exception
+    {
+  
+    	if (!fileBin.canExecute())
+    	{
+			Shell shell = Shell.startShell();
+			shell.add(new SimpleCommand("chmod " + CHMOD_EXE_VALUE + ' ' + fileBin.getCanonicalPath())).waitForFinish();
+			
+			File fileTest = new File(fileBin.getCanonicalPath());
+			shell.close();
+    	}
+    	
+		return fileBin.canExecute();
+    }
+	
+	
+	/*
+	 * Write the inputstream contents to the file
+	 */
+    public static boolean streamToFile(InputStream stm, File outFile, boolean append, boolean zip) throws IOException
+
+    {
+        byte[] buffer = new byte[FILE_WRITE_BUFFER_SIZE];
+
+        int bytecount;
+
+    	OutputStream stmOut = new FileOutputStream(outFile.getAbsolutePath(), append);
+    	ZipInputStream zis = null;
+    	
+    	if (zip)
+    	{
+    		zis = new ZipInputStream(stm);    		
+    		ZipEntry ze = zis.getNextEntry();
+    		stm = zis;
+    		
+    	}
+    	
+        while ((bytecount = stm.read(buffer)) > 0)
+        {
+
+            stmOut.write(buffer, 0, bytecount);
+
+        }
+
+        stmOut.close();
+        stm.close();
+        
+        if (zis != null)
+        	zis.close();
+        
+        
+        return true;
+
+    }
+	
+    //copy the file from inputstream to File output - alternative impl
+	public static void copyFile (InputStream is, File outputFile)
+	{
+		
+		try {
+			outputFile.createNewFile();
+			DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFile));
+			DataInputStream in = new DataInputStream(is);
+			
+			int b = -1;
+			byte[] data = new byte[1024];
+			
+			while ((b = in.read(data)) != -1) {
+				out.write(data);
+			}
+			
+			if (b == -1); //rejoice
+			
+			//
+			out.flush();
+			out.close();
+			in.close();
+			// chmod?
+			
+			
+			
+		} catch (IOException ex) {
+			Log.e(TorConstants.TAG, "error copying binary", ex);
+		}
+
+	}
+	
+	
+
+   
+	/**
+	 * Copies a raw resource file, given its ID to the given location
+	 * @param ctx context
+	 * @param resid resource id
+	 * @param file destination file
+	 * @param mode file permissions (E.g.: "755")
+	 * @throws IOException on error
+	 * @throws InterruptedException when interrupted
+	 */
+	public static void copyRawFile(Context ctx, int resid, File file, String mode, boolean isZipd) throws IOException, InterruptedException
+	{
+		final String abspath = file.getAbsolutePath();
+		// Write the iptables binary
+		final FileOutputStream out = new FileOutputStream(file);
+		InputStream is = ctx.getResources().openRawResource(resid);
+		
+		if (isZipd)
+    	{
+    		ZipInputStream zis = new ZipInputStream(is);    		
+    		ZipEntry ze = zis.getNextEntry();
+    		is = zis;
+    	}
+		
+		byte buf[] = new byte[1024];
+		int len;
+		while ((len = is.read(buf)) > 0) {
+			out.write(buf, 0, len);
+		}
+		out.close();
+		is.close();
+		// Change the permissions
+		Runtime.getRuntime().exec("chmod "+mode+" "+abspath).waitFor();
+	}
+   
+	
+
+}
diff --git a/src/org/torproject/android/pluto/PlutoInstance.java b/src/org/torproject/android/pluto/PlutoInstance.java
new file mode 100644
index 0000000..4585083
--- /dev/null
+++ b/src/org/torproject/android/pluto/PlutoInstance.java
@@ -0,0 +1,9 @@
+package org.torproject.android.pluto;
+
+import java.io.File;
+
+public class PlutoInstance {
+
+	public String name;
+	public File fileBinary;
+}
diff --git a/src/org/torproject/android/service/HiddenServiceManager.java b/src/org/torproject/android/service/HiddenServiceManager.java
new file mode 100644
index 0000000..6b0d32d
--- /dev/null
+++ b/src/org/torproject/android/service/HiddenServiceManager.java
@@ -0,0 +1,25 @@
+package org.torproject.android.service;
+
+
+//list view with add/remove hidden services - user is prompted for port
+
+public class HiddenServiceManager {
+
+}
+/*
+ * 
+ * ## Once you have configured a hidden service, you can look at the
+## contents of the file ".../hidden_service/hostname" for the address
+## to tell people.
+##
+## HiddenServicePort x y:z says to redirect requests on port x to the
+## address y:z.
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+#HiddenServicePort 22 127.0.0.1:22
+*/
+
diff --git a/src/org/torproject/android/service/OnBootReceiver.java b/src/org/torproject/android/service/OnBootReceiver.java
new file mode 100644
index 0000000..ef40619
--- /dev/null
+++ b/src/org/torproject/android/service/OnBootReceiver.java
@@ -0,0 +1,39 @@
+package org.torproject.android.service;
+
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+public class OnBootReceiver extends BroadcastReceiver {
+	
+	@Override
+	public void onReceive(Context context, Intent intent) {
+		
+		SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context.getApplicationContext());
+		
+		boolean startOnBoot = prefs.getBoolean("pref_start_boot",true);
+		
+		if (startOnBoot)
+		{
+			startService("init",context);
+			startService("start",context);			
+		}
+
+	}
+	
+
+	private void startService (String action, Context context)
+	{
+		
+		Intent torService = new Intent(context, TorService.class);    
+		torService.setAction(action);
+		context.startService(torService);
+		
+        
+	}
+	
+	
+}
+
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index 63bf0d5..d9a2fd5 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -47,10 +47,9 @@ import org.json.JSONArray;
 import org.json.JSONObject;
 import org.sufficientlysecure.rootcommands.Shell;
 import org.sufficientlysecure.rootcommands.command.SimpleCommand;
-import org.torproject.android.Orbot;
+import org.torproject.android.OrbotMainActivity;
 import org.torproject.android.R;
 import org.torproject.android.TorConstants;
-import org.torproject.android.Utils;
 import org.torproject.android.settings.AppManager;
 import org.torproject.android.settings.TorifiedApp;
 import org.torproject.android.vpn.OrbotVpnService;
@@ -241,7 +240,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
  	{	    
  		
  		//Reusable code.
- 		Intent intent = new Intent(TorService.this, Orbot.class);
+ 		Intent intent = new Intent(TorService.this, OrbotMainActivity.class);
  		PendingIntent pendIntent = PendingIntent.getActivity(TorService.this, 0, intent, 0);
  
 		if (mNotifyBuilder == null)
diff --git a/src/org/torproject/android/service/Utils.java b/src/org/torproject/android/service/Utils.java
new file mode 100644
index 0000000..a89e03f
--- /dev/null
+++ b/src/org/torproject/android/service/Utils.java
@@ -0,0 +1,100 @@
+/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
+/* See LICENSE for licensing information */
+
+
+package org.torproject.android.service;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Utils {
+
+
+	 public static String readString (InputStream stream)
+	    {
+	    	String line = null;
+	    
+	    	StringBuffer out = new StringBuffer();
+	    	
+	    	try {
+		    	BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+
+				while ((line = reader.readLine()) != null)
+				{
+					out.append(line);
+					out.append('\n');
+					
+				}
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
+			return out.toString();
+	    	
+	    }
+	/*
+	 * Load the log file text
+	 */
+	 public static String loadTextFile (String path)
+	    {
+	    	String line = null;
+	    
+	    	StringBuffer out = new StringBuffer();
+	    	
+	    	try {
+		    	BufferedReader reader = new BufferedReader((new FileReader(new File(path))));
+
+				while ((line = reader.readLine()) != null)
+				{
+					out.append(line);
+					out.append('\n');
+					
+				}
+				
+				reader.close();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
+			return out.toString();
+	    	
+	    }
+	 
+
+		/*
+		 * Load the log file text
+		 */
+		 public static boolean saveTextFile (String path, String contents)
+		    {
+			 	
+		    	try {
+		    		
+		    		 FileWriter writer = new FileWriter( path, false );
+                     writer.write( contents );
+                     
+                     writer.close();
+
+                     
+		    		
+		    		return true;
+			    	
+				} catch (IOException e) {
+				//	Log.d(TAG, "error writing file: " + path, e);
+						e.printStackTrace();
+					return false;
+				}
+				
+				
+		    	
+		    }
+	
+
+
+}
diff --git a/src/org/torproject/android/ui/ChooseLocaleWizardActivity.java b/src/org/torproject/android/ui/ChooseLocaleWizardActivity.java
new file mode 100644
index 0000000..1858f66
--- /dev/null
+++ b/src/org/torproject/android/ui/ChooseLocaleWizardActivity.java
@@ -0,0 +1,136 @@
+package org.torproject.android.ui;
+
+import java.util.Locale;
+
+import org.torproject.android.R;
+import org.torproject.android.TorConstants;
+import org.torproject.android.service.TorServiceUtils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Toast;
+
+public class ChooseLocaleWizardActivity extends Activity implements TorConstants {
+
+	private int flag = 0;
+	private ListView listLocales;
+	
+	protected void onCreate(Bundle savedInstanceState)
+	{
+        super.onCreate(savedInstanceState);
+       
+	}
+	
+	@Override
+	protected void onStart() {
+		
+		super.onStart();
+		setContentView(R.layout.layout_wizard_locale);
+		
+		
+		listLocales = (ListView)findViewById(R.id.wizard_locale_list);
+	    Button next = ((Button)findViewById(R.id.btnWizard2));
+	   // next.setEnabled(false);
+	    
+	    String[] strLangs = getResources().getStringArray(R.array.languages);
+	    strLangs[0] = Locale.getDefault().getDisplayName();
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1,  strLangs);	        
+        listLocales.setAdapter(adapter);
+	    
+	    listLocales.setSelection(0);
+	    		    
+	    
+	    listLocales.setOnItemClickListener(new OnItemClickListener() {
+			
+
+			@Override
+			public void onItemClick(AdapterView<?> arg0, View arg1,
+					int arg2, long arg3) {
+				
+				setLocalePref(arg2);
+				finish();
+				startActivity(new Intent(ChooseLocaleWizardActivity.this, LotsaText.class));
+				
+			}
+		});
+	        
+	    next.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				setLocalePref(0);
+				finish();
+				startActivity(new Intent(ChooseLocaleWizardActivity.this, LotsaText.class));
+
+			}
+		});
+		    
+
+	       
+	}
+	
+	private void setLocalePref(int selId)
+	{
+
+		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
+
+        Configuration config = getResources().getConfiguration();
+
+        String[] localeVals = getResources().getStringArray(R.array.languages_values);
+        
+        String lang = localeVals[selId];
+
+    	Editor pEdit = prefs.edit();
+		pEdit.putString(PREF_DEFAULT_LOCALE, lang);
+		pEdit.commit();
+		Locale locale = null;
+		
+        if (lang.equals("xx"))
+        {
+        	locale = Locale.getDefault();
+        
+        }
+        else
+        	locale = new Locale(lang);
+        
+        Locale.setDefault(locale);
+        config.locale = locale;
+        getResources().updateConfiguration(config, getResources().getDisplayMetrics());
+        
+        
+    
+		
+	}
+
+	@Override
+	protected void onRestoreInstanceState(Bundle savedInstanceState) {
+		super.onRestoreInstanceState(savedInstanceState);
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState) {
+		super.onSaveInstanceState(outState);
+		
+	}
+	
+	//Code to override the back button!
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event)  {
+	    if(keyCode == KeyEvent.KEYCODE_BACK){
+	    	Toast.makeText(getApplicationContext(), R.string.wizard_exit_at_first_screen_toast, Toast.LENGTH_SHORT).show();
+	    	return true;
+	    }
+	    return false;
+	}
+}
\ No newline at end of file
diff --git a/src/org/torproject/android/ui/ImageProgressView.java b/src/org/torproject/android/ui/ImageProgressView.java
new file mode 100644
index 0000000..641c444
--- /dev/null
+++ b/src/org/torproject/android/ui/ImageProgressView.java
@@ -0,0 +1,78 @@
+package org.torproject.android.ui;
+
+import java.util.Random;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+
+public class ImageProgressView extends ImageView
+{
+
+	  private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+	  private float progress = 0f; // 0 to 1
+	  
+	  private RectF circle;
+	  
+	public ImageProgressView(Context context) {
+	 super(context);
+	 // TODO Auto-generated constructor stub
+	 init();
+	 
+	}
+
+	public ImageProgressView(Context context, AttributeSet attrs) {
+	 super(context, attrs);
+	 init();
+	}
+
+	public ImageProgressView(Context context, AttributeSet attrs, int defStyle) {
+	 super(context, attrs, defStyle);
+	 
+	 init();
+	}
+
+	private void init(){
+	 paint.setStyle(Paint.Style.STROKE);
+	 paint.setColor(Color.GREEN);
+	 paint.setAntiAlias(true);
+	 paint.setStrokeWidth(20);
+	 
+	}
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+	   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+	   
+	   setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
+	   MeasureSpec.getSize(heightMeasureSpec));
+	 
+	}
+
+	@Override
+	protected void onDraw(Canvas canvas) {
+
+		super.onDraw(canvas);
+		
+		if (circle == null)
+		{
+		circle = new RectF(getWidth()/2,getHeight()/2+getHeight()/8, getWidth()/3,getHeight()/3);
+		}
+		
+		float sweepAngle = 360f * progress;
+		
+		canvas.drawArc(circle, 0, sweepAngle, true, paint);
+		
+	}
+	
+	
+
+	
+}
\ No newline at end of file
diff --git a/src/org/torproject/android/ui/LotsaText.java b/src/org/torproject/android/ui/LotsaText.java
new file mode 100644
index 0000000..5fdaa57
--- /dev/null
+++ b/src/org/torproject/android/ui/LotsaText.java
@@ -0,0 +1,137 @@
+package org.torproject.android.ui;
+
+import org.torproject.android.R;
+import org.torproject.android.TorConstants;
+import org.torproject.android.service.TorServiceUtils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class LotsaText extends Activity implements TorConstants{
+	
+	private Context context;
+	
+	protected void onCreate(Bundle savedInstanceState)
+	{	
+		
+		
+        super.onCreate(savedInstanceState);
+        context = this;
+        
+
+	}
+	
+	@Override
+	protected void onStart() {
+		
+		super.onStart();
+		setContentView(R.layout.scrollingtext_buttons_view);
+		
+		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
+
+		boolean wizardScreen1 = prefs.getBoolean("wizardscreen1",true);
+		if(wizardScreen1)
+			stepOne();
+		else
+			stepTwo();
+        
+	}
+	
+	@Override
+	protected void onResume() {
+		super.onResume();
+	
+		
+	}
+	
+	private void stepOne() {
+		
+		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
+
+		Editor pEdit = prefs.edit();
+		pEdit.putBoolean("wizardscreen1",true);
+		pEdit.commit();
+		
+		String title = context.getString(R.string.wizard_title);
+		String msg = context.getString(R.string.wizard_title_msg);
+		
+		setTitle(title);
+        
+        TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
+		txtBody.setText(msg);
+		
+        Button btn1 = ((Button)findViewById(R.id.btnWizard1));
+        Button btn2 = ((Button)findViewById(R.id.btnWizard2));
+        
+    	btn1.setVisibility(Button.INVISIBLE);
+
+    	btn2.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				stepTwo();
+			}
+		});
+		
+	}
+	
+	private void stepTwo() {
+		
+		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
+
+		Editor pEdit = prefs.edit();
+		pEdit.putBoolean("wizardscreen1",false);
+		pEdit.commit();
+		
+		setContentView(R.layout.scrollingtext_buttons_view);
+		String title = context.getString(R.string.wizard_warning_title);
+		String msg = context.getString(R.string.wizard_warning_msg);
+		
+		setTitle(title);
+		
+        TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
+		txtBody.setText(msg);
+		
+        Button btn1 = ((Button)findViewById(R.id.btnWizard1));
+        Button btn2 = ((Button)findViewById(R.id.btnWizard2));
+        
+    	btn1.setVisibility(Button.VISIBLE);
+    	
+    	
+    	btn1.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				
+				stepOne();
+			}
+		});
+    	
+    	btn2.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				finish();
+				startActivity(new Intent(LotsaText.this, TipsAndTricks.class));
+			}
+		});
+		
+	}
+	
+	//Code to override the back button!
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event)  {
+	    if(keyCode == KeyEvent.KEYCODE_BACK){
+	    	finish();
+	    	startActivity(new Intent(getBaseContext(), ChooseLocaleWizardActivity.class));
+	    	return true;
+	    }
+	    return true;
+	}
+	
+}
\ No newline at end of file
diff --git a/src/org/torproject/android/ui/OrbotDiagnosticsActivity.java b/src/org/torproject/android/ui/OrbotDiagnosticsActivity.java
new file mode 100644
index 0000000..3f72d16
--- /dev/null
+++ b/src/org/torproject/android/ui/OrbotDiagnosticsActivity.java
@@ -0,0 +1,337 @@
+package org.torproject.android.ui;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+import org.sufficientlysecure.rootcommands.Shell;
+import org.sufficientlysecure.rootcommands.command.SimpleCommand;
+import org.torproject.android.R;
+import org.torproject.android.R.id;
+import org.torproject.android.R.layout;
+import org.torproject.android.R.menu;
+import org.torproject.android.R.raw;
+import org.torproject.android.service.TorResourceInstaller;
+import org.torproject.android.service.TorServiceConstants;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.os.StatFs;
+import android.text.format.Formatter;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+
+
+public class OrbotDiagnosticsActivity extends Activity {
+
+	private TextView mTextView = null;
+	private final static String TAG = "OrbotDiag";
+	private StringBuffer log = new StringBuffer();
+	Process mProcess;
+	
+	@Override
+	protected void onCreate(Bundle savedInstanceState) { 
+		super.onCreate(savedInstanceState);
+		
+		setContentView(R.layout.layout_diag);
+		
+		mTextView = (TextView)findViewById(R.id.diaglog);
+		
+	}
+
+	private String getFreeStorage ()
+	{
+		File path = Environment.getDataDirectory();
+		StatFs stat = new StatFs(path.getPath());
+		long blockSize = stat.getBlockSize();
+		long availableBlocks = stat.getAvailableBlocks();
+		return Formatter.formatFileSize(this, availableBlocks * blockSize);
+	}
+	
+	@Override
+	protected void onPause() {
+		super.onPause();
+		
+		stopTor();
+	}
+
+	@Override
+	protected void onDestroy() {
+
+		super.onDestroy();
+		
+	}
+	
+	private void stopTor ()
+	{
+		File appBinHome = this.getDir("bin", Context.MODE_PRIVATE);
+
+		File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
+    	
+		if (mProcess != null)
+			mProcess.destroy();
+		
+		
+	}
+	
+	
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+
+
+		log("Hello, Orbot!");
+		
+		try
+		{
+			log(android.os.Build.DEVICE);
+			log(android.os.Build.HARDWARE);
+			log(android.os.Build.MANUFACTURER);
+			log(android.os.Build.MODEL);
+			log(android.os.Build.VERSION.CODENAME);
+			log(android.os.Build.VERSION.RELEASE);
+		}
+		catch (Exception e)
+		{
+			log("error getting device info");
+		}
+		
+		showFileTree ();
+		
+		runTorTest();
+	}
+
+	private void runTorTest ()
+	{
+		try
+		{
+			File appBinHome = this.getDir("bin", Context.MODE_PRIVATE);
+			File appDataHome = this.getDir("data", Context.MODE_PRIVATE);
+	
+	    	File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY);
+	    	enableBinExec (fileTor, appBinHome);	    	
+	    	
+			InputStream is = getResources().openRawResource(R.raw.torrc);
+			File fileTorrc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY + "diag");
+			TorResourceInstaller.streamToFile(is,fileTorrc, false, false);
+		
+			/**
+			ArrayList<String> alEnv = new ArrayList<String>();
+			alEnv.add("HOME=" + appBinHome.getAbsolutePath());
+			Shell shell = Shell.startShell(alEnv,appBinHome.getAbsolutePath());
+			SimpleCommand cmdTor = new SimpleCommand(fileTor.getAbsolutePath() + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + fileTorrc.getAbsolutePath());			
+			shell.add(cmdTor);
+			**/
+			
+			String cmd = fileTor.getAbsolutePath() + " DataDirectory " + appDataHome.getAbsolutePath() + " -f " + fileTorrc.getAbsolutePath();
+			
+			log ("Executing command> " + cmd);
+			
+			mProcess = Runtime.getRuntime().exec(cmd);
+			
+			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
+			StreamGobbler sg = new StreamGobbler();
+			sg.reader = bufferedReader;
+			sg.process = mProcess;
+			new Thread(sg).start();
+			
+			if (mProcess.getErrorStream() != null)
+			{
+				bufferedReader = new BufferedReader(new InputStreamReader(mProcess.getErrorStream()));
+				sg = new StreamGobbler();
+				sg.reader = bufferedReader;
+				sg.process = mProcess;
+				new Thread(sg).start();
+			}
+			
+			
+		}
+		catch (Exception e)
+		{
+			Log.d(TAG,"runTorTest exception",e);
+		}
+        
+	}
+	
+	class StreamGobbler implements Runnable
+	{
+		BufferedReader reader;
+		Process process;
+		
+		public void run ()
+		{
+			String line = null;			
+			try {
+				while ( (line = reader.readLine()) != null)
+				{
+					Message msg = mHandler.obtainMessage(0);
+					msg.getData().putString("log", line);
+					mHandler.sendMessage(msg);
+				}
+				
+			} catch (IOException e) {
+				Log.d(TAG, "error reading line",e);
+			}
+			
+			//log("Tor exit code=" + process.exitValue() + ";");
+			
+		}
+	}
+	
+	 private boolean enableBinExec (File fileBin, File appBinHome) throws Exception
+	    {
+	    	
+	    	log(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute());
+	  
+	    	if (!fileBin.canExecute())
+	    	{
+	    		log("(re)Setting permission on binary: " + fileBin.getAbsolutePath());	
+				Shell shell = Shell.startShell(new ArrayList<String>(), appBinHome.getAbsolutePath());
+			
+				shell.add(new SimpleCommand("chmod " + TorServiceConstants.CHMOD_EXE_VALUE + ' ' + fileBin.getAbsolutePath())).waitForFinish();
+				
+				File fileTest = new File(fileBin.getAbsolutePath());
+				log(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute());
+				
+				shell.close();
+	    	}
+	    	
+			return fileBin.canExecute();
+	    }
+	
+	private void showFileTree ()
+	{
+		
+		File fileDir = this.getDir("bin", Context.MODE_PRIVATE);
+		
+		if (fileDir.exists())
+		{
+			log("checking file tree: " + fileDir.getAbsolutePath());
+			printDir (fileDir.getName(), fileDir);
+		}
+		else
+		{
+			log("app_bin does not exist");
+		}
+		
+		fileDir = this.getDir("data", Context.MODE_PRIVATE);
+		if (fileDir.exists())
+		{
+			log("checking file tree: " + fileDir.getAbsolutePath());
+			printDir (fileDir.getName(), fileDir);
+		}
+		else
+		{
+			log ("app_data does not exist");
+		}
+				
+
+	}
+	
+	private void printDir (String path, File fileDir)
+	{
+		File[] files = fileDir.listFiles();
+		
+		if (files != null && files.length > 0)
+		{
+			for (File file : files)
+			{
+
+				try
+				{
+					if (file.isDirectory())
+					{
+						printDir(path + '/' + file.getName(), file);
+					}
+					else
+					{
+						log(path + '/' + file.getName() + " len:" + file.length() + " exec:" + file.canExecute());
+						
+					}
+				}
+				catch (Exception e)
+				{
+					log("problem printing out file information");
+				}
+			
+			}
+		}
+	}
+	
+	Handler mHandler = new Handler ()
+	{
+
+		@Override
+		public void handleMessage(Message msg) {
+		
+			super.handleMessage(msg);
+			
+			String logMsg = msg.getData().getString("log");
+			log(logMsg);
+		}
+		
+	};
+	
+	private void log (String msg)
+	{
+		Log.d(TAG, msg);
+		mTextView.append(msg + '\n');
+		log.append(msg + '\n');
+	}
+	
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+	    // Inflate menu resource file.
+	    getMenuInflater().inflate(R.menu.share_menu, menu);
+	
+	    // Locate MenuItem with ShareActionProvider
+	    MenuItem item = menu.findItem(R.id.menu_item_share);
+	
+	    return true;
+	}
+	
+	@Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+	    switch (item.getItemId()) {
+	
+	    case R.id.menu_item_share:
+	    	sendLog();
+	        return true;
+	
+	    default:
+	        return super.onOptionsItemSelected(item);
+	    }
+    }
+	
+	private void sendLog ()
+	{
+		int maxLength = 5000;
+		
+		String logShare = null;
+		
+		if (log.length() > maxLength)
+			logShare = log.substring(0,  maxLength);
+		else
+			logShare = log.toString();
+		
+		Intent sendIntent = new Intent();
+		sendIntent.setAction(Intent.ACTION_SEND);
+		sendIntent.putExtra(Intent.EXTRA_TEXT, logShare);
+		sendIntent.setType("text/plain");
+		startActivity(sendIntent);
+	}
+
+
+}
diff --git a/src/org/torproject/android/ui/OrbotLogActivity.java b/src/org/torproject/android/ui/OrbotLogActivity.java
new file mode 100644
index 0000000..ae83b77
--- /dev/null
+++ b/src/org/torproject/android/ui/OrbotLogActivity.java
@@ -0,0 +1,75 @@
+/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */
+/* See LICENSE for licensing information */
+
+package org.torproject.android.ui;
+
+import org.torproject.android.TorConstants;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+
+
+public class OrbotLogActivity extends Activity implements TorConstants
+{
+	
+    /** Called when the activity is first created. */
+	public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+    	doLayout();
+		LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
+			      new IntentFilter("log"));
+
+		
+	}
+	
+	// Our handler for received Intents. This will be called whenever an Intent
+	// with an action named "custom-event-name" is broadcasted.
+	private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
+		
+		
+		
+	  @Override
+	  public void onReceive(Context context, Intent intent) {
+	    // Get extra data included in the Intent
+		  
+		if (intent.hasExtra("log"))
+		{
+			String log = intent.getStringExtra("log");
+			updateStatus(log);
+		}
+		
+		
+	  }
+	};
+
+	
+	
+	private void doLayout ()
+	{
+		
+
+    }
+	
+	
+	private void updateStatus(String log)
+	{
+		
+	}
+   
+
+   	@Override
+	protected void onDestroy() {
+		super.onDestroy();
+		  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
+
+	}
+
+	
+
+}
diff --git a/src/org/torproject/android/ui/Rotate3dAnimation.java b/src/org/torproject/android/ui/Rotate3dAnimation.java
new file mode 100644
index 0000000..7829d2d
--- /dev/null
+++ b/src/org/torproject/android/ui/Rotate3dAnimation.java
@@ -0,0 +1,76 @@
+package org.torproject.android.ui;
+
+import android.graphics.Camera;
+import android.graphics.Matrix;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+/**
+ * An animation that rotates the view on the Y axis between two specified angles.
+ * This animation also adds a translation on the Z axis (depth) to improve the effect.
+ */
+public class Rotate3dAnimation extends Animation {
+    private final float mFromDegrees;
+    private final float mToDegrees;
+    private final float mCenterX;
+    private final float mCenterY;
+    private final float mDepthZ;
+    private final boolean mReverse;
+    private Camera mCamera;
+
+    /**
+     * Creates a new 3D rotation on the Y axis. The rotation is defined by its
+     * start angle and its end angle. Both angles are in degrees. The rotation
+     * is performed around a center point on the 2D space, definied by a pair
+     * of X and Y coordinates, called centerX and centerY. When the animation
+     * starts, a translation on the Z axis (depth) is performed. The length
+     * of the translation can be specified, as well as whether the translation
+     * should be reversed in time.
+     *
+     * @param fromDegrees the start angle of the 3D rotation
+     * @param toDegrees the end angle of the 3D rotation
+     * @param centerX the X center of the 3D rotation
+     * @param centerY the Y center of the 3D rotation
+     * @param reverse true if the translation should be reversed, false otherwise
+     */
+    public Rotate3dAnimation(float fromDegrees, float toDegrees,
+            float centerX, float centerY, float depthZ, boolean reverse) {
+        mFromDegrees = fromDegrees;
+        mToDegrees = toDegrees;
+        mCenterX = centerX;
+        mCenterY = centerY;
+        mDepthZ = depthZ;
+        mReverse = reverse;
+    }
+
+    @Override
+    public void initialize(int width, int height, int parentWidth, int parentHeight) {
+        super.initialize(width, height, parentWidth, parentHeight);
+        mCamera = new Camera();
+    }
+
+    @Override
+    protected void applyTransformation(float interpolatedTime, Transformation t) {
+        final float fromDegrees = mFromDegrees;
+        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
+
+        final float centerX = mCenterX;
+        final float centerY = mCenterY;
+        final Camera camera = mCamera;
+
+        final Matrix matrix = t.getMatrix();
+
+        camera.save();
+        if (mReverse) {
+            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
+        } else {
+            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
+        }
+        camera.rotateY(degrees);
+        camera.getMatrix(matrix);
+        camera.restore();
+
+        matrix.preTranslate(-centerX, -centerY);
+        matrix.postTranslate(centerX, centerY);
+    }
+}
diff --git a/src/org/torproject/android/ui/TipsAndTricks.java b/src/org/torproject/android/ui/TipsAndTricks.java
new file mode 100644
index 0000000..33548f4
--- /dev/null
+++ b/src/org/torproject/android/ui/TipsAndTricks.java
@@ -0,0 +1,248 @@
+package org.torproject.android.ui;
+
+import org.torproject.android.OrbotMainActivity;
+import org.torproject.android.R;
+import org.torproject.android.TorConstants;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class TipsAndTricks extends Activity implements TorConstants {
+
+	protected void onCreate(Bundle savedInstanceState)
+	{
+        super.onCreate(savedInstanceState);
+
+	}
+	
+	@Override
+	protected void onStart() {
+		
+		super.onStart();
+		setContentView(R.layout.layout_wizard_tips);
+		
+		stepFive();
+        
+	}
+	
+	@Override
+	protected void onResume() {
+		super.onResume();
+	
+		
+	}
+
+	void stepFive(){
+		
+		
+		String title = getString(R.string.wizard_tips_title);
+		
+		setTitle(title);
+	    	
+        Button btnLink = (Button)findViewById(R.id.WizardRootButtonInstallGibberbot);
+        
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+
+				String url = getString(R.string.gibberbot_apk_url);
+				finish();
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallOrweb);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.orweb_apk_url);
+				finish();
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallDuckgo);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.duckgo_apk_url);
+				finish();
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallFirefox);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.proxymob_setup_url);
+				finish();
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallTwitter);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.twitter_setup_url);
+				finish();
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallStoryMaker);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.story_maker_url);
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallMartus);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.martus_url);
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});
+        
+        
+        btnLink = (Button)findViewById(R.id.WizardRootButtonGooglePlay);
+
+        btnLink.setOnClickListener(new OnClickListener() {
+			
+			public void onClick(View view) {
+				
+				String url = getString(R.string.wizard_tips_play_url);
+				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+
+			}
+		});        
+        
+        
+        Button back = ((Button)findViewById(R.id.btnWizard1));
+        Button next = ((Button)findViewById(R.id.btnWizard2));
+        
+        back.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				finish();
+				startActivityForResult(new Intent(TipsAndTricks.this, LotsaText.class), 1);
+			}
+		});
+    	
+    	next.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				showWizardFinal();
+			}
+		});
+        
+	}
+	
+	private void showWizardFinal ()
+	{
+		setContentView(R.layout.scrollingtext_buttons_view);
+		String title =  getString(R.string.wizard_final);
+		String msg = getString(R.string.wizard_final_msg);
+		
+		setTitle(title);
+        
+        TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
+		txtBody.setText(msg);
+		
+        Button btn1 = ((Button)findViewById(R.id.btnWizard1));
+        Button btn2 = ((Button)findViewById(R.id.btnWizard2));
+        
+        btn2.setText(getString(R.string.btn_finish));
+    	btn1.setVisibility(Button.VISIBLE);
+    	
+    	btn1.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				finish();
+				startActivity(new Intent(TipsAndTricks.this, LotsaText.class));
+			}
+		});
+    	
+    	btn2.setOnClickListener(new View.OnClickListener() {
+			
+			public void onClick(View v) {
+				finish();
+			}
+		});
+	}
+	
+	//Code to override the back button!
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event)  {
+	    if(keyCode == KeyEvent.KEYCODE_BACK){
+	    	finish();
+	    	startActivity(new Intent(getBaseContext(), LotsaText.class));
+	    	return true;
+	    }
+	    return false;
+	}
+	
+	/*
+	private void showWizardFinal ()
+	{
+		String title = null;
+		String msg = null;
+		
+		
+		title = context.getString(R.string.wizard_final);
+		msg = context.getString(R.string.wizard_final_msg);
+		
+		DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() {
+			
+			@Override
+			public void onClick(DialogInterface dialog, int which) {
+				context.startActivity(new Intent(context, Orbot.class));
+
+			}
+		};
+	
+		
+		 new AlertDialog.Builder(context)
+		.setIcon(R.drawable.icon)
+        .setTitle(title)
+        .setPositiveButton(R.string.button_close, ocListener)
+        .setMessage(msg)
+        .show();
+	
+	
+				
+		
+	}*/
+}
\ No newline at end of file
diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java
index 443bc78..e5b9668 100644
--- a/src/org/torproject/android/vpn/OrbotVpnService.java
+++ b/src/org/torproject/android/vpn/OrbotVpnService.java
@@ -41,13 +41,13 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     private PendingIntent mConfigureIntent;
 
     private Handler mHandler;
-    private Thread mThreadProxy;
     private Thread mThreadVPN;
 
     private String mSessionName = "OrbotVPN";
     private ParcelFileDescriptor mInterface;
 
-    private int mSocksProxyPort = 9999;
+    //private Thread mThreadProxy;
+    //private int mSocksProxyPort = 9999;
    // private ProxyServer mProxyServer;
     
     private final static int VPN_MTU = 1500;
@@ -63,7 +63,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
         // Stop the previous session by interrupting the thread.
         if (mThreadVPN == null || (!mThreadVPN.isAlive()))
         {
-        	startSocksBypass ();
+        	enableAppRouting ();
             setupTun2Socks();               
         }
      
@@ -71,8 +71,19 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
         return START_STICKY;
     }
     
-    private void startSocksBypass ()
+    private void enableAppRouting ()
     {
+    	
+    	boolean isLollipop = false;
+    	
+    	if (isLollipop)
+    	{
+    		//allow for specific apps to be sent through VPN based on list selection
+    	}
+    	else
+    	{
+    		//do socks bypass trick
+    	}
     }
 
     @Override
diff --git a/src/org/torproject/android/wizard/ChooseLocaleWizardActivity.java b/src/org/torproject/android/wizard/ChooseLocaleWizardActivity.java
deleted file mode 100644
index 1a620c1..0000000
--- a/src/org/torproject/android/wizard/ChooseLocaleWizardActivity.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.torproject.android.wizard;
-
-import java.util.Locale;
-
-import org.torproject.android.R;
-import org.torproject.android.TorConstants;
-import org.torproject.android.service.TorServiceUtils;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.ListView;
-import android.widget.Toast;
-
-public class ChooseLocaleWizardActivity extends Activity implements TorConstants {
-
-	private int flag = 0;
-	private ListView listLocales;
-	
-	protected void onCreate(Bundle savedInstanceState)
-	{
-        super.onCreate(savedInstanceState);
-       
-	}
-	
-	@Override
-	protected void onStart() {
-		
-		super.onStart();
-		setContentView(R.layout.layout_wizard_locale);
-		
-		
-		listLocales = (ListView)findViewById(R.id.wizard_locale_list);
-	    Button next = ((Button)findViewById(R.id.btnWizard2));
-	   // next.setEnabled(false);
-	    
-	    String[] strLangs = getResources().getStringArray(R.array.languages);
-	    strLangs[0] = Locale.getDefault().getDisplayName();
-        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1,  strLangs);	        
-        listLocales.setAdapter(adapter);
-	    
-	    listLocales.setSelection(0);
-	    		    
-	    
-	    listLocales.setOnItemClickListener(new OnItemClickListener() {
-			
-
-			@Override
-			public void onItemClick(AdapterView<?> arg0, View arg1,
-					int arg2, long arg3) {
-				
-				setLocalePref(arg2);
-				finish();
-				startActivity(new Intent(ChooseLocaleWizardActivity.this, LotsaText.class));
-				
-			}
-		});
-	        
-	    next.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				setLocalePref(0);
-				finish();
-				startActivity(new Intent(ChooseLocaleWizardActivity.this, LotsaText.class));
-
-			}
-		});
-		    
-
-	       
-	}
-	
-	private void setLocalePref(int selId)
-	{
-
-		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
-
-        Configuration config = getResources().getConfiguration();
-
-        String[] localeVals = getResources().getStringArray(R.array.languages_values);
-        
-        String lang = localeVals[selId];
-
-    	Editor pEdit = prefs.edit();
-		pEdit.putString(PREF_DEFAULT_LOCALE, lang);
-		pEdit.commit();
-		Locale locale = null;
-		
-        if (lang.equals("xx"))
-        {
-        	locale = Locale.getDefault();
-        
-        }
-        else
-        	locale = new Locale(lang);
-        
-        Locale.setDefault(locale);
-        config.locale = locale;
-        getResources().updateConfiguration(config, getResources().getDisplayMetrics());
-        
-        
-    
-		
-	}
-
-	@Override
-	protected void onRestoreInstanceState(Bundle savedInstanceState) {
-		super.onRestoreInstanceState(savedInstanceState);
-	}
-
-	@Override
-	protected void onSaveInstanceState(Bundle outState) {
-		super.onSaveInstanceState(outState);
-		
-	}
-	
-	//Code to override the back button!
-	@Override
-	public boolean onKeyDown(int keyCode, KeyEvent event)  {
-	    if(keyCode == KeyEvent.KEYCODE_BACK){
-	    	Toast.makeText(getApplicationContext(), R.string.wizard_exit_at_first_screen_toast, Toast.LENGTH_SHORT).show();
-	    	return true;
-	    }
-	    return false;
-	}
-}
\ No newline at end of file
diff --git a/src/org/torproject/android/wizard/LotsaText.java b/src/org/torproject/android/wizard/LotsaText.java
deleted file mode 100644
index 137282f..0000000
--- a/src/org/torproject/android/wizard/LotsaText.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package org.torproject.android.wizard;
-
-import org.torproject.android.R;
-import org.torproject.android.TorConstants;
-import org.torproject.android.service.TorServiceUtils;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Button;
-import android.widget.TextView;
-
-public class LotsaText extends Activity implements TorConstants{
-	
-	private Context context;
-	
-	protected void onCreate(Bundle savedInstanceState)
-	{	
-		
-		
-        super.onCreate(savedInstanceState);
-        context = this;
-        
-
-	}
-	
-	@Override
-	protected void onStart() {
-		
-		super.onStart();
-		setContentView(R.layout.scrollingtext_buttons_view);
-		
-		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
-
-		boolean wizardScreen1 = prefs.getBoolean("wizardscreen1",true);
-		if(wizardScreen1)
-			stepOne();
-		else
-			stepTwo();
-        
-	}
-	
-	@Override
-	protected void onResume() {
-		super.onResume();
-	
-		
-	}
-	
-	private void stepOne() {
-		
-		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
-
-		Editor pEdit = prefs.edit();
-		pEdit.putBoolean("wizardscreen1",true);
-		pEdit.commit();
-		
-		String title = context.getString(R.string.wizard_title);
-		String msg = context.getString(R.string.wizard_title_msg);
-		
-		setTitle(title);
-        
-        TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
-		txtBody.setText(msg);
-		
-        Button btn1 = ((Button)findViewById(R.id.btnWizard1));
-        Button btn2 = ((Button)findViewById(R.id.btnWizard2));
-        
-    	btn1.setVisibility(Button.INVISIBLE);
-
-    	btn2.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				stepTwo();
-			}
-		});
-		
-	}
-	
-	private void stepTwo() {
-		
-		SharedPreferences prefs =  TorServiceUtils.getSharedPrefs(getApplicationContext());
-
-		Editor pEdit = prefs.edit();
-		pEdit.putBoolean("wizardscreen1",false);
-		pEdit.commit();
-		
-		setContentView(R.layout.scrollingtext_buttons_view);
-		String title = context.getString(R.string.wizard_warning_title);
-		String msg = context.getString(R.string.wizard_warning_msg);
-		
-		setTitle(title);
-		
-        TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
-		txtBody.setText(msg);
-		
-        Button btn1 = ((Button)findViewById(R.id.btnWizard1));
-        Button btn2 = ((Button)findViewById(R.id.btnWizard2));
-        
-    	btn1.setVisibility(Button.VISIBLE);
-    	
-    	
-    	btn1.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				
-				stepOne();
-			}
-		});
-    	
-    	btn2.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				finish();
-				startActivity(new Intent(LotsaText.this, TipsAndTricks.class));
-			}
-		});
-		
-	}
-	
-	//Code to override the back button!
-	@Override
-	public boolean onKeyDown(int keyCode, KeyEvent event)  {
-	    if(keyCode == KeyEvent.KEYCODE_BACK){
-	    	finish();
-	    	startActivity(new Intent(getBaseContext(), ChooseLocaleWizardActivity.class));
-	    	return true;
-	    }
-	    return true;
-	}
-	
-}
\ No newline at end of file
diff --git a/src/org/torproject/android/wizard/TipsAndTricks.java b/src/org/torproject/android/wizard/TipsAndTricks.java
deleted file mode 100644
index 3eea373..0000000
--- a/src/org/torproject/android/wizard/TipsAndTricks.java
+++ /dev/null
@@ -1,248 +0,0 @@
-package org.torproject.android.wizard;
-
-import org.torproject.android.Orbot;
-import org.torproject.android.R;
-import org.torproject.android.TorConstants;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.TextView;
-
-public class TipsAndTricks extends Activity implements TorConstants {
-
-	protected void onCreate(Bundle savedInstanceState)
-	{
-        super.onCreate(savedInstanceState);
-
-	}
-	
-	@Override
-	protected void onStart() {
-		
-		super.onStart();
-		setContentView(R.layout.layout_wizard_tips);
-		
-		stepFive();
-        
-	}
-	
-	@Override
-	protected void onResume() {
-		super.onResume();
-	
-		
-	}
-
-	void stepFive(){
-		
-		
-		String title = getString(R.string.wizard_tips_title);
-		
-		setTitle(title);
-	    	
-        Button btnLink = (Button)findViewById(R.id.WizardRootButtonInstallGibberbot);
-        
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-
-				String url = getString(R.string.gibberbot_apk_url);
-				finish();
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallOrweb);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.orweb_apk_url);
-				finish();
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallDuckgo);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.duckgo_apk_url);
-				finish();
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallFirefox);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.proxymob_setup_url);
-				finish();
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallTwitter);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.twitter_setup_url);
-				finish();
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallStoryMaker);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.story_maker_url);
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonInstallMartus);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.martus_url);
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});
-        
-        
-        btnLink = (Button)findViewById(R.id.WizardRootButtonGooglePlay);
-
-        btnLink.setOnClickListener(new OnClickListener() {
-			
-			public void onClick(View view) {
-				
-				String url = getString(R.string.wizard_tips_play_url);
-				startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-
-			}
-		});        
-        
-        
-        Button back = ((Button)findViewById(R.id.btnWizard1));
-        Button next = ((Button)findViewById(R.id.btnWizard2));
-        
-        back.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				finish();
-				startActivityForResult(new Intent(TipsAndTricks.this, LotsaText.class), 1);
-			}
-		});
-    	
-    	next.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				showWizardFinal();
-			}
-		});
-        
-	}
-	
-	private void showWizardFinal ()
-	{
-		setContentView(R.layout.scrollingtext_buttons_view);
-		String title =  getString(R.string.wizard_final);
-		String msg = getString(R.string.wizard_final_msg);
-		
-		setTitle(title);
-        
-        TextView txtBody = ((TextView)findViewById(R.id.WizardTextBody));
-		txtBody.setText(msg);
-		
-        Button btn1 = ((Button)findViewById(R.id.btnWizard1));
-        Button btn2 = ((Button)findViewById(R.id.btnWizard2));
-        
-        btn2.setText(getString(R.string.btn_finish));
-    	btn1.setVisibility(Button.VISIBLE);
-    	
-    	btn1.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				finish();
-				startActivity(new Intent(TipsAndTricks.this, LotsaText.class));
-			}
-		});
-    	
-    	btn2.setOnClickListener(new View.OnClickListener() {
-			
-			public void onClick(View v) {
-				finish();
-			}
-		});
-	}
-	
-	//Code to override the back button!
-	@Override
-	public boolean onKeyDown(int keyCode, KeyEvent event)  {
-	    if(keyCode == KeyEvent.KEYCODE_BACK){
-	    	finish();
-	    	startActivity(new Intent(getBaseContext(), LotsaText.class));
-	    	return true;
-	    }
-	    return false;
-	}
-	
-	/*
-	private void showWizardFinal ()
-	{
-		String title = null;
-		String msg = null;
-		
-		
-		title = context.getString(R.string.wizard_final);
-		msg = context.getString(R.string.wizard_final_msg);
-		
-		DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() {
-			
-			@Override
-			public void onClick(DialogInterface dialog, int which) {
-				context.startActivity(new Intent(context, Orbot.class));
-
-			}
-		};
-	
-		
-		 new AlertDialog.Builder(context)
-		.setIcon(R.drawable.icon)
-        .setTitle(title)
-        .setPositiveButton(R.string.button_close, ocListener)
-        .setMessage(msg)
-        .show();
-	
-	
-				
-		
-	}*/
-}
\ No newline at end of file





More information about the tor-commits mailing list