[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [orbot/master] refactoring into cleaner packages
commit 7c303f1589656c2e6de44b96e710a14aae3ec8f5
Author: Nathan Freitas <nathan@xxxxxxxxxxx>
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
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits